**ECS 170- Introduction to Artificial Intelligence;
Homework Assignment #2 - Solutions**

Winter 2003

Rao Vemuri

(70
points) – A third problem, discussed in the class, has been added at the end

Assigned: 21 January 2003

Due: 28 January 2003

(1) (25 points, 5 pts for each part) Consider the game of Tic-tac-toe. The game involves playing on a board with 9 squares arranged in a 3 x 3 grid. Two players take turns; one player puts a token (a cross) and the other puts another token (a circle) in one of the available empty squares of the game board. The play continues until one of the players gets all three of his/her tokens in a row, column or along a diagonal.

(a) Make an estimate of the number of states of this game. Do not just give a number. Show how you got it.

At the first level the branching factor = 9. Next level it is 8, and so on. So, one way of looking at this problem is to say that there are 9! states.

(b) Show the whole game tree starting from an empty board down to a depth 2 (i.e., one X and one O on the board, taking symmetry into account (you should have 3 positions at level 1 and 12 at level 2)

Let us define the canonical positions as 1, 2, 3, 4, 5, 6, 7, 8, 9 going from the top left square to the bottom right square as a raster.

At the first level, there are is a state with an x in one corner (square 1) one state with an x in the middle (square 5), and a state with an x in the middle of a side (square 2). All others are symmetrical.

At the second level, there are 5 children to the node with an x in the corner,

These children get a “o” in positions 2, 3, 5, 6, 9.

five children to the node with an x in the middle of the side and

These children get a “o” in positions 3, 4, 5, 7, 8.

only two children for the node with a x in the center.

These children get a “o” in positions 1, 2.

© Now it is an easy matter to calculate the evaluation function for these using the given formula.

(d) Mark on your tree the backed-up values for the positions at levels 1 and 0, using the minimax algorithm and then use them to choose the best move.

(e) Circle the nodes that at level 2
that would **not** be evaluated if alpha-beta pruning were applied, assuming
that the nodes are generated in the optimal order for alpha-beta pruning.

(2) (25 points, 8/8/9 points for the parts) Let us continue with the tic-tac-toe problem. Now we are interested in looking at the programming aspects of this problem. One of the first issues we have to tackle is the representation issue. Toward this goal let us make a few attempts.

(a) First attempt: **TTT1:** Let us define a
data structure as shown below.

**Data structures: **

- 1) A nine element vector (array) representing the board

· | 1 | 2 | 3 |

· | 4 | 5 | 6 |

· | 7 | 8 | 9 |

Each element contains the values

- 0 === square has blank
- 1 === square has X
- 2 === square has O
- 2) A movetable: A vector of 3^9 elements (19,683). Each element of which is a nine-element vector.

**Algorithm: **

- 1) Use the current board state specified by the ternary nine-digit number and convert to Decimal
- 2) Use the number from above as an index into the movetable and access the vector stored there.
- 3) The vector in step 2 represents the "correct" move. It specifies what the board will look after the move. Set the board equal to the vector

**Comments:**

Advantages:

- 1) efficient in time
- 2) optimal in theory

Disadvantages:

- 1) lots of space (too
much?)
- 2) Someone has to
specify all the 3^9 entries (19683 entries)
- 3) errors in
specifying all 3^9 entries easy to make
- 4)
Extensibility? (3 dim 3^{27} movetable entries, 4x4....)

(b) Second attempt: **TTT2:**
Let us define a data structure as shown below.

**Data Structures:**

- 1) Board: A nine element vector representing the board

· value 2 === blank

· value 3 === X

· value 5 === O

· why?...

- 2) Turn: An integer indicating which move

· turn = 1 first move

· turn = 9 last move

` `

**Algorithm: **

Three procedures.

- 1) make2: tries to make two in a row. It first tries to play in the center then tries noncorner squares.
- 2) Posswin(p):

· if player p cannot win in the next move

· Return 0

· else

· Returns the number of square that

· constitutes a winning move

` `

We first call posswin(us), if we can win
we make the winning move. If we cannot win we call posswin(opponent) and block
opponents move if he/she can win.

posswin checks each row, column, and diagonal

- If (product == 18) X can win ((3 * 3 * 2) = 18)
- If (product == 50) O can win ((5 * 5 * 2) = 50)

That is, Scan row/column/diag to find blank space to move to.

- 3) Go(n): Move to square n

**X starts!! **

Algorithm in more detail:

- 1) turn = 1 go(1) /*upper left corner*/
- 2) turn = 2

· if(board[5] is blank)

· go(5)

· else

· go(1)

- 3) turn = 3

· if(board[9] is blank)

· go(9)

· else

· go(3)

` `

- 4) turn = 4

· if(posswin(X) != 0 )

· go(posswin(X)) /*block opponent*/

· else

· go(make2)

` `

- 5) turn = 5 etc.....

**Comments: **

Disadvantages:

- 1) Not as efficient in
time
- 2) Total strategy has
been figures out in advance by programmer. Bugs in strategy?
- 3) Cannot generalize
to 3-D or other games

Advantages:

- 1) Efficient in space
- 2) Time isn't so bad
- 3) Easy to understand
strategy or to change it.

(c)
Third attempt: **TTT3:** Suggest an alternative formulation
and an alternate algorithm (just state the algorithm in a few steps, each step
in informal English) and its advantages and disadvantages.

Solution

**Data Structures: **

- 1) Board position:
**A STRUCTURE**containing - - a nine element
vector representing the board
- - A list of board
positions that could result from the next move.
- - a number
representing/estimating the likelihood of winning for each move

**Algorithm: **

- 0) create a list of
subsequent board positions
- 1) Look at list of
subsequent board positions
- 2) decide which one is
best, make the move and pass return this best moves numerical rating

**Deciding
which move is best: **

For
each move

- 1) See if it is a win,
if yes give it highest rating
- 2) If not a win:
- Consider all moves
opponent could make next
- See which of them is
worst for us (recursive call)
- Assume the opponent
will make this move (What is worst for us is best for opponent)
- return this rating
- 3) the best move is the
one with highest rating

(3) (20 points, you will lose one point for each error) In the class, I drew a tree on the board and demonstrated how to do the alpha-beta pruning. Complete that procedure for the rest of the tree and show the best move sequence for the maximizing player.