Jump to content

Photo

RND function question


35 replies to this topic

#1 TXG/MNX OFFLINE  

TXG/MNX

    River Patroller

  • 3,633 posts

Posted Mon Jan 11, 2016 7:46 AM

Hello,

 

I was using RND to print a character to random location on te screen. But when I start the output rom in VJ I get most of the times the same result I was expecting everytime I run the ROM the character was printed on a different position.

 

Using:

FOR i=1 TO 10

RLOCATE (RND*320),(RND*200)

RPRINT "x"

NEXT i

 



#2 Sporadic OFFLINE  

Sporadic

    Dragonstomper

  • 503 posts
  • Probably RB+ing
  • Location:UK

Posted Mon Jan 11, 2016 7:57 AM

I was expecting everytime I run the ROM the character was printed on a different position.

 

 

Hi,

 

Numbers are never truly random on any computer/console etc - typically you would specify a seed value for it to base the random numbers on.

 

Put the following at the top of the program (before you use any RND commands).

randomize(20)

 

Changing the 20 in that randomize command will change the seed and present you with another set of "random" numbers.

 

So, changing the seed, changes the set of random numbers you receive.   Therefore, if you want this to change every time someone plays then you must get creative with how you generate the seed.

 

One way would be to start a counter when the game starts and leave that counting up in a loop.  Get the player to press a button to start the game and at this point you use the counter as the seed.  Eg. randomize(counter)

Now, unless the player presses the button to start at the exact same point every time, you will see random results.

 

Hope this helps.


Edited by Sporadic, Mon Jan 11, 2016 7:58 AM.


#3 ggn OFFLINE  

ggn

    Stargunner

  • 1,385 posts
  • Location:Athens, Greece

Posted Mon Jan 11, 2016 8:16 AM

