home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / progs / ttt.icn < prev    next >
Text File  |  2000-07-29  |  7KB  |  317 lines

  1. ############################################################################
  2. #
  3. #    File:     ttt.icn
  4. #
  5. #    Subject:  Program to play tic-tac-toe
  6. #
  7. #    Author:   Chris Tenaglia
  8. #
  9. #    Date:     August 14, 1996
  10. #
  11. ############################################################################
  12. #
  13. #   This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #  This program plays the game of tic-tac-toe.
  18. #
  19. ############################################################################
  20. #
  21. #  Links:  random
  22. #
  23. ############################################################################
  24.  
  25. link random
  26.  
  27. global me,you,true,false,draw,pointer,wins,pass,taken,winner
  28. global mark,row,routes,route
  29.  
  30. procedure main()
  31.   local again, index, path, play, square, tmp, victory, your_last_move
  32.  
  33.   init()
  34.   play := true
  35.   while play == true do
  36.     {
  37.     me      := set()      # computer is me
  38.     you     := set()      # player   is you
  39.     victory := ""         # nobodys' won yet
  40.     winner  := ""         # winner flag
  41.     pass    := 0          # start flag
  42.     taken   := table(false)    # taken position table (rather than set?)
  43.     display()
  44. #
  45. # computer makes first move
  46. #
  47.     insert(me,1)
  48.     taken[1] := true
  49.     display()
  50. #
  51. # player follows
  52. #
  53.     insert(you,(tmp := integer(get_your_move())))
  54.     taken[integer(tmp)] := true
  55.     display()
  56.     path := routes[tmp]              # players' move determines strategy
  57.     index := 2                       # points at 2nd move just happened
  58.  
  59. #
  60. # computers' next move determined from strategy list
  61. #
  62.     insert(me,(tmp := integer(path[(index+:=1)])))
  63.     taken[tmp] := true
  64.     display()
  65. #
  66. # player follows
  67. #
  68.     insert(you,(tmp := integer(get_your_move())))
  69.     taken[integer(tmp)] := true
  70.     your_last_move := tmp
  71.     display()
  72. #
  73. # if didn't take position dictated, loss ensues
  74. #
  75.     if your_last_move ~= (tmp := integer(path[(index+:=1)])) then
  76.       {
  77.       winner := "me"
  78.       insert(me,tmp)
  79.       taken[tmp] := true
  80.       display()
  81.       done_yet()
  82.       write(at(1,22),chop(&host)," Wins, You Loose!")
  83.       every square := !row do writes(pointer[square],mark)
  84.       again := map(input(at(1,23) || "Another game? Y/N :"))[1]
  85.       if again=="y" then next
  86.       stop(at(1,23),"Game Over.",chop())
  87.       }
  88.  
  89. #
  90. # user made a good move, continue (computer plays now)
  91. #
  92.     insert(me,(tmp := integer(path[(index+:=1)])))
  93.     taken[tmp] := true
  94.     display()
  95. #
  96. # player follows
  97. #
  98.     insert(you,(tmp := integer(get_your_move())))
  99.     taken[integer(tmp)] := true
  100.     your_last_move := tmp
  101.     display()
  102.  
  103. #
  104. # if didn't take position dictated, loss ensues
  105. #
  106.     if your_last_move ~= (tmp := integer(path[(index+:=1)])) then
  107.       {
  108.       winner := "me"
  109.       insert(me,tmp)
  110.       taken[tmp] := true
  111.       display()
  112.       done_yet()
  113.       write(at(1,22),chop(&host)," Wins, You Loose!")
  114.       every square := !row do writes(pointer[square],mark)
  115.       again := map(input(at(1,23) || "Another game? Y/N :"))[1]
  116.       if again=="y" then next
  117.       stop(at(1,23),"Game Over.",chop())
  118.       }
  119. #
  120. # if players first move wasn't 5, they lose now too
  121. #
  122.     if integer(path[2]) ~= 5 then
  123.       {
  124.       tmp := integer(path[(index+:=1)])
  125.       winner := "me"
  126.       insert(me,tmp)
  127.       taken[tmp] := true
  128.       display()
  129.       done_yet()
  130.       write(at(1,22),chop(&host)," Wins, You Loose!")
  131.       every square := !row do writes(pointer[square],mark)
  132.       again := map(input(at(1,23) || "Another game? Y/N :"))[1]
  133.       if again=="y" then next
  134.       stop(at(1,23),"Game Over.",chop())
  135.       }
  136.  
  137. #
  138. # user made a good move, continue (computer plays now)
  139. #
  140.     insert(me,(tmp := integer(path[(index+:=1)])))
  141.     taken[tmp] := true
  142.     display()
  143.     write(at(1,22),chop(),"Game was a draw.")
  144.     again := map(input(at(1,23) || "Another game? Y/N :"))[1]
  145.     if again=="y" then next
  146.     stop(at(1,23),"Game Over.",chop())
  147.     }
  148.   end
  149. #
  150. # procedure to display the current tictactoe grid and plays
  151. #               
  152. procedure display()
  153.   local line, x, y
  154.  
  155.   if (pass +:= 1) = 1 then
  156.     {
  157.     write(cls(),uhalf(),"          T I C - T A C - T O E")
  158.     write(lhalf(),"          T I C - T A C - T O E")
  159.     write(trim(center("Computer is 'O' and you are 'X'",80)))
  160.     line := repl("q",60) ; line[21] := "n" ; line[41] := "n"
  161.     every y := 5 to 20 do writes(at(30,y),graf("x"))
  162.     every y := 5 to 20 do writes(at(50,y),graf("x"))
  163.     writes(at(10,10),graf(line))
  164.     writes(at(10,15),graf(line))
  165.     every x := 1 to 9  do writes(pointer[x],dim(x))
  166.     }
  167.   every writes(pointer[!me],high("O"))
  168.   every writes(pointer[!you],under("X"))
  169.   end
  170.                 
  171. #
  172. # procedure to obtain a move choice from the player
  173. #
  174. procedure get_your_move()
  175.   local yours,all_moves
  176.   repeat {
  177.   writes(at(5,22))
  178.   yours := input("Enter block # (1-9) :")
  179.   writes(at(5,23),chop())
  180.   if not(integer(yours)) then
  181.     {
  182.     writes(at(5,23),beep(),"Invalid Input! Choose 1-9.")
  183.     next
  184.     }
  185.   if (1 > yours) | (yours > 9) then
  186.     {
  187.     writes(at(5,23),beep(),"Value out of range! Choose 1-9.")
  188.     next
  189.     }
  190.   if taken[integer(yours)] == true then
  191.     {
  192.     writes(at(5,23),beep(),"That position is already taken! Try again.")
  193.     next
  194.     }
  195.   break }
  196.   return integer(yours)
  197.   end
  198.  
  199. #
  200. # procedure to test if computer has won, or the game is a draw
  201. #
  202. procedure done_yet()
  203.   local outcome, test, part
  204.  
  205.   every outcome := !wins do
  206.     {
  207.     test := 0
  208.     every part := !outcome do
  209.       if member(you,part) then test +:= 1
  210.     if test = 3 then
  211.       {
  212.       winner := "you"
  213.       row    := outcome
  214.       mark   := high(blink("X"))
  215.       return true
  216.       }
  217.     }
  218.   every outcome := !wins do
  219.     {
  220.     test := 0
  221.     every part := !outcome do
  222.       if member(me,part) then test +:= 1
  223.     if test = 3 then
  224.       {
  225.       winner := "me"
  226.       row    := outcome
  227.       mark   := high(blink("O"))
  228.       return true
  229.       }             
  230.     }
  231.   if *me + *you > 8 then
  232.     {
  233.     winner := draw
  234.     return draw
  235.     }
  236.   return "not done yet"
  237.   end
  238. #
  239. # prompts for an input from the user
  240. #
  241. procedure input(prompt)
  242.   writes(prompt)
  243.   return read()
  244.   end
  245. #
  246. # procedures to output ansi graphics and attributes
  247. #
  248. procedure at(x,y)
  249.   return "\e[" || y || ";" || x || "f"
  250.   end
  251.   
  252. procedure graf(str)
  253.   return "\e(0" || str || "\e(B"
  254.   end
  255.  
  256. procedure uhalf(str)
  257.   /str := ""
  258.   return "\e#3" || str
  259.   end
  260.  
  261. procedure lhalf(str)
  262.   /str := ""
  263.   return "\e#4" || str
  264.   end
  265.  
  266. procedure high(str)
  267.   return "\e[1m" || str || "\e[0m"
  268.   end
  269.  
  270. procedure normal(str)
  271.   return "\e[0m" || str
  272.   end
  273.  
  274. procedure dim(str)
  275.   return "\e[2m" || str || "\e[0m"
  276.   end
  277.   
  278. procedure under(str)
  279.   return "\e[4m" || str || "\e[0m"
  280.   end
  281.  
  282. procedure blink(str)
  283.   return "\e[5m" || str || "\e[0m"
  284.   end
  285.  
  286. procedure cls(str)
  287.   /str := ""
  288.   return "\e[2J\e[H" || str
  289.   end
  290.  
  291. procedure chop(str)
  292.   /str := ""
  293.   return "\e[J" || str
  294.   end
  295.  
  296. procedure beep()
  297.   return "\7"
  298.   end
  299. #
  300. # procedure to init useful global variables for later use
  301. #
  302. procedure init()
  303.   true    := "y"
  304.   false   := "n"
  305.   draw    := "?"
  306.   randomize()
  307.   routes  := ["-","1274958","1374958","1432956","1547328",
  308.                   "1632745","1732956","1874352","1974352"]
  309.   wins    := [set([1,5,9]),set([3,5,7]),set([1,2,3]),set([4,5,6]),
  310.               set([7,8,9]),set([1,4,7]),set([2,5,8]),set([3,6,9])]
  311.   pointer := [at(17,7), at(37,7), at(57,7),
  312.               at(17,12),at(37,12),at(57,12),
  313.               at(17,17),at(37,17),at(57,17)]
  314.   end
  315.   
  316.  
  317.