home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / snobol / vsnobol / tictac.sno < prev    next >
Text File  |  1991-02-14  |  5KB  |  149 lines

  1. *    This program plays a rudimentary game of TIC-TAC-TOE.
  2. *
  3. *    Although the strategy is not elaborate, it illustrates
  4. *    how pattern matching can be used to analyse board positions.
  5. *
  6. *    The board is represented by a nine-character string.  Each string
  7. *    position may contain an "X" (player), "O" (program), or "." (vacant).
  8. *
  9. *    The correspondence between character position and the board is:
  10. *
  11. *        0 | 1 | 2
  12. *        ---------
  13. *        3 | 4 | 5
  14. *        ---------
  15. *        6 | 7 | 8
  16. *
  17. *
  18. *    From STRING AND LIST PROCESSING IN SNOBOL4 by Ralph E. Griswold,
  19. *             by permission of the author.
  20. *    ----------------------------------------------------------------
  21. *
  22. *
  23. *    (c) Copyright 1985 - Catspaw, Incorporated
  24. *
  25. -TICTAC
  26. *********************************************************************
  27. *                            INITIALIZATION                         *
  28. *********************************************************************
  29.     &TRIM    =    1
  30.     DEFINE("COL(C1,C2,C3)")
  31.     DEFINE("DIAG(C1,C2,C3)")
  32.     DEFINE("ROW(C1,C2,C3)")
  33.     DEFINE("TWO(M)")
  34.     UC    =    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  35.     LC    =    'abcdefghijklmnopqrstuvwxyz'
  36.     SKIP    =    NULL . OUTPUT
  37.     ROW    =    LEN(3) . OUTPUT
  38.     PRINT    =    SKIP ROW ROW ROW SKIP
  39. *********************************************************************
  40. *                            BOARD PATTERNS                         *
  41. *********************************************************************
  42. *    Columns start at character positions 0, 1, and 2:
  43.     C    =    TAB(0) | TAB(1) | TAB(2)
  44.  
  45. *    Rows start at character positions 0, 3, and 6:
  46.     R    =    TAB(0) | TAB(3) | TAB(6)
  47.  
  48. *    Assign scanner position to M, then see if the next square is free:
  49.     F    =    @M "."
  50.  
  51. *    Pattern to take a vacant square at position M:
  52.     P    =    POS(*M) "."
  53.  
  54. *    Pattern to determine if the center square is free.  Set M = 4 if so.
  55.     CENTER    =    TAB(4) F
  56.  
  57. *    Pattern to see if any corner is free, set M = corner if so.
  58.     CORNER    =    (TAB(0) | TAB(2) | TAB(6) | TAB(8)) F
  59.  
  60. *    SNOBOL4 can win if there are two O's and a free square in a line:
  61.     WIN    =    TWO("O")
  62.  
  63. *    SNOBOL4 must block user if two X's and a free square in a line:
  64.     BLOCK    =    TWO("X")
  65.  
  66. *    SNOBOL4 loses if row, column, or diagonal of 3 X's:
  67.     LOSE    =    ROW("X","X","X") | COL("X","X","X") |
  68. +            DIAG("X","X","X")
  69.  
  70. *    Block if necessary, else seize corner, else any take first free square:
  71.     PLAY    =    BLOCK | CORNER | F
  72.  
  73. *********************************************************************
  74. *                            INTRODUCTION                           *
  75. *********************************************************************
  76.     OUTPUT    =    "This program plays TIC-TAC-TOE.  Your mark is"
  77. +            " X and you will play first."
  78.     OUTPUT    =    "The board is numbered as follows:"
  79.     "012345678"    PRINT
  80.     OUTPUT    =    "When it is your turn to play, type the number"
  81. +            " of the square you wish to mark."
  82.     OUTPUT    =    "For example, if you type '4', the result is:"
  83.     "....X...."    PRINT
  84.     OUTPUT    =    "Any time it is your turn to play, you may"
  85. +            " start a new game by typing 'N'"
  86.     OUTPUT    =    "or end the session by typing 'Q'"
  87. *********************************************************************
  88. *                            GAME PLAY                              *
  89. *********************************************************************
  90. START    OUTPUT    =    DUPL("-",10)
  91.     OUTPUT    =    "NEW GAME"
  92.     BOARD    =    DUPL(".",9)
  93.  
  94. NEXT    OUTPUT    =    "Your play"
  95.     M    =    REPLACE(INPUT,LC,UC)            :F(ABAND)
  96.     IDENT(M,"N")                        :S(START)
  97.     IDENT(M,"Q")                        :S(STOP)
  98.     INTEGER(M)                        :F(ERROR)
  99.  
  100. *    Make move for user:
  101.     BOARD    P    =    "X"                :F(ERROR)
  102.  
  103. *    Try to seize the center:
  104.     BOARD    CENTER                        :S(MINE)
  105.  
  106. *    Check if we lost:
  107.     BOARD    LOSE                        :S(LOSE)
  108.  
  109. *    Check if we won:
  110.     BOARD    WIN                        :S(WIN)
  111.  
  112. *    Neither.  Select our next move:
  113.     BOARD    PLAY                        :F(TIE)
  114.  
  115. *    Make our move into position M.
  116. MINE    BOARD    P    =    "O"
  117.     BOARD    PRINT                        :(NEXT)
  118.  
  119. LOSE    OUTPUT    =    "You win"                :(NEW)
  120.  
  121. TIE    OUTPUT    =    "Tie game"                :(NEW)
  122.  
  123. WIN    BOARD    P    =    "O"
  124.     OUTPUT    =    "I win"
  125.  
  126. NEW    BOARD    PRINT                        :(START)
  127. ABAND    OUTPUT    =    'Session abandoned'            :(END)
  128. STOP    OUTPUT    =    'Session ended'                :(END)
  129. ERROR    OUTPUT    =    'Erroneous move - try again'         :(NEXT)
  130. *********************************************************************
  131. *                            FUNCTION DEFINITIONS                   *
  132. *********************************************************************
  133.  
  134. * Function returns pattern to check for C1, C2, C3 adjacent in any column.
  135. COL    COL    =    C C1 LEN(2) C2 LEN(2) C3        :(RETURN)
  136.  
  137. * Function returns pattern to check for C1, C2, C3 adjacent in any diagonal.
  138. DIAG    DIAG    =    TAB(0) C1 TAB(4) C2 TAB(8) C3 |
  139. +            TAB(2) C1 TAB(4) C2 TAB(6) C3        :(RETURN)
  140.  
  141. * Function returns pattern to check for C1, C2, C3 adjacent in any row.
  142. ROW    ROW    =    R C1 C2 C3                :(RETURN)
  143.  
  144. * Function returns pattern to check for two marks (M) and a vacant square:
  145. TWO    TWO    =    ROW(F,M,M) | ROW(M,F,M) | ROW(M,M,F) |
  146. +            COL(F,M,M) | COL(M,F,M) | COL(M,M,F) |
  147. +            DIAG(F,M,M) | DIAG(M,F,M) | DIAG(M,M,F)    :(RETURN)
  148. END
  149.