Basically what Sporadic said. It's a bit hard coming up with a random number from a system that's mostly deterministic at booting up. One idea to try is to replace the "20" with a value from some hardware register that changes a lot (like maybe the line buffer address). Or enable some user interaction, i.e. have the user press fire while increasing a number (inside the loop where you'll waiting for user input). That will more or less guarantee a random number for randomize.



#4 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Mon Jan 11, 2016 8:21 AM

There is some entropy to be had in the power-up contents of RAM locations not used during initialisation by the BIOS. Summing a few 100 bytes worth might get you something for an initial seed and then you can add the counter to that too.



#5 TXG/MNX OFFLINE  

TXG/MNX

    River Patroller

  • Topic Starter
  • 3,633 posts

Posted Mon Jan 11, 2016 8:33 AM

Thanx for the quick response will do some more testing later today

Sent from UMI hammer with Tapatalk

#6 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Mon Jan 11, 2016 9:10 AM

RND is single precision floating point which isn't going to be good for speed. You might want to consider rolling your own integer routine and then use modulo 320 and modulo 200 (IMOD) instead of the floating multiplications and their inherent integer conversions.



#7 Sporadic OFFLINE  

Sporadic

    Dragonstomper

  • 503 posts
  • Probably RB+ing
  • Location:UK

Posted Mon Jan 11, 2016 9:26 AM

RND is single precision floating point which isn't going to be good for speed. You might want to consider rolling your own integer routine and then use modulo 320 and modulo 200 (IMOD) instead of the floating multiplications and their inherent integer conversions.

Yes, i've seen micro-pauses when using RND at run-time.

 

another solution is to fill an array of ints with random ones before the game starts.  Then you can iterate through that array while the game is playing.  You can always loop back to the beginning of the array if needed.


Edited by Sporadic, Mon Jan 11, 2016 9:27 AM.


#8 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Mon Jan 11, 2016 9:43 AM

Yes, i've seen micro-pauses when using RND at run-time.


A 16bit integer random number generator can be as simple as this (in "C") :-
unsigned short int theRandomSeed=0xAAAA; // Any non-zero value

if (theRandomSeed&1)
    {
    theRandomSeed>>=1;
    theRandomSeed^=0xB400;
    }
else
    theRandomSeed>>=1;


#9 Zerosquare ONLINE  

Zerosquare

    River Patroller

  • 2,689 posts
  • Location:France

Posted Mon Jan 11, 2016 2:31 PM

You need to do that 16 times ; each iteration only gets you a single random bit.

 

Otherwise I agree, a LFSR like this is a good solution when performance matters more than randomness (i.e. games). 



#10 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Mon Jan 11, 2016 2:34 PM

You need to do that 16 times ; each iteration only gets you a single random bit.

 

Thats all you need :P.



#11 TXG/MNX OFFLINE  

TXG/MNX

    River Patroller

  • Topic Starter
  • 3,633 posts

Posted Tue Jan 12, 2016 1:54 PM

Hi,

 

No success every time I get the same random numbers. And RANDOMIZE TIMER seems not to exist in in this version of BCX



#12 CyranoJ ONLINE  

CyranoJ

    Quadrunner

  • 5,442 posts
  • RAPTOR in LOCAL
  • Location:Adelaide, SA

Posted Tue Jan 12, 2016 1:57 PM

Hi,

 

No success every time I get the same random numbers. And RANDOMIZE TIMER seems not to exist in in this version of BCX

 

http://atariage.com/...n/#entry3413117



#13 sh3-rg OFFLINE  

sh3-rg

    River Patroller

  • 3,395 posts
  • doge + tie = dothemath
  • Location:BOLTON, England

Posted Tue Jan 12, 2016 1:57 PM

Hi,

 

No success every time I get the same random numbers. And RANDOMIZE TIMER seems not to exist in in this version of BCX

 

If you're using user input with a counter variable feeding RANDOMIZE it seems a bit strange you're getting the same results. Feel free to post a code snippet.



#14 Sporadic OFFLINE  

Sporadic

    Dragonstomper

  • 503 posts
  • Probably RB+ing
  • Location:UK

Posted Tue Jan 12, 2016 1:57 PM

Hi,

 

No success every time I get the same random numbers. And RANDOMIZE TIMER seems not to exist in in this version of BCX

Did you try the suggestions above? Yes, timer doesnt exist.  You must create your own as suggested



#15 TXG/MNX OFFLINE  

TXG/MNX

    River Patroller

  • Topic Starter
  • 3,633 posts

Posted Tue Jan 12, 2016 2:13 PM

Hi,

 

I got random numbers at start of the Jaguar console

 

 

'random numbers
'
basic_r_indx=0
basic_r_size=0

DIM a AS int

a = peek(1024)
randomize(a)
RLOCATE 10,10
print rnd

 

This seems to work, so I use this value to create more new random numbers.

 

Did try it on vj several times with success.

 

I can use a also as value for counter.

 

 

 

 



#16 Clint Thompson OFFLINE  

Clint Thompson

    River Patroller

  • 4,359 posts
  • Kiss Reality Goodbye.
  • Location:Indianapolis, Indiana

Posted Thu Jul 26, 2018 6:09 PM

I'm back from the dead and as ridiculous as it sounds, I've been beating my brains out the past few days over this goofy Simon clone as I'm probably doing something terribly stupid (always tends to be the case) but haven't made progress outside of countless errors (side note, not progress). I have all the graphics, sounds and animations working and in place  -  so the skeleton of the game is there, just not the actual game play (surprise surprise).

 

I don't even really know where to begin as far as where I'm stuck. I know I need to have DIMs setup and need to randomize their values out of a total of 4 every time you play it with counters so it knows how many times to play back, with progression, etc. Should I change randomize(20) to randomize(4)? Maybe there's an easier approach but I've tried finding basic programs as basic as they get to use as an example but like an idiot, feel defeated. There's only a handful and the rest are for Python, C++, etc. which are completely foreign to me. I can barely BASIC -- clearly.

 

My idea is to setup 32 DIMs with an initial value of 0 (right?) and then use the RND function to randomly pick from 1 to 4 to assign and store in RAM as such, so I can have the Jaguar playback on-screen the string of numbers in progression (using counters in sets of 8, 16 or 32 range based on length of play/round - with IF counter1 > 8 THEN CALL gamewin ((as example)) and then have the Jaguar check the input of the player vs. what is stored already in the DIM. Then setup a countdown counter or check counter so each button depressed should match that stored in the DIM test1, DIM test2, etc., ELSE CALL gameover. Sounds a million times easier than it actually is.

 

Where should the RND command be, in a subroutine? In the beginning somewhere? (I'm guessing if I do that, it'll continuously loop and re-write the values causing chaos and a broken game) and how do I write that to change the DIM value? I only ask because I keep getting build errors and have tried LET test1 = RND(0)*3)+1 (and variants) but will not compile saying rnd() cannot be used as a function or that test1 isn't defined, and I have a DIM setup for that so not sure what gives or why.

 

I did manage to get what TXG/MNX wrote to work and print on screen just as a quick test, but the results were always .000403293 or really bizarre strings with a decimal and then like 9 numbers. But I don't need to print them, I need to store them. If anyone can just set me up with how the first DIM should look, first randomization for said DIM specifically (how and where) that would be seriously helpful start. I can deal with the counters and otherwise I think  and can continue to experiment from there but struggling with the first bit. I'm better with graphics/music/sound than I ever will be with programming but I can only waste so much time trying.

 

Attached File  IMG_5206.JPG   124.65KB   1 downloads

Attached File  IMG_5012.jpg   97.55KB   1 downloads



#17 Clint Thompson OFFLINE  

Clint Thompson

    River Patroller

  • 4,359 posts
  • Kiss Reality Goodbye.
  • Location:Indianapolis, Indiana

Posted Thu Jul 26, 2018 7:49 PM

As a work around, I was considering having the computer randomly pick from 100 subroutines that contain a pattern (cheating but still requires the use of RND) and so I find myself with the issue of also not knowing for sure how to have it randomly generate a number 1 to 100.

I tried this but no dice:

SUB playball

a = peek(1024)
randomize(a)
IF a = 1 THEN CALL seq1
IF a = 2 THEN CALL seq2
IF a = 3 THEN CALL seq3
IF a = 4 THEN CALL seq4
IF a = 5 THEN CALL seq5
IF a = 6 THEN CALL seq6
IF a = 7 THEN CALL seq7
IF a = 8 THEN CALL seq8

END SUB

I feel like I'm missing something in there to make it specify out of 100 where as peeking said memory location doesn't specify that.



#18 Zerosquare ONLINE  

Zerosquare

    River Patroller

  • 2,689 posts
  • Location:France

Posted Thu Jul 26, 2018 10:42 PM

You're making it much more complicated that it needs to be, and confusing RANDOMIZE with RND. :)

RANDOMIZE is called once to make sure you don't get the same "random" numbers every time you play the game.
RND is called every time you need a new random number.
Since RND returns a value that's between 0 and 1, if you want a result that's between 1 and 4, what you need is INT(RND * 4) + 1.

For a Simon clone, you don't need to create tons of variables, you only need one single array. (I assume there's something about arrays in the rB+ docs. Read it.)
At the beginning of your game, you call RANDOMIZE once. Then (using a loop), you fill every item in your array with a random number.

