home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / euphor10.zip / TTT.EX < prev    next >
Text File  |  1993-06-11  |  18KB  |  892 lines

  1.         -------------------------------
  2.         -- 3-Dimensional Tic Tac Toe --
  3.         -------------------------------
  4. -- Play 3 dimensional tic-tac-toe against one ot 2 computer algorithms
  5. -- or against another human -- or let the 2 computer algorithms play
  6. -- each other. Which algorithm is better?
  7. -- Enter your move by typing a 3-digit code.
  8.  
  9. -- There are two major data structures. One describes each board position.
  10. -- The other describes each possible winning line of 4 positions in a row.
  11.  
  12. include graphics.e
  13.  
  14. constant TRUE = 1, FALSE = 0
  15.  
  16. constant COLOR = TRUE -- set to FALSE if you don't want color
  17.  
  18. constant KEYB = 0, SCREEN = 1  -- I/O devices
  19.  
  20. constant
  21.     NPOSITIONS = 64,  -- number of board positions
  22.     NLINES = 76   -- number of 4-in-a-row lines
  23.  
  24. type line(integer x)
  25.     return x >= 0 and x <= NLINES
  26. end type
  27.  
  28. type Position(integer x)
  29.     return x >= 0 or x <= NPOSITIONS
  30. end type
  31.  
  32. type all_positions(sequence x)
  33.     return length(x) = NPOSITIONS
  34. end type
  35.  
  36. type all_lines(sequence x)
  37.     return length(x) = NLINES
  38. end type
  39.  
  40. type boolean(integer x)
  41.     return x = TRUE or x = FALSE
  42. end type
  43.  
  44. type players(sequence x)
  45.     return length(x) = 4
  46. end type
  47.  
  48. type joysticks(sequence x)
  49.     return length(x) = 4
  50. end type
  51.  
  52. type player_number(integer x)
  53.     return x = 1 or x = 2
  54. end type
  55.  
  56. type positive_int(integer x)
  57.     return x >= 1
  58. end type
  59.  
  60. type natural(integer x)
  61.     return x >= 0
  62. end type
  63.  
  64. type human_count(integer x)
  65.     return x >=0 and x <= 2
  66. end type
  67.  
  68. type move_value(integer x)
  69.     return integer(x) and x >= -1
  70. end type
  71.  
  72. type time_delay(integer x)
  73.     return x >= 0 and x < 1000
  74. end type
  75.  
  76. type reason_number(integer x)
  77.     return x >= 1 and x <= 10
  78. end type
  79.  
  80. type three_digits(sequence x)
  81.     return length(x) = 3
  82. end type
  83.  
  84. type move_number(integer x)
  85.     return x >= 111 and x <= 444
  86. end type
  87.  
  88. all_positions p
  89.     -- p is a list of all the board positions
  90.  
  91. constant
  92.     -- p columns:
  93.     LINES_THRU = 1, -- the number of lines passing through this position
  94.     LINE1 = 2,  -- the first of up to 7 lines passing
  95.         -- through this position
  96.     NLIVE = 9,  -- the number of "live" lines passing through this position
  97.     NEXTP = 10,  -- index of next position (or 0)
  98.     PREVP = 11, -- index of previous position (or 0)
  99.     AVAIL = 12  -- is this position available, 1 = yes, 0 = no
  100.  
  101. all_lines l
  102.     -- l is a list of all the lines of 4 positions in a row
  103.     -- it is indexed from 1 to NLINES
  104.  
  105. constant
  106.     -- l columns:
  107.     COUNT = 1,   -- number of "live" markers on this line
  108.     POS1 = 2,    -- first position of 4
  109.     POS4 = 5,    -- last position
  110.     NEXTL = 6,   -- index of next line (or 0)
  111.     PREVL = 7,   -- index of previous line (or 0)
  112.     STATUS = 8,  -- status of this line
  113.     -- possible status of a line:
  114.     EMPTY = 0,
  115.     COMPUTER = 1,
  116.     HUMAN = 2,
  117.     DEAD = 3
  118.  
  119.        sequence lp       -- L->P format
  120.        all_positions pl  -- P->L format
  121.        sequence dbl      -- used in 3x3 check
  122.        players ptype,    -- player types
  123.            pname     -- player names
  124.  
  125.        line fptr,  -- free position list
  126.         cptr,  -- computer's line list
  127.         hptr,  -- human's line list
  128.         eptr   -- empty line list
  129.        player_number player
  130.        natural cmoves, hmoves, l2
  131.        boolean endgame, found
  132.        human_count humans
  133.        move_value bestval
  134.        atom x
  135.        sequence marker
  136.  
  137. procedure Color(natural position)
  138. -- set appropriate foreground and background colors
  139. -- given the position and the marker
  140.  
  141.     if COLOR = FALSE then
  142.     return
  143.     end if
  144.     if position >= 411 then
  145.     text_color(15)
  146.     bk_color(4)
  147.     elsif position >= 311 then
  148.     text_color(15)
  149.     bk_color(2)
  150.     elsif position >= 211 then
  151.     text_color(15)
  152.     bk_color(5)
  153.     elsif position >= 111 then
  154.     text_color(15)
  155.     bk_color(1)
  156.     else
  157.     text_color(15)
  158.     bk_color(0)
  159.     end if
  160. end procedure
  161.  
  162. procedure Delay(time_delay t)
  163.     atom t0
  164.  
  165.     if humans = 0 and endgame = FALSE then
  166.     return
  167.     end if
  168.     t0 = time()
  169.     while time() < t0 + t/700 do
  170.     end while
  171. end procedure
  172.  
  173. procedure Why(reason_number reason)
  174.     position(22, 11)
  175.     if reason = 1 then
  176.     puts(SCREEN, "BLOCK 3 IN A ROW")
  177.     elsif reason = 2 then
  178.     puts(SCREEN, "FORCE 3X3       ")
  179.     elsif reason = 3 then
  180.     puts(SCREEN, "FORCE 3-2-2-1   ")
  181.     elsif reason = 4 then
  182.     puts(SCREEN, "FORCE 3-2-2     ")
  183.     elsif reason = 5 then
  184.     puts(SCREEN, "PREVENT 3X3     ")
  185.     elsif reason = 6 then
  186.     puts(SCREEN, "PREVENT 3-2-2-1 ")
  187.     elsif reason = 7 then
  188.     puts(SCREEN, "PREVENT 3-2-2   ")
  189.     elsif reason = 8 then
  190.     printf(SCREEN, "VALUE=%d         ", bestval)
  191.     else
  192.     puts(SCREEN, "                ")
  193.     end if
  194. end procedure
  195.  
  196.  
  197. function Get4th()
  198. integer pos
  199.     for z = POS1 to POS4 do
  200.     pos = l[x][z]
  201.     if p[lp[pos]][AVAIL] = 0 then
  202.         return pos
  203.     end if
  204.     end for
  205. end function
  206.  
  207.  
  208. function Find2()
  209. integer pos
  210.     for z = POS1 to POS4 do
  211.     pos = l[x][z]
  212.     if p[lp[pos]][AVAIL] = 0 then
  213.         dbl[l2] = pos
  214.         l2 = l2 + 1
  215.     end if
  216.     end for
  217.     if l2 < 4 then
  218.     return 0
  219.     end if
  220.     for z = l2 - 2 to l2 - 1 do
  221.     for z1 = 1 to l2 - 3 do
  222.         if dbl[z] = dbl[z1] then
  223.         found = TRUE
  224.         return dbl[z]
  225.         end if
  226.     end for
  227.     end for
  228.     return 0
  229. end function
  230.  
  231.  
  232. function FindA()
  233. -- find pattern "A"
  234. integer k, z1, line, zz
  235.     k = 0
  236.     for z = POS1 to POS4 do
  237.     z1 = lp[l[x][z]]
  238.     for i = LINE1 to p[z1][LINES_THRU] + 1 do
  239.         line = p[z1][i]
  240.         if l[line][STATUS] = l2 then
  241.         if l[line][COUNT] = 2 then
  242.             k = k + 1
  243.             exit
  244.         end if
  245.         end if
  246.     end for
  247.     if k = 3 then
  248.         zz = z
  249.         exit
  250.     end if
  251.     end for
  252.     if k = 3 then
  253.     found = TRUE
  254.     return l[x][zz]
  255.     end if
  256.     return 0
  257. end function
  258.  
  259.  
  260. function FindB()
  261. -- find pattern "B"
  262. integer k, z1, line
  263.     k = 0
  264.     for z = POS1 to POS4 do
  265.     z1 = lp[l[x][z]]
  266.     if p[z1][AVAIL] = 0 then
  267.         for i = LINE1 to p[z1][LINES_THRU] + 1 do
  268.         line = p[z1][i]
  269.         if l[line][STATUS] = l2 then
  270.             if l[line][COUNT] = 2 then
  271.             k = k + 1
  272.             exit
  273.             end if
  274.         end if
  275.         end for
  276.         if k = 2 then
  277.         found = TRUE
  278.         return l[x][z]
  279.         end if
  280.     end if
  281.     end for
  282.     return 0
  283. end function
  284.  
  285.  
  286. function FindMax()
  287. -- find best free position
  288. integer i, bestm
  289.     i = fptr
  290.     bestval = -1
  291.     while i do
  292.     if p[i][NLIVE] > bestval then
  293.         bestval = p[i][NLIVE]
  294.         bestm = i
  295.     elsif p[i][NLIVE] = bestval then
  296.         if rand(7) = 1 then
  297.         bestm = i
  298.         end if
  299.     end if
  300.     i = p[i][NEXTP]
  301.     end while
  302.     return pl[bestm]
  303. end function
  304.  
  305.  
  306. function numeric(sequence string)
  307. -- convert digit string to a number
  308.     natural n
  309.     positive_int i
  310.  
  311.     n = 0
  312.     i = 1
  313.  
  314.     -- delete any leading blanks
  315.     while string[i] = ' ' do
  316.     i = i + 1
  317.     end while
  318.  
  319.     while string[i] != '\n' and string[i] != ' ' do
  320.     n = n * 10 + string[i] - '0'
  321.     i = i + 1
  322.     end while
  323.     return n
  324. end function
  325.  
  326.  
  327. function GetMove()
  328. -- get the human's move
  329.     integer m
  330.  
  331.     while 1 do
  332.     position(20, 1)
  333.     puts(SCREEN, repeat(' ', 40))
  334.     position(20, 1)
  335.     puts(SCREEN, pname[player])
  336.     puts(SCREEN, "'S MOVE? ")
  337.     m = numeric(gets(KEYB))
  338.     if m >= 111 and m <= 444 then
  339.         if lp[m] then
  340.         if p[lp[m]][AVAIL] = 0 then
  341.             puts(SCREEN, repeat(' ', 40))
  342.             return m
  343.         else
  344.             puts(SCREEN, "OCCUPIED ALREADY")
  345.         end if
  346.         else
  347.         puts(SCREEN, "DIGITS MUST BE 1 to 4")
  348.         end if
  349.     else
  350.         puts(SCREEN, "MUST BE 111 to 444")
  351.     end if
  352.     end while
  353. end function
  354.  
  355.  
  356. procedure AdjValues(integer x, integer delta)
  357. integer pos
  358.     for z = POS1 to POS4 do
  359.     pos = lp[l[x][z]]
  360.     p[pos][NLIVE] = p[pos][NLIVE] + delta
  361.     end for
  362. end procedure
  363.  
  364.  
  365. procedure Relink(integer player, integer x)
  366.  
  367.     line prev, next
  368.  
  369.     next = l[x][NEXTL]
  370.     prev = l[x][PREVL]
  371.  
  372.     if player = COMPUTER then
  373.     AdjValues(x, 1)
  374.     l[x][NEXTL] = cptr
  375.     l[x][PREVL] = 0
  376.     if cptr then
  377.         l[cptr][PREVL] = x
  378.     end if
  379.     cptr = x
  380.     else
  381.     l[x][NEXTL] = hptr
  382.     l[x][PREVL] = 0
  383.     if hptr then
  384.         l[hptr][PREVL] = x
  385.     end if
  386.     hptr = x
  387.     end if
  388.     if prev then
  389.     l[prev][NEXTL] = next
  390.     if next then
  391.         l[next][PREVL] = prev
  392.     end if
  393.     else
  394.     eptr = next
  395.     if eptr then
  396.         l[eptr][PREVL] = 0
  397.     end if
  398.     end if
  399. end procedure
  400.  
  401. function digits(natural x)
  402. -- return the 3-digits in number x
  403.     three_digits d
  404.  
  405.     d = {0, 0, 0}
  406.     while x >= 100 do
  407.     d[1] = d[1] + 1
  408.     x = x - 100
  409.     end while
  410.  
  411.     while x >= 10 do
  412.     d[2] = d[2] + 1
  413.     x = x - 10
  414.     end while
  415.  
  416.     d[3] = x
  417.     return d
  418. end function
  419.  
  420.  
  421. procedure PrintMove(move_number move)
  422. -- print the move that was just made
  423.     three_digits d
  424.     integer px, py
  425.  
  426.     d = digits(move)
  427.     py = (d[1] - 1) * 4 + d[2] + 1
  428.     px = (d[1] - 1) * 7 + d[3] * 4
  429.     Color(move)
  430.     for i = 1 to 3 do
  431.     position(py, px)
  432.     puts(SCREEN, "   ")
  433.     Delay(70)
  434.     position(py, px)
  435.     if player = COMPUTER then
  436.         puts(SCREEN, " " & marker[1] & " ")
  437.     else
  438.         puts(SCREEN, " " & marker[2] & " ")
  439.     end if
  440.     Delay(70)
  441.     end for
  442.     Color(0)
  443.     if endgame then
  444.     return
  445.     end if
  446.     if player = COMPUTER then
  447.     cmoves = cmoves + 1
  448.     else
  449.     hmoves = hmoves + 1
  450.     end if
  451. end procedure
  452.  
  453.  
  454. procedure Another(line x)
  455.     integer inarow
  456.  
  457.     inarow = l[x][COUNT] + 1
  458.     l[x][COUNT] = inarow
  459.     if inarow < 4 then
  460.     return
  461.     end if
  462.     position(21,6)
  463.     puts(SCREEN, pname[player])
  464.     puts(SCREEN, " WINS!          ")
  465.     endgame = TRUE
  466.     for i = 1 to 4 do
  467.     for j = POS1 to POS4 do
  468.         PrintMove(l[x][j])
  469.     end for
  470.     Delay(80)
  471.     end for
  472. end procedure
  473.  
  474.  
  475. procedure Delete_c(line x)
  476. -- delete from computer list
  477.     line prev, next
  478.  
  479.     prev = l[x][PREVL]
  480.     next = l[x][NEXTL]
  481.     if prev then
  482.     l[prev][NEXTL] = next
  483.     else
  484.     cptr = next
  485.     end if
  486.     if next then
  487.     l[next][PREVL] = prev
  488.     end if
  489. end procedure
  490.  
  491.  
  492. procedure Delete_h(line x)
  493. -- delete from human list
  494.     line prev, next
  495.  
  496.     prev = l[x][PREVL]
  497.     next = l[x][NEXTL]
  498.     if prev then
  499.     l[prev][NEXTL] = next
  500.     else
  501.     hptr = next
  502.     end if
  503.     if next then
  504.     l[next][PREVL] = prev
  505.     end if
  506. end procedure
  507.  
  508.  
  509. procedure SayMove(move_number move)
  510.     position(18, 1)
  511.     puts(SCREEN, pname[player])
  512.     printf(SCREEN, "'S MOVE:%d ", move)
  513. end procedure
  514.  
  515.  
  516. procedure init()
  517. -- initialize variables
  518.     integer temp, u, line, t
  519.     move_number pos
  520.  
  521.     clear_screen()
  522.     endgame = FALSE
  523.     cmoves = 0
  524.     hmoves = 0
  525.     for i = 1 to NLINES do
  526.     l[i][STATUS] = EMPTY
  527.     l[i][COUNT] = 0
  528.     end for
  529.     for i = 1 to NPOSITIONS do
  530.     p[i][LINES_THRU] = 0
  531.     p[i][AVAIL] = 0
  532.     end for
  533.     line = 1
  534.     for i = POS1 to POS4 do
  535.     l[line][i] = (i-1) * 111
  536.     l[line+1][i] = (i-1) * 109 + 5
  537.     l[line+2][i] = (i-1) * 91 + 50
  538.     l[line+3][i] = (i-1) * 89 + 55
  539.     end for
  540.     line = line + 4
  541.     for i = 1 to 4 do
  542.     for j = POS1 to POS4 do
  543.         l[line][j] = i * 100 + (j-1) * 11
  544.         l[line+1][j] = i * 100 + (j-1) * 9 + 5
  545.         l[line+2][j] = (j-1) * 101 + i * 10
  546.         l[line+3][j] = (j-1) * 99 + i * 10 + 5
  547.         l[line+4][j] = (j-1) * 110 + i
  548.         l[line+5][j] = (j-1) * 90 + 50 + i
  549.     end for
  550.     line = line + 6
  551.     end for
  552.     for i = 1 to 4 do
  553.     for j = 1 to 4 do
  554.         for k = POS1 to POS4 do
  555.         t = 100 * i + 10 * j + k - 1
  556.         u = (i - 1) * 16 + (j - 1) * 4 + k - 1
  557.         lp[t] = u
  558.         pl[u] = t
  559.         l[line][k] = t
  560.         l[line+1][k] = 100 * j + 10 * (k-1) + i
  561.         l[line+2][k] = 100 * (k-1) + 10 * i + j
  562.         end for
  563.         line = line + 3
  564.     end for
  565.     end for
  566.     for i = 1 to NPOSITIONS do
  567.     p[i][PREVP] = i - 1
  568.     p[i][NEXTP] = i + 1
  569.     end for
  570.     p[1][PREVP] = 0
  571.     p[NPOSITIONS][NEXTP] = 0
  572.     fptr = 1
  573.     for i = 1 to NLINES do
  574.     l[i][NEXTL] = i + 1
  575.     l[i][PREVL] = i - 1
  576.     for j = POS1 to POS4 do
  577.         t = l[i][j]
  578.         u = lp[t]
  579.         temp = p[u][LINES_THRU] + 1
  580.         p[u][LINES_THRU] = temp
  581.         p[u][temp+1] = i
  582.     end for
  583.     end for
  584.     cptr = 0
  585.     hptr = 0
  586.     eptr = 0
  587.     l[NLINES][NEXTL] = 0
  588.     l[1][PREVL] = 0
  589.     for i = 1 to NPOSITIONS do
  590.     p[i][NLIVE] = p[i][LINES_THRU]
  591.     end for
  592.     -- print the board:
  593.     for i = 0 to 3 do
  594.     for j = 0 to 3 do
  595.         position(2+i*4+j, 4+i*7)
  596.         for k = 1 to 4 do
  597.         pos = (i+1)*100 + (j+1)*10 + k
  598.         Color(pos)
  599.         printf(SCREEN, "%d ", pos)
  600.         end for
  601.     end for
  602.     end for
  603.     position(1, 31)
  604.     Color(111)
  605.     puts(SCREEN, "3-D ")
  606.     Color(211)
  607.     puts(SCREEN, "tic ")
  608.     Color(311)
  609.     puts(SCREEN, "TAC ")
  610.     Color(411)
  611.     puts(SCREEN, "toe ")
  612.     Color(0)
  613. end procedure
  614.  
  615.  
  616. procedure UpdateMove(move_number m)
  617. -- update data structures after making move m
  618.     Position x1
  619.     line x2
  620.     integer prev, next, val, s
  621.  
  622.     x1 = lp[m]
  623.     p[x1][AVAIL] = 1
  624.     prev = p[x1][PREVP]
  625.     next = p[x1][NEXTP]
  626.     if prev then
  627.     p[prev][NEXTP] = next
  628.     if next then
  629.         p[next][PREVP] = prev
  630.     end if
  631.     else
  632.     fptr = next
  633.     if fptr then
  634.         p[fptr][PREVP] = 0
  635.     end if
  636.     end if
  637.     for j = LINE1 to 1+p[x1][LINES_THRU] do
  638.     x2 = p[x1][j]
  639.     s = l[x2][STATUS]
  640.     if s = EMPTY then
  641.         l[x2][STATUS] = player
  642.         l[x2][COUNT] = 1
  643.         Relink(player, x2)
  644.     elsif s = COMPUTER then
  645.         if player = COMPUTER then
  646.         Another(x2)
  647.         else
  648.         l[x2][STATUS] = DEAD
  649.         AdjValues(x2, -2)
  650.         Delete_c(x2)
  651.         end if
  652.     elsif s = HUMAN then
  653.         if player = HUMAN then
  654.         Another(x2)
  655.         if l[x2][COUNT] = 2 then
  656.             val = 4
  657.         else
  658.             val = 0
  659.         end if
  660.         AdjValues(x2, val)
  661.         else
  662.         if l[x2][COUNT] > 1 then
  663.             val = -5
  664.         else
  665.             val = -1
  666.         end if
  667.         l[x2][STATUS] = DEAD
  668.         AdjValues(x2, val)
  669.         Delete_h(x2)
  670.         end if
  671.     end if
  672.     end for
  673. end procedure
  674.  
  675.  
  676. function Think()
  677. -- pick the best move, return {move, reason for it}
  678.     integer m, mymoves, myptr, me, him, hisptr, hismoves
  679.  
  680.     found = FALSE
  681.     if player = COMPUTER then
  682.     mymoves = cmoves
  683.     hismoves = hmoves
  684.     myptr = cptr
  685.     hisptr = hptr
  686.     me = COMPUTER
  687.     him = HUMAN
  688.     else
  689.     mymoves = hmoves
  690.     hismoves = cmoves
  691.     myptr = hptr
  692.     hisptr = cptr
  693.     me = HUMAN
  694.     him = COMPUTER
  695.     end if
  696.  
  697.     -- Have I got 3 in a row?
  698.     if mymoves >= 3 then
  699.     x = myptr
  700.     while x do
  701.         if l[x][COUNT] = 3 then
  702.         return {Get4th(), 9}
  703.         end if
  704.         x = l[x][NEXTL]
  705.     end while
  706.     end if
  707.  
  708.     -- Does the other guy have 3 in a row?
  709.     if hismoves >= 3 then
  710.     x = hisptr
  711.     while x do
  712.         if l[x][COUNT] = 3 then
  713.         return {Get4th(), 1}
  714.         end if
  715.         x = l[x][NEXTL]
  716.     end while
  717.     end if
  718.  
  719.     -- Do I have a 2x2 force?
  720.     if mymoves >= 4 then
  721.     x = myptr
  722.     l2 = 1
  723.     while x do
  724.         if l[x][COUNT] = 2 then
  725.         m = Find2()
  726.         if found then
  727.             return {m, 2}
  728.         end if
  729.         end if
  730.         x = l[x][NEXTL]
  731.     end while
  732.  
  733.     -- Do I have a 3-2-2-1 force ?
  734.     x = eptr
  735.     l2 = me
  736.     while x do
  737.         m = FindA()
  738.         if found then
  739.         return {m, 3}
  740.         end if
  741.         x = l[x][NEXTL]
  742.     end while
  743.  
  744.     -- do I have a 3-2-2 force?
  745.     if mymoves >= 5 then
  746.         x = myptr
  747.         while x do
  748.         if l[x][COUNT] = 1 then
  749.             m = FindB()
  750.             if found then
  751.             return {m, 4}
  752.             end if
  753.         end if
  754.         x = l[x][NEXTL]
  755.         end while
  756.     end if
  757.     end if
  758.  
  759.     -- does the other guy have a 2x2 force?
  760.     if hismoves >= 4 then
  761.     x = hisptr
  762.     l2 = 1
  763.     while x do
  764.         if l[x][COUNT] = 2 then
  765.         m = Find2()
  766.         if found then
  767.             return {m, 5}
  768.         end if
  769.         end if
  770.         x = l[x][NEXTL]
  771.     end while
  772.  
  773.     -- does the other guy have a 3-2-2-1 force?
  774.     x = eptr
  775.     l2 = him
  776.     while x do
  777.         m = FindA()
  778.         if found then
  779.         return {m, 6}
  780.         end if
  781.         x = l[x][NEXTL]
  782.     end while
  783.  
  784.     -- does the other guy have a 3-2-2 force?
  785.     if hismoves >= 5 then
  786.         x = hisptr
  787.         while x do
  788.         if l[x][COUNT] = 1 then
  789.             m = FindB()
  790.             if found then
  791.             return {m, 7}
  792.             end if
  793.         end if
  794.         x = l[x][NEXTL]
  795.         end while
  796.     end if
  797.     end if
  798.     -- just pick the move with the most possibilities
  799.     return {FindMax(), 8}
  800. end function
  801.  
  802.  
  803. procedure Setup()
  804. -- create arrays
  805.     object name
  806.  
  807.     p = repeat(repeat(0, 12), NPOSITIONS)
  808.     l = repeat(repeat(0, 8), NLINES)
  809.     lp = repeat(0, 444)
  810.     pl = repeat(0, 64)
  811.     dbl = repeat(0, 52)
  812.     ptype = repeat(0, 4)
  813.     pname = ptype
  814.     ptype[1] = COMPUTER
  815.     ptype[2] = COMPUTER
  816.     pname[1] = "DEFENDO"
  817.     pname[2] = "AGGRESSO"
  818.     puts(SCREEN, "Name of player 1? (cr for DEFENDO) ")
  819.     name = gets(KEYB)
  820.     name = name[1..length(name)-1]
  821.     humans = 0
  822.     if length(name) > 0 then
  823.     pname[1] = name
  824.     ptype[1] = HUMAN
  825.     humans = humans + 1
  826.     end if
  827.     puts(SCREEN, "\nName of player 2? (cr for AGGRESSO) ")
  828.     name = gets(KEYB)
  829.     name = name[1..length(name)-1]
  830.     if (length(name) > 0) then
  831.     pname[2] = name
  832.     ptype[2] = HUMAN
  833.     humans = humans + 1
  834.     end if
  835.     marker = pname[1][1] & pname[2][1]
  836.     if marker[1] = marker[2] then
  837.     if marker[1] != 'X' then
  838.         marker[2] = 'X'
  839.     else
  840.         marker[2] = '0'
  841.     end if
  842.     end if
  843. end procedure
  844.  
  845. procedure ttt()
  846. -- this is the main routine
  847.     sequence m, answer
  848.  
  849.     Color(0)
  850.     Setup()
  851.     player = rand(2)
  852.     while 1 do
  853.     init()
  854.     while endgame = FALSE do
  855.         if fptr then
  856.         if ptype[player] = HUMAN then
  857.             m = {GetMove()}
  858.         else
  859.             m = Think()
  860.             SayMove(m[1])
  861.             Why(m[2])
  862.         end if
  863.         PrintMove(m[1])
  864.         UpdateMove(m[1])
  865.         player = 3 - player
  866.         else
  867.         position(18,1)
  868.         puts(SCREEN, "A DRAW             ")
  869.         Delay(500)
  870.         exit
  871.         end if
  872.     end while
  873.     position(19, 1)
  874.     puts(SCREEN, "Another game?")
  875.     answer = gets(KEYB)
  876.     if length(answer) > 1 then
  877.         if answer[1] = 'n' then
  878.         exit
  879.         end if
  880.     end if
  881.     end while
  882. end procedure
  883.  
  884. ttt()
  885. if COLOR then
  886.     text_color(7)
  887.     bk_color(0)
  888. end if
  889. clear_screen()
  890.  
  891.  
  892.