Shop OBEX P1 Docs P2 Docs Learn Events
Array Assignment Problem — Parallax Forums

Array Assignment Problem

paulmorelandpaulmoreland Posts: 4
edited 2021-01-20 17:30 in BASIC Stamp
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 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

  • Hi Paul,

    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
    cycles=(relays // 5) + 1
    This is relays MOD 5

    is not the same as
    cycles=(relays // 5+1)
    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
    
    
Sign In or Register to comment.