Each time RND pulls a number, store it in a variable. The next time it pulls one, compare it to the variable and only use the number if it doesn't match the variable. Then give the variable its new value. Else, try again.
Make a randomizer a bit better?
Root / Programming Questions / [.]
darwin_primeCreated:
I'm making a program that randomly selects a name. I'm doing this for somehing I'll use at work. Ocassionally I have to give an order to another coworker. As I don't speak their language, I can only set it up, but a coworker then has to process it. That's the back story.
So the program is finished, but at times if you tell it to randomize again, it brings back the same name as before. How would you write it, so that if RND() pulled the same number twice in a row, that it would pull instead again until it got a different result?
Here's the key. Don't expect too much, I put this together in about a half an hour.
4K4N3XJP
Thanks!
If this has to be done with respect to the program having closed as well, you'll have to save that result as a TXT file
e.g.
SAVE "TXT:LASTRESULT", RESULT$
then loaded next time with
LASTRESULT$ = LOAD("TXT:LASTRESULT")
Each time RND pulls a number, store it in a variable. The next time it pulls one, compare it to the variable and only use the number if it doesn't match the variable. Then give the variable its new value. Else, try again.This is kind of what I"m alredy doing so that the program knows which string to print. I'm not sure how to have RND saved to two variables and then compare the two to eachother without them always being identical though. Unless I make two seperate loops that take turns ransomizing the string to be printed and then compare those two to each other? Here's essentially what it is right now: @SPIN N=RND(3) A$=JOHN B$=MIKE C$=JEFF GOTO @PRI @PRI IF N==0 THEN PRINT A$ IF N==1 THEN PRINT B$ Thanks for the help.
If this has to be done with respect to the program having closed as well, you'll have to save that result as a TXT file e.g. SAVE "TXT:LASTRESULT", RESULT$ then loaded next time with LASTRESULT$ = LOAD("TXT:LASTRESULT")Thanks for the tip. I won't need to be that complex though, just something I pop open at work once in a while and randomly select somone to give the order to. I only need to do this maybe three times a day so saving the last result in a TXT file might be overkill.
I just figured it out! Forgive my excitement, but I'm totally new to programming. I always assumed it to difficult to try.
In case someone else is looking for how to do this, I took advatage of the fact that SB reads from top to bottom.
@SPIN
N=RND(5)
A$=STEVE
B$=JENNY
etc...
GOTO @PRINT
This is where I put the "check" in with IF X=N. At the moment the program has never seen X before and so it doesn't matter and just skips it over
@PRINT
IF X==N THEN GOTO @SPIN
IF N==2 THEN PRINT A$
blah blah blah
GOTO @END
Now the program will write for X for the first time
@END
X=N
blah blah blah GOTO @SPIN
Now that X has been written, it can be compared to N at the top and the program can behave to the instruction accordingly. I've tested this about 25 times now and not seen a duplicate result at all.
That looks like a good solution. I would use variable names more like PREVIOUS for X, and maybe THIS for N.
And when you're ready to learn something that, I think, will make your job a lot easier: look into 'arrays'.
VAR Name$ 'Current random number or 'roll' VAR CurNum% 'Keeping track of last roll so as to prevent it from happening a second time in a row VAR LastNum% @ROLL CurNum% = RND(2) IF CurNum% != LastNum% THEN IF CurNum% == 0 THEN Name$ = "Forest" ELSEIF CurNum == 1 THEN Name$ = "Jennay" ENDIF 'Update the last number variable LastNum% = CurNum% ELSE GOTO @ROLL ENDIF END 'of random name generatorAlternatively, you can store the last numbers as far back as you want into an array. Although, I would only recommend that if it becomes a particularly big list. I imagine it's like Earthbound's "Don't Care" option. I could only wonder for what 'business' purposes this would be needed. Especially for SmileBASIC.
'## Setup ## VAR CURRENT DIM NAME$[3] DATA "Bob","Joe","12Me21" FOR I=0 to LEN(NAME$)-1 RESTORE NAME$[I] NEXT '## Randomizer Function ## DEF RNDNAME$() CURRENT=(CURRENT+RND(LEN(NAME$)-1)+1) MOD LEN(NAME$) RETURN NAME$[CURRENT] ENDHere's another way. In this example, there are 3 names, and a variable that stores the CURRENT name. Each time, you add a number between 1 and 2 to CURRENT (and then MOD 3). That way, you can never repeat the same name twice in a row, and only ever have to randomize once.
12Me21 has a pretty good comment. I was about to mention arrays.
This is where I put the "check" in with IF X=N. At the moment the program has never seen X before and so it doesn't matter and just skips it over @PRINT IF X==N THEN GOTO @SPIN IF N==2 THEN PRINT A$ blah blah blah GOTO @ENDThis isn't quite what is happening. Since you don't have OPTION STRICT on, the first time SmileBasic "sees" the variable X, it is created. Since you don't manually do a VAR X = value, X in @PRINT will actually be initialized to 0. So, pedantically, your previous value starts at 0 and this just doesn't match the pseudo-random value of N.
12Me21 has a pretty good comment. I was about to mention arrays.That's pretty interesting. Thanks for all the feedback everyone. This is all a lot to chew on and practice with. I think the next thing I'll move onto is arrays like AGAaron suggested. Start small and work your way up.This is where I put the "check" in with IF X=N. At the moment the program has never seen X before and so it doesn't matter and just skips it over @PRINT IF X==N THEN GOTO @SPIN IF N==2 THEN PRINT A$ blah blah blah GOTO @ENDThis isn't quite what is happening. Since you don't have OPTION STRICT on, the first time SmileBasic "sees" the variable X, it is created. Since you don't manually do a VAR X = value, X in @PRINT will actually be initialized to 0. So, pedantically, your previous value starts at 0 and this just doesn't match the pseudo-random value of N.