Array Assignment Problem
I feel very close now and would really appreciate some help getting over the finishing line.
A sequence of 125 is made up of a number of cycles with varying numbers of active elements (between 1 and 5 per cycle )
The sticking point for me is:
If I run the code with the array assignment commented out the debug output looks perfect, as soon as I uncomment the line below it all goes horribly wrong.
Also I've just spotted another issue. getActive:is supposed to generate a new "active" then loop through the confirmed array looking to see if it already exists in it. If it does it sets flag=1. All my testing shows this to work and only returns 2 if the array doesn't already hold that particular value.
Back in the main:
is supposed to check the value of flag and if it's 2 write the active into the current index(i) so duplicates shouldn't be possible. As the assigning to the array is broken (see above) in debug I just concatenate the values to see what the assignment statement would look like, when I look at this i do see duplicates. What's the problem there?
A sequence of 125 is made up of a number of cycles with varying numbers of active elements (between 1 and 5 per cycle )
The sticking point for me is:
IF flag = 2 THEN
confirmed(i)=active
ENDIF
If I run the code with the array assignment commented out the debug output looks perfect, as soon as I uncomment the line below it all goes horribly wrong.
confirmed(i)=active
' {$STAMP BS2sx}
' {$PBASIC 2.5}
'---------------variables---------------
sequence VAR Byte
relays VAR Byte
irelays VAR Byte
cycles VAR Byte
active VAR Nib
i VAR Nib
x VAR Nib
confirmed VAR Byte(10)
flag VAR Nib
'---------------initialise---------------
sequence=0
relays=0
irelays=0
cycles=0
active=0
i=0
x=0
flag=0
main:
' sets up outer loop to count 125 cycles
DO WHILE (sequence < 125)
' generate random number between 1-5 relays to fire
cycles=(relays // 5+1)
RANDOM relays
' check if this cycle would sequence over 125. If it would decrement sequence otherwise increment sequence
IF sequence + cycles > 125 THEN
sequence = sequence - cycles
ELSE
sequence = sequence + cycles
'setup loop to call getActive subroutine
DEBUG DEC ? cycles, CR
FOR i = 1 TO cycles
GOSUB getActive
'tests the value of flag after getActive and if flag = 2 current active can be added to the array.
IF flag = 2 THEN
'confirmed(i)=active
DEBUG "confirmed("
DEBUG DEC i
DEBUG ") = "
DEBUG DEC active, CR
ENDIF
NEXT
DEBUG "--------------------",CR
ENDIF
LOOP
HIGH 15
DEBUG CR
DEBUG "End of sequence"
PAUSE 2000
LOW 15
END
getActive:
'generate random number between 1-5 which is active
flag=0
x=0
active=(irelays // 5+1)
RANDOM irelays
'need to run through array and set flag to 1 if active already in array or 2 if not and can be added to the array.
DO WHILE (flag <> 2)
FOR x = 1 TO 5
IF active = confirmed(x) THEN
flag = 1
ELSE
IF flag <> 1 THEN
flag = 2
ENDIF
ENDIF
NEXT
LOOP
RETURN
Also I've just spotted another issue. getActive:is supposed to generate a new "active" then loop through the confirmed array looking to see if it already exists in it. If it does it sets flag=1. All my testing shows this to work and only returns 2 if the array doesn't already hold that particular value.
Back in the main:
IF flag = 2 THEN
'confirmed(i)=active
DEBUG "confirmed("
DEBUG DEC i
DEBUG ") = "
DEBUG DEC active, CR
ENDIF
is supposed to check the value of flag and if it's 2 write the active into the current index(i) so duplicates shouldn't be possible. As the assigning to the array is broken (see above) in debug I just concatenate the values to see what the assignment statement would look like, when I look at this i do see duplicates. What's the problem there?
Comments
I've never really used the stamp before, but one basic is usually similar to another.
And hence...
I can see a few little errors and have pasted the (what I think is the) corrected code below,
but it wouldn't do any harm to get a further opinions.
I've added comments to explain each step of the changes.
hope it helps...
The main points were the MOD statement, where This is relays MOD 5
is not the same as which is relays MOD 6
and also the order in which you generated your random number,
I think you had the two lines back to front, but since I don't know stamp very well I cant be sure.
' {$STAMP BS2sx} ' {$PBASIC 2.5} '---------------variables--------------- sequence VAR Byte relays VAR Byte irelays VAR Byte cycles VAR Byte active VAR Byte i VAR Byte x VAR Byte ' reduced array size to 5 since you only have 5 relays confirmed VAR Byte(5) flag VAR Nib '---------------initialise--------------- sequence=0 relays=0 irelays=0 cycles=0 active=0 i=0 x=0 flag=0 main: ' seed relays with number between 0 and65535 relays = 123 ' sets up outer loop to count 125 cycles DO WHILE (sequence < 125) ' generate random number RANDOM relays ' mod random number with 5 to end up with a value between 1 + 5 cycles=(relays // 5) + 1 ' check if this cycle would sequence over 125. If it would decrement sequence otherwise increment sequence IF sequence + cycles > 125 THEN sequence = sequence - cycles ELSE sequence = sequence + cycles 'setup loop to call getActive subroutine DEBUG DEC ? cycles, CR FOR i = 1 TO cycles GOSUB getActive 'tests the value of flag after getActive and if flag = 2 current active can be added to the array. IF flag = 2 THEN confirmed(i-1)=active DEBUG "confirmed(" DEBUG DEC i DEBUG ") = " DEBUG DEC active, CR ENDIF NEXT DEBUG "--------------------",CR ENDIF LOOP HIGH 15 DEBUG CR DEBUG "End of sequence" PAUSE 2000 LOW 15 END getActive: ' generate random number between 1-5 which is active flag=0 x=0 ' seed irelays with number between 0 and 65535 irelays=relays ' get random number between 0 and 65535 RANDOM irelays ' mod random number with 5 to end up with a value between 1 + 5 active=(irelays // 5) + 1 'need to run through array and set flag to 1 if active already in array or 2 if not and can be added to the array. FOR x = 1 TO 5 IF active = confirmed(x) THEN flag = 1 exit ' exit for loop we matched the nummber so theres no need to continue looping? ELSE flag = 2 ENDIF NEXT RETURN