During the game, you start at the beginning of the array every time, the only thing that changes is how many items you use (one more each time the player correctly reproduces the sequence).

Edited by Zerosquare, Thu Jul 26, 2018 10:43 PM.


#19 ggn OFFLINE  

ggn

    Stargunner

  • 1,385 posts
  • Location:Athens, Greece

Posted Thu Jul 26, 2018 11:10 PM

Pretty much what Zerosquare said. Try something like

dim simonvalues[20] as int
dim i as int

randomize(peek(1024))

for i=0 to 19
    simonvalues[i]=rnd*4+1
    rlocate 10,i*8
    print simonvalues[i]
next i

do
    vsync
loop
Also, if you get stuck with logic problems like these, never hesitate to ask. I know that it's much more rewarding figuring things out on your own but sometimes there might be an easier way to do things and you simply aren't aware of it :)

#20 Zerosquare ONLINE  

Zerosquare

    River Patroller

  • 2,689 posts
  • Location:France

Posted Fri Jul 27, 2018 1:27 AM

Does rB+ convert floating point to integer by rounding, or by getting rid of the decimal part?

In the former case, you need INT(RND * 4) instead of just RND * 4, because anything >= 3.5 will get rounded to 4 otherwise.

Edited by Zerosquare, Fri Jul 27, 2018 1:28 AM.


#21 ggn OFFLINE  

ggn

    Stargunner

  • 1,385 posts
  • Location:Athens, Greece

Posted Fri Jul 27, 2018 2:18 AM

Does rB+ convert floating point to integer by rounding, or by getting rid of the decimal part?

In the former case, you need INT(RND * 4) instead of just RND * 4, because anything >= 3.5 will get rounded to 4 otherwise.


In general this is just transformed into C code, so assume C behaviour for most things. In this case, yes, the casting from float to int is handled by the compiler

#22 Clint Thompson OFFLINE  

Clint Thompson

    River Patroller

  • 4,359 posts
  • Kiss Reality Goodbye.
  • Location:Indianapolis, Indiana

Posted Fri Jul 27, 2018 8:10 AM

Thanks guys, I'll work with this over the weekend.



#23 Clint Thompson OFFLINE  

Clint Thompson

    River Patroller

  • 4,359 posts
  • Kiss Reality Goodbye.
  • Location:Indianapolis, Indiana

Posted Mon Jul 30, 2018 10:03 PM

I messed around with this a little tonight and was able to get it to seemingly randomly print the numbers between 1-4 (good grief...)

 

 

Please forgive my ignorance, my patience is running thin. I've watched videos about setting up arrays and have checked out the starfield particle demos in Rb+ and read through stuff (again), however, I would like some clarification on the following so I understand what is happening or why and what I'm doing wrong (again):

 

So:

 

dim simonvalues[20] as int

 

This is creating an array for the variable simonvalues between (or 1 - 20) correct? (or am I wrong and needing to setup an individual DIM for every single one similar to the particle starfield arrary?)

 

