TXG/MNX Posted January 11, 2016 Share Posted January 11, 2016 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 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted January 11, 2016 Share Posted January 11, 2016 (edited) 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 January 11, 2016 by Sporadic 4 Quote Link to comment Share on other sites More sharing options...
ggn Posted January 11, 2016 Share Posted January 11, 2016 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 Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted January 11, 2016 Share Posted January 11, 2016 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. 4 Quote Link to comment Share on other sites More sharing options...
TXG/MNX Posted January 11, 2016 Author Share Posted January 11, 2016 Thanx for the quick response will do some more testing later today Sent from UMI hammer with Tapatalk 1 Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted January 11, 2016 Share Posted January 11, 2016 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. 4 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted January 11, 2016 Share Posted January 11, 2016 (edited) 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 January 11, 2016 by Sporadic Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted January 11, 2016 Share Posted January 11, 2016 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; 1 Quote Link to comment Share on other sites More sharing options...
Zerosquare Posted January 11, 2016 Share Posted January 11, 2016 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). Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted January 11, 2016 Share Posted January 11, 2016 You need to do that 16 times ; each iteration only gets you a single random bit. Thats all you need . Quote Link to comment Share on other sites More sharing options...
TXG/MNX Posted January 12, 2016 Author Share Posted January 12, 2016 Hi, No success every time I get the same random numbers. And RANDOMIZE TIMER seems not to exist in in this version of BCX Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted January 12, 2016 Share Posted January 12, 2016 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/forums/topic/247781-rnd-function-question/?do=findComment&comment=3413117 1 Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted January 12, 2016 Share Posted January 12, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted January 12, 2016 Share Posted January 12, 2016 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 Quote Link to comment Share on other sites More sharing options...
TXG/MNX Posted January 12, 2016 Author Share Posted January 12, 2016 Hi, I got random numbers at start of the Jaguar console 'random numbers'basic_r_indx=0basic_r_size=0DIM a AS inta = peek(1024)randomize(a)RLOCATE 10,10print 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. Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted July 27, 2018 Share Posted July 27, 2018 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. Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted July 27, 2018 Share Posted July 27, 2018 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. Quote Link to comment Share on other sites More sharing options...
Zerosquare Posted July 27, 2018 Share Posted July 27, 2018 (edited) 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 July 27, 2018 by Zerosquare 3 Quote Link to comment Share on other sites More sharing options...
ggn Posted July 27, 2018 Share Posted July 27, 2018 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 5 Quote Link to comment Share on other sites More sharing options...
Zerosquare Posted July 27, 2018 Share Posted July 27, 2018 (edited) 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 July 27, 2018 by Zerosquare Quote Link to comment Share on other sites More sharing options...
ggn Posted July 27, 2018 Share Posted July 27, 2018 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 Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted July 27, 2018 Share Posted July 27, 2018 Thanks guys, I'll work with this over the weekend. 1 Quote Link to comment Share on other sites More sharing options...
Clint Thompson Posted July 31, 2018 Share Posted July 31, 2018 (edited) 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 19simonvalues=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=0basic_r_indx=1RLOCATE 200,80print simonvalues[1]+1DELAY(10)print simonvalues[2]+1DELAY(10)print simonvalues[3]+1DELAY(10)print simonvalues[4]+1DELAY(10)print simonvalues[5]+1DELAY(10)print simonvalues[6]+1DELAY(10)print simonvalues[7]+1DELAY(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 July 31, 2018 by Clint Thompson Quote Link to comment Share on other sites More sharing options...
ggn Posted July 31, 2018 Share Posted July 31, 2018 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=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 2 Quote Link to comment Share on other sites More sharing options...
Christos Posted August 6, 2018 Share Posted August 6, 2018 (edited) 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 August 6, 2018 by Christos Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.