Tic Tac Toe

November 3, 2004
Jim Mahoney
based on LightsOn.nb by Rob Raguet-Schofield, Wolfram Research

Code part 1 : User Interface

Evaluating this code :
All this stuff is evaluated automatically when the file is opened; just click "yes" in the dialog box that pops up.  How does this work?  Read on.

All the cells in this "Code" section have been marked as "initialization" cells, and the notebook itself has been set to always evaluate those that can be evaluated when the file is opened.  All these properties, both for the cells and the notebook, can be seen and changed in the Option Inspector, which is under the Format menu.  

For example, select the Code block, then bring up the Option Inspector, then click the Cell Options tab, and within that the Evaluation Options tab.  Click the Initialization Cell option.  To see what that did, select one of the cells and choose Show Expression. What you'll see is that the InitializationCell->True property has been set.

So here it is

Don't complain if symbol names are similar.

Off[General::spell1];

This next command initializes the Tic Tac Toe game by defining the global variables :
  board is a 3 by 3 matrix of spaces, X's, and O's, and
  whoseMove is either "X" or "O",
  winner is "" if no one has won, or "X" or "O" if someone has
and then drawing the board.

init:=Module[{},board=Table[" ",{3},{3}];
      whoseMove="X";
      winner="";
      drawBoard;];

Create a clickable button for an empty row and column spot on the board.

makeButton[row_,column_]:=
    ButtonBox[
      RowBox[{" "}],
      ButtonFunction:>doClick[row,column],
      ButtonEvaluator->Automatic,
      Active->True,
      ButtonMargins->15,
      ButtonFrame->"None"
      ];

Create a 3x3 array of X's, O's, and (where the board is blank) buttons.

makeClickableBoard:=
    Table[
      If[board[[row,column]]==" ",
        (*then*) makeButton[row,column],
        (*else*) board[[row,column]]
        ],
      {row,1,3},{column,1,3}
      ];

Draw the Tic Tac Toe board in the cell whose tag is "TicTacToeBoard".

drawBoard:=Module[{},
      nb=SelectedNotebook[];
      NotebookFind[nb,"TicTacToeBoard",All,CellTags];
       NotebookWrite[nb,
        Cell[
          BoxData[
            GridBox[
              makeClickableBoard,
              RowLines->True,
              ColumnLines->True,
              ColumnWidths->1.5,
              RowMinHeight->1.5,
              ColumnsEqual->True
              ]
            ],
          FontFamily->"Sand",
          FontSize->32,
          CellTags->{"TicTacToeBoard"},
          Editable->False,
          Selectable->False,
          CellMargins->{{100,10},{10,10}}  
          (* {left,right},{bottom,top} in "printer's points" *)
          ]
        ];
      ];

What do do after a click : (a) mark the board, (b) change whose move it is, and (c) re-draw the board.

doClick[row_,column_]:=Module[{},
      board[[row,column]]=whoseMove;
      checkForWinner;
      If[whoseMove == "X",
        (*then*) whoseMove="O",
        (*else*) whoseMove = "X"
        ];
      drawBoard;
      ];

After all that is defined, initialize the game

init;

the Game

Click on the board to mark an X or O .
Click this button to start a new game :    Reset the game.

Questions to look at in class

Code part 2 : Computer Analysis

(*Put your program here ...  though to use this "\
Program" style,you'll have to use theOptions Inspectorto make the cell Evluatable.*)

\(checkForWinner := 
          Module[{}, 
winner = ""; 
winningLine\  = \ {whoseMove, whoseMove, 
                whoseMove}; 
Do[
If[\ 
                board[\([i, All]\)] == 
                  winningLine, 
 (*then*) \ 
                winner = whoseMove; \ Return[]\ ]; 
If[\ 
                board[\([All, i]\)] == 
                  winningLine, 
 (*then*) \ 
                winner = whoseMove; \ Return[]\ ]
, {i, 1, 
                3}
]; 
If[
              winner == whoseMove, \ 
              Return[]]; 
leftDiagonal\  = \ 
              Table[\ board[\([i, i]\)], {i, 1, 3}]; 
If[
              leftDiagonal == 
                winningLine, \ 
 (*then*) \ 
              winner = whoseMove; \ 
              Return[]]; 
rightDiagonal\  = \ 
              Table[\ board[\([i, 4 - i]\)], {i, 1, 
                  3}]; 
If[
              rightDiagonal == 
                winningLine, \ 
 (*then*) \ 
              winner = whoseMove; \ 
              Return[]];
];\)

checkForWinner;

whoseMove = "X"

board

winner

Table[ board[[i, 4 - i]], {i, 1, 3}]

Table[i, {i, 1, 3}]

Table[4 - i, {i, 1, 3}]

Scratch Space

board // MatrixForm

whoseMove

board

board // MatrixForm