The Book
ON INCHAT
{
ttt GLOBAL ;tictactoe game state variable
xpl GLOBAL ;string name of X ttt player
opl GLOBAL ;string name of O ttt player
tttb GLOBAL ;ttt board value
plt GLOBAL ;number of ttt player whose turn it is 1=X 2=O
pltn GLOBAL ;name of ttt player whose turn it is
br GLOBAL ;Board Row of ttt
bc GLOBAL ;Board Column of ttt

;TicTacToe initialization routine- set up board and array
	{
	 {1 ttt =		;set game state variable to 1
	  "TTT" mousepos ADDLOOSEPROP ;put board on screen at mouse position
	  mousepos br = bc =	;store mouse position in br and bc variables
	  0 tttb = ;put board variable to zero- blank board
	  "" xpl = "" opl = ;set player names to null strings
	 }WHOCHAT WHOME == 0 ttt == AND IF ;if the person saying that is you...
	} CHATSTR "Play TicTacToe" == IF ;If someone says that

;Assign players section of TTT:
	{
	 {{WHOCHAT WHONAME opl = ;name of person saying that assigned to opl
	  ttt++ opl " is O" + bc br SAYAT ;print board message
	  } "" opl == IF ;only if no one is already O
	 } CHATSTR "^[Ii].* be [Oo].*" GREPSTR IF ;if someone says this..
		;exact format: either I or i, followed by anything, followed by "be" space O or o
		;followed by anything. "I be O" "i'll be o" "I want to be O!!!!" all work
	 {{WHOCHAT WHONAME xpl = 1 plt = xpl pltn = ;set player turn and name variables
	  ttt++ xpl " is X" + bc br SAYAT ;X always goes first
	  } "" xpl == IF
	 } CHATSTR "^[Ii].* be [Xx].*" GREPSTR IF
	} ttt 0 > ttt 3 < * IF ;subroutine active only if variable is 1 or 2
	;it starts at one, when one player is assigned, it goes to 2, when both assigned, it goes 	
	;to three... and that activates the play section:

;Play section of TTT:
	{  ;look at the end of these brackets to find the conditions to get in
	 {
	  {
	   "$1" GREPSUB mo = ;assigns the number said to mo
	   mo ATOI mov = mov -- ;makes the mo string a number, puts it in mov
	   0 stp = 9 ARRAY tttba = ;creates game array
	   {tttb 3 % tttba 8 stp - PUT ;converts board number to array information
	   3 tttb /= stp ++
	   }{9 stp == NOT} WHILE
	   tttba mov GET occ = ;assign the number of requested spot to occ
	   {
	    { 255 255 255 PENCOLOR 6 PENSIZE PENFRONT ;paint the X
	      bc mov 3 % 14 * + 2 + br mov 3 / 14 * + 2 + PENPOS ;on the board
	      6 0 LINETO 0 6 LINETO -6 0 LINETO 0 -6 LINETO 1 1 LINETO
	      255 0 0 PENCOLOR 2 PENSIZE
	      9 9 LINETO -1 -9 PENTO -9 9 LINETO
	      2 plt = opl pltn = ttt ++ ;change player name & # to other player
	      1 tttba mov PUT ;put the value for x in the array
	    }
	    { bc mov 3 % 14 * + 2 + br mov 3 / 14 * + 2 + PENPOS ;paint the O
	      255 255 255 PENCOLOR 6 PENSIZE PENFRONT ;on the board
	      6 0 LINETO 0 6 LINETO -6 0 LINETO 0 -6 LINETO 3 1 LINETO
	      0 0 255 PENCOLOR 2 PENSIZE
	      3 0 LINETO 2 2 LINETO 0 3 LINETO -2 2 LINETO -3 0 LINETO
	      -2 -2 LINETO 0 -3 LINETO 2 -2 LINETO
	      1 plt = xpl pltn = ttt ++ ;change name & number to other player
	      2 tttba mov PUT ;put value for o in the array
	    } plt 1 == IFELSE ;if the number is 1, it executes the x section
			;if not, it executes the o section
	    { ts =  ;this checks for a win- ts is current possibility
	      tttba ts 0 GET GET ITOA    ;look in those spaces on the board
	      tttba ts 1 GET GET ITOA +
	      tttba ts 2 GET GET ITOA +
	      wht =  ;assign the string values to wht
	      { 13 ttt = } wht "111" == IF ;three x's- x wins
	      { 14 ttt = } wht "222" == IF ;three o's- o wins
	    } [ [0 1 2 ] [3 4 5 ] [6 7 8 ] [0 3 6] [2 5 8]
		[1 4 7] [0 4 8] [6 4 2] ] FOREACH ;puts all possibilities on stack
	   }
	   {"Invalid Move, " pltn + bc br SAYAT ;if occ > 0 then it does this
	   } occ 0 == IFELSE ;if it is 0, the first section- move- is done
	   0 stp = 0 tttb = ;clear out board variable
	   {tttba stp GET tri = ;calculate array data into board variable
	    tttb 3 * tri + tttb =
	    stp++
	   }{9 stp == NOT} WHILE
	  } CHATSTR "^([123456789])$" GREPSTR IF ;if they say 1-9
	 } WHOCHAT WHONAME pltn == IF ;if the person talking is the one whose turn it is
	} ttt 2 > ttt 12 < * IF ;if the board variable is in the right position...
	;every time a move is made, it is increased by 1. It starts at 3, and if it is 12, it is a tie
	;13 or 14 are assigned in the check win section above, they are x or o wins.

;win/lose section of TTT:
	{[ "Yippee!" "All Right!" "I'm number 1!" "Yes!" ] win = ;four possible win sayings
	 [ "Boohoo." "-:sob:-" "rats!" "Not fair!" ] lose = ;four possible lose sayings
	 { "Cat wins. MEOW!" bc br SAYAT  ;board message
	   lose 4 RANDOM GET xpl WHOPOS SAYAT ;two loser messages
	   lose 4 RANDOM GET opl WHOPOS SAYAT ;for both x and o
	 } ttt 12 == IF ;if it is a tie- or cat- game....
	 { xpl " Wins!" + bc br SAYAT ;x wins board message
	   win 4 RANDOM GET xpl WHOPOS SAYAT ;winner x message
	   lose 4 RANDOM GET opl WHOPOS SAYAT ;loser o message
	 } ttt 13 == IF ;an x win
	 { opl " Wins!" + bc br SAYAT ;o wins board message
	   lose 4 RANDOM GET xpl WHOPOS SAYAT ;loser x message
	   win 4 RANDOM GET opl WHOPOS SAYAT ;winner o message
	 } ttt 14 == IF ;value for an o win
	 CLEARLOOSEPROPS ;clear off the board
	 PAINTCLEAR ;clear off the x's and o's
	 0 ttt = "" xpl = "" opl = ;reset game variable to 0, and player names to ""
	} ttt 11 > IF ;if it is greater than 11, the game is over one way or another
	
; To quit the game prematurely:
	
	{
	 CLEARLOOSEPROPS ;clear off board
	 PAINTCLEAR ;and x's and o's
	 0 ttt = "" xpl = "" opl = ;reset game state variables
	} CHATSTR "Quit TicTacToe" == IF