Depth-First Search and Game Simulations

Depth-First Search and Game Simulations

Depth-first searches are often used in simulations of games (and game-like situations in the real world). In a typical game you can choose one of several possible actions. Each choice leads to further choices, each of which leads to further choices, and so on into an ever-expanding tree-shaped graph of possibilities. A choice point corre- sponds to a vertex, and the specific choice taken corresponds to an edge, which leads to another choice-point vertex.

Searches 635

Imagine a game of tic-tac-toe. If you go first, you can make one of nine possible moves. Your opponent can counter with one of eight possible moves, and so on. Each move leads to another group of choices by your opponent, which leads to another series of choices for you, until the last square is filled.

When you are deciding what move to make, one approach is to mentally imagine a move, then your opponent’s possible responses, then your responses, and so on. You can decide what to do by seeing which move leads to the best outcome. In simple games like tic-tac-toe the number of possible moves is sufficiently limited that it’s possible to follow each path to the end of the game. After you’ve analyzed the paths completely, you know which move to make first. This can be represented by a graph with one node representing your first move, which is connected to eight nodes representing your opponent’s possible responses, each of which is connected to seven nodes representing your responses, and so on. All these paths from the begin- ning node to an end node include nine nodes. For a complete analysis you’ll need to draw nine graphs, one for each starting move.

Even in this simple game the number of paths is surprisingly large. If we ignore simplifications from symmetry, there are 9*8*7*6*5*4*3*2*1 paths in the nine graphs. This is 9 factorial (9!) or 362,880. In a game like chess where the number of possible moves is much greater, even the most powerful computers (like IBM’s “Deep Blue”) cannot “see” to the end of the game. They can only follow a path to a certain depth and then evaluate the board to see if it appears more favorable than other choices.

The natural way to examine such situations in a computer program is to use a depth- first search. At each node you decide what move to make next, as is done in the getAdjUnvisitedVertex() method in the dfs.java program (Listing 13.1). If there are still unvisited nodes (choice points), you push the current one on the stack and go on to the next. If you find you can’t make a move ( getAdjUnvisitedVertex() returns –1) in a certain situation, you backtrack by popping a node off the stack (which corresponds to taking back a move) and see if the resulting position has any unex- plored choices.

You can think of the sequences of moves in a game as a tree, with nodes represent- ing moves. The first move is the root. In tic-tac-toe, after the first move there are eight possible second moves, each represented by a node connected to the root. After each of these eight second moves, there are seven possible third moves represented by nodes connected to the second-move nodes. You end up with a tree with 9! possi- ble paths from the root to the leaves. This is called the game tree.

Actually, the number of branches in the game tree is reduced because the game is often won before all the squares are filled. However, the tic-tac-toe game tree is still very large and complex, and this is a simple game compared with many others, such as chess.

636 CHAPTER 13 Graphs

Only some paths in a game tree lead to a successful conclusion. For example, some lead to a win by your opponent. When you reach such an ending, you must back up, or backtrack, to a previous node and try a different path. In this way you explore the tree until you find a path with a successful conclusion. Then you make the first move along this path.