Shop OBEX P1 Docs P2 Docs Learn Events
Select Case problem — Parallax Forums

Select Case problem

Does anyone know how to use Debug/Select/Case commands using words and sentences from keyboard ? Appreciate the
help.

Comments

  • If you want to input byte strings, you can use the STR formatter with DEBUGIN. Be aware that a BS-2 is not going to get you very far with parsing sentences. It just doesn't have enough storage space or program space.
  • Here is a little program that will try to match a single keyword from DEBUGIN and dispatch if it finds a match. You can obviously change the keywords to suit yourself. They are not case sensitive. They can each be any length up to seven characters. You can have more than four keywords.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    KW1   DATA    "Einie", 0
    KW2   DATA    "Minie", 0
    KW3   DATA    "Miney", 0
    KW4   DATA    "Moe",0
    
    NmbrKW   CON   4        'number of keywords to look for
    
    KWPoint  VAR   Nib      'pointer to current keyword
    InStrng  VAR   Byte(8)  'string from debugin
    DBPoint  VAR   Word     'pointer to beginning of current trial
    DByte    VAR   Byte     'string element from the data list
    CByte    VAR   Byte     'string element from Debugin
    X1       VAR   Nib      'pointer into current strings
    
    begin:   DEBUG  CLS, "Please type a keyword.", CR
             DEBUGIN STR InStrng \7 \CR             'input up to 7 characters, terminated with CR
             GOSUB LookItUp    'returns 1-NmbrKW if found, zero if not found
             SELECT KWPoint    'dispatch accordingly
               CASE 1
                  DEBUG "you input 'einie'", CR
    
               CASE 2
                  DEBUG "you input minie", CR
    
               CASE 3
                  DEBUG "Case Three", CR
    
               CASE 4
                  DEBUG "Case 4", CR
    
               CASE ELSE
                 DEBUG "Keyword not recognized.", CR
               ENDSELECT
               PAUSE 2000
               GOTO begin
    
    LookItUp:
             FOR KwPoint = 1 TO NmbrKW        'search one keyword at a time
                LOOKUP (KwPoint-1), [KW1, KW2, KW3, KW4], DBPoint  'get pointer to current trial keyword
                X1 = 0                                    'set offset to beginning
    LookMore:   READ (DBPoint + X1), DByte                'get current comparand
                DByte = DByte | $20                       'force lower case
                CByte = InStrng(X1) | $20                 'get byte from in, lower case
               ' DEBUG CR, DEC KWPoint, "   ", DEC x1, "   ", DByte, "   ", CByte  'diagnostic
                IF (DByte <> CByte) THEN NoMatch           'see if this byte of this kw matches
                IF (DByte = $20) THEN FullMatch            'yes, we got to terminator
                X1 = X1 + 1                                'to next byte in each
                GOTO LookMore                              'continue with current keyword
    NoMatch:
      NEXT                                          'no match, try next keyword
      KWPoint = 0                                   'no next keyword to try
      RETURN                                        'failure exit
    
    FullMatch:
      RETURN                                        'KWPoint points to keyword that matched
    
    
    
    
    
  • Thanks for the code Tom.
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2016-04-29 18:03
    Another approach to this is to map each key word onto a numerical value. For example, for key words left, right, up, down, multiply the ascii code for each letter by successive prime numbers and add them up like this:
    left 108*2+ 101*3+ 102*5+ 116*7 =1841
    right 114*2+ 105*3+ 103*5+ 104*7+ 116*11 =3062
    up 117*2+ 112*3 =570
    down 100*2+ 111*3+ 119*5+ 110*7 =1898
    By the "chinese remainder theorem", the values computed will be unique. Subsequently when you input chars from the keyboard after the prompt, sum up with the same math until you get a CR, then look for a numerical match.
    LOOKUP x,[2,3,5,7,9,11,13],y
    sum = Dbyte * y + sum

    For a small set of key words it could work by simply adding up the ascii codes, if it turns out that the sums are unique anyway.
    sum = Dbyte + sum

  • tomcrawfordtomcrawford Posts: 1,126
    edited 2016-04-30 17:39
    Here is a little program that implements what Tracy Allen suggested. It has the neat property of a really truly valid use of LOOKDOWN. It has the not-so-neat property of using "magic numbers". But in a good cause.

    Edit: Tracy, I sent you a PM regarding this thread. EndEdit
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    InStrng  VAR   Byte(10)  'string from debugin
    DByte    VAR   Byte     'string element from InStrng
    X1       VAR   Nib      'pointer into InStrng
    Value    VAR   Word     'sum corresponding to contents of Instrng
    Temp     VAR   Byte     'generally useful
    
    begin:   DEBUG  "Please type a keyword.", CR
             DEBUGIN STR InStrng \9 \CR             'input up to 7 characters, terminated with CR
             GOSUB Calc       'returns code corresponding to InStrng
             Temp = 255       'not found indicator
             LOOKDOWN Value, [1841, 3062, 570, 1898, 6189, 1731, 8293], Temp
                             'left  right up   down  forward  back  toandfro
             SELECT Temp    'dispatch accordingly
               CASE 0
                  DEBUG "LEFT", CR
    
               CASE 1
                  DEBUG "RIGHT", CR
    
               CASE 2
                  DEBUG "UP", CR
    
               CASE 3
                  DEBUG "DOWN", CR
    
               CASE 4
                  DEBUG "FORWARD", CR
    
               CASE 5
                  DEBUG "BACK", CR
    
               CASE 6
                  DEBUG "TOANDFRO", CR
    
               CASE 255
                 DEBUG "Keyword not recognized.  ", DEC value, CR
    'To add a keyword, you must put an additional entry in the LOOKDOWN command
    'and a put an additional CASE in the SELECT/CASE command.  You could also
    'replace current entries in the lookdown and select/case.
    
               CASE ELSE
                 DEBUG "This program is broken.", CR
               ENDSELECT
    
               PAUSE 2000
               GOTO begin
    
    Calc:    Value = 0
             X1 = 0
    Calc1:   DByte = InStrng(X1)           'get first (next) character
             IF (DByte = 0) THEN RETURN    'termination indicator
             LOOKUP X1, [2,3,5,7,11,13,17,19,23], Temp   'get the prime number
             Value = Value + ((DByte | $20) * Temp)      'accumulate (forcing lower case)
             X1 = X1 + 1                                 'point to next
             GOTO Calc1
    
    
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2016-04-30 18:07
    Thanks for the PM Tom! Tom pointed out my flawed logic in saying that the sums with the prime basis would be unique for every combination of letters. Easy to see. For example, with 4 letters chosen from "a" to "z". that is 26^4 = 456976 possible 4-letter words, which can't by a long shot fit in 425 values the range of "aaaa"=1649 to "zzzz"=2074. What was I thinking?! My original thought had been to calculate a CRC on string and use that for comparison. That would allow a lot 2^16 values, but would be harder to compute, and ultimately still less than the 456976 possible 4-letter words.

    The method or one like it does works though for a small set of words, just so long as the words map to unique numerical values.
  • I see I went around the barn to get where I wanted to go. The LOOKDOWN that maps the code into 1...n is totally unneedful. Just use the codes themselves in the SELECT/CASE. Saves code space and makes it easier to add new keywords.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    InStrng  VAR   Byte(10)  'string from debugin
    DByte    VAR   Byte     'string element from InStrng
    X1       VAR   Nib      'pointer into InStrng
    Value    VAR   Word     'sum corresponding to contents of Instrng
    Temp     VAR   Byte     'generally useful
    
    begin:   DEBUG  "Please type a keyword.", CR
             DEBUGIN STR InStrng \9 \CR             'input up to 7 characters, terminated with CR
             GOSUB Calc       'returns code corresponding to InStrng
             SELECT Value    'dispatch accordingly
               CASE 1841
                  DEBUG "LEFT", CR
    
               CASE 3062
                  DEBUG "RIGHT", CR
    
               CASE 570
                  DEBUG "UP", CR
    
               CASE 1898
                  DEBUG "DOWN", CR
    
               CASE 6189
                  DEBUG "FORWARD", CR
    
               CASE 1731
                  DEBUG "BACK", CR
    
               CASE 8293
                  DEBUG "TOANDFRO", CR
    
               CASE ELSE
                 DEBUG "Keyword not recognized.  ", DEC value, CR
    'To add a keyword, you can simply add another CASE (or replace one).
               ENDSELECT
    
               PAUSE 2000
               GOTO begin
    
    Calc:    Value = 0
             X1 = 0
    Calc1:   DByte = InStrng(X1)           'get first (next) character
             IF (DByte = 0) THEN RETURN    'termination indicator
             LOOKUP X1, [2,3,5,7,11,13,17,19,23], Temp   'get the prime number
             Value = Value + ((DByte | $20) * Temp)      'accumulate (forcing lower case)
             X1 = X1 + 1                                 'point to next
             GOTO Calc1
    

    Sometimes you don't see the forest for the trees.
  • I'll put in a plug for the PBASIC 2.0 primitive, BRANCH. The SELECT:CASE construct is strictly PBASIC 2.5 and resolves to a chain of IFs and GOTOs. BRANCH is faster, although maybe not so in this particular counterclockwise trip around the barn. Snippet:
    brachiosaurus:   ' come here as a GOSUB with Value
           Temp = 255
            LOOKDOWN Value, [1841, 3062, 570, 1898, 6189, 1731, 8293], Temp
           BRANCH Temp[left,  right, up,   down,  forward,  back,  toandfro]
           RETURN  ' not found, temp=255
    
    left:
          DEBUG "LEFT", CR
          RETURN
    
    ' etc., separate subroutine for each action with RETURN
    


Sign In or Register to comment.