Remembering the Moves and Possible Wins

In this lab, you will continue your Tic-Tac-Toe project to make the program analyze the game board to detect wins and ties.

On this page, you'll prepare by allowing the program to record the moves that are made, and teach it the winning groups of three squares.

When you first wrote Tic Tac Toe, it was easy to detect illegal moves (moving to a square that's already wearing an X or O costume) because each sprite could test for that without knowing about the rest of the game board. But to detect wins and ties, the program needs a way to test the state of the whole game board, not just one individual piece. So, you'll use a global variable, board, to keep track of whether the square in each position is empty or filled with an X or an O.

You learned about global variables on Unit 2 Lab 1 Page 4: Keeping Score with Global Variables.

picture of: watcher of board variable showing {O, O, X, 4, X, 6, X, 8, 9}; and Tic Tac Toe game with X, X, O in top row; empty, X, empty in middle row; and X, empty, empty in bottom row

  1. Open your U3L1-TicTacToe project, and save it as U3L3-TicTacToe so you'll still have your old version when you edit the new one.
  2. Make a global variable called board that, at the beginning of the game, contains a list with the numbers from 1 to 9.

Each sprite needs to know its own position on the board so that you can use the item of block to replace that position with an X or an O. So, you'll create a sprite variable, position number, and each clone will have its own version of this variable.

: Sprite Variable

A sprite variable is like a global variable in that it doesn't belong to a particular script, but it does belong to a particular sprite.

  1. Create a sprite variable position number.

    You make a sprite variable similarly to how you make global variables:

    • Click make a variable button in the Variables palette.
    • Then, as you are typing the variable's name, select "for this sprite only" to make it a sprite variable.

    variable name dialog box with 'for this sprite only' selected
  2. As you create the clones, set each one's position number to the appropriate value (1-9).
    In the loop that makes the clones, increase the parent sprite's variable by one for each new clone so that each clone will have a unique value.
    Make sure that the parent's position number doesn't end up being a number 1-9 so that it doesn't conflict with a clone.
  3. When a square is clicked, replace that square's entry in the board list with X or O as appropriate.
  4. Watch the values stored in the board variable as you play a game of Tic Tac Toe. Make sure that it updates as you expect it to, and fix any bugs.

Storing All the Ways to Win

To program a way to detect a win, you need to determine what counts as a win. You'll store each possible winning triple as a list of three position numbers (a triple). For example, this winning triple could be represented as list{3, 5, 7} because the win is in the 3rd, 5th, and 7th positions:
diagonal win bottom left to top right

  1. Talk with Your Partner
    1. How many winning triples are possible?
    2. Write down each of the possible winning triples.

You could check for each possible win separately:
is there a win? (Comment: Don't build this!! Just read it.) : if (is there a win at (1) (2) (3) ?) report (true); if (is there a win at (4) (5) (6) ?) report (true); ...; if (is there a win at (3) (5) (7) ?) report (true); report (false)

But that's way too much code, especially because you'll have to do something very similar again, later on, when the computer actually plays against you. Instead, you'll create a list to store all of the possible winning triples so you can check it against the current state of the game stored by board.

    Save Your Work
  1. Create a reporter that outputs a list of all possible winning triples. It will look something like this:
    winning triples partial block definition showing a list with at least two lists inside it: {1,2,3} and {2,5,8}
  2. Save. You will use this later.