then by making

 

dim i as int

 

this allows:

 

for i=0 to 19
simonvalues[i]=INT(RND()*3)+1

 

to insert/store a randomized number in each bank of said array (of 20 as listed above) *if I"m understanding this correctly, this is eliminating the need to create a separate DIM for 8, 16, or more simonvalues...

 

Then to retrieve said supposed randomized number that was generated and stored(I say this because I don't think it's random as it's consistently the same), I'm doing this:

 

basic_r_size=0
basic_r_indx=1
RLOCATE 200,80
print simonvalues[1]+1
DELAY(10)
print simonvalues[2]+1
DELAY(10)
print simonvalues[3]+1
DELAY(10)
print simonvalues[4]+1
DELAY(10)
print simonvalues[5]+1
DELAY(10)
print simonvalues[6]+1
DELAY(10)
print simonvalues[7]+1
DELAY(10)
print simonvalues[8]+1

 

I'm adding +1 because otherwise it prints 0-4 , even though I thought that was the purpose of adding +1 after the RND command.

Past that, how am I able to read from the array to know what the number is stored (permitting this is what is actually happening) outside of printing it on screen? Shouldn't I just be able to do something like this?:

 

IF simonvalues[1]=1 THEN

(do stuff here)

ELSE

(do other stuff here)

 

but it keeps failing saying a function definition is now allowed before {

 

I've toyed around with adding brackets () around numbers, changing it around multiple ways but no go....


Edited by Clint Thompson, Mon Jul 30, 2018 10:06 PM.


#24 ggn OFFLINE  

ggn

    Stargunner

  • 1,385 posts
  • Location:Athens, Greece

Posted Tue Jul 31, 2018 12:22 AM

I messed around with this a little tonight and was able to get it to seemingly randomly print the numbers between 1-4 (good grief...)
 

 
Please forgive my ignorance, my patience is running thin. I've watched videos about setting up arrays and have checked out the starfield particle demos in Rb+ and read through stuff (again), however, I would like some clarification on the following so I understand what is happening or why and what I'm doing wrong (again):
 
So:
 
dim simonvalues[20] as int
 
This is creating an array for the variable simonvalues between (or 1 - 20) correct? (or am I wrong and needing to setup an individual DIM for every single one similar to the particle starfield arrary?)

Nope, that's fine. After the dim simonvalues can hold up to 20 integer values with indices 0 to 19.
 

then by making
 
dim i as int
 
this allows:
 
for i=0 to 19
simonvalues[i]=INT(RND()*3)+1

 
to insert/store a randomized number in each bank of said array (of 20 as listed above) *if I"m understanding this correctly, this is eliminating the need to create a separate DIM for 8, 16, or more simonvalues...

Yes, using this small loop you can fill all the indices of the array without having to write 20 lines of code, one for each index.

Then to retrieve said supposed randomized number that was generated and stored(I say this because I don't think it's random as it's consistently the same), I'm doing this:
 
basic_r_size=0
basic_r_indx=1
RLOCATE 200,80
print simonvalues[1]+1
DELAY(10)
print simonvalues[2]+1
DELAY(10)
print simonvalues[3]+1
DELAY(10)
print simonvalues[4]+1
DELAY(10)
print simonvalues[5]+1
DELAY(10)
print simonvalues[6]+1
DELAY(10)
print simonvalues[7]+1
DELAY(10)
print simonvalues[8]+1

 
I'm adding +1 because otherwise it prints 0-4 , even though I thought that was the purpose of adding +1 after the RND command.

Well, I removed the +1 in your print statements and replaced the INT(RND()*3)+1 with INT(RND()*4)+1. From my tests it does print 1 to 4, so what you report is a bit weird.

Past that, how am I able to read from the array to know what the number is stored (permitting this is what is actually happening) outside of printing it on screen? Shouldn't I just be able to do something like this?:
 
IF simonvalues[1]=1 THEN
(do stuff here)
ELSE
(do other stuff here)
 
but it keeps failing saying a function definition is now allowed before {
 
I've toyed around with adding brackets () around numbers, changing it around multiple ways but no go....

I can only assume that you're missing an ENDIF there. I mean, this seems to work here:

IF simonvalues[1]=1 THEN
i=1
ELSE
i=2
endif


#25 Christos OFFLINE  

Christos

    Stargunner

  • 1,014 posts
  • Location:Thessaloniki, Greece

Posted Mon Aug 6, 2018 1:54 AM

If someone needs a good pseudo random number generator maybe it would be possible to convert my mersienne twister implementation to rb+ but RND and RANDOMIZE should be enough for basic usage.


Edited by Christos, Mon Aug 6, 2018 1:55 AM.




Reply to this topic



  


0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users