12.4 Tic-Tac-Toe Revised

Although a player-versus-player version of tic-tac-toe is nice, chances are you will not have a friend who wants to spend time playing computerized tic-tac-toe with you for long. Perhaps it will be more satisfying if you create a version of tic-tac-toe that will play against you. This is what we will do in this section.

First, let’s understand the change we are trying to make. Instead of always having the player input the position on the board to fill, we want the computer to take one of the turns. Therefore, we will make a clearer distinction between the human’s move and the computer’s move. The code in Example 12-13 illustrates this change.

Example 12-13. Revised ask_player_for_move method
    1 def ask_player_for_move(current_player)
    2 	if current_player == COMPUTER_PLAYER
    3 		computer_move(current_player)
    4 	else
    5 		human_move(current_player)
    6 	end
    7 end

The purpose of the ask_player_for_move method is to switch between player input and computer AI (artificial intelligence) based on the current player. If the current player is the computer (line 2), let the computer take its move (line 3); otherwise (line 4), let the user take her or his move (line 5). Make sure to define the constant COMPUTER_PLAYER. It may be set equal to X or O. This would also be a good time to define the constant HUMAN_PLAYER. This should be set equal to O if COMPUTER_PLAYER is equal to X, or X if COMPUTER_PLAYER is equal to O.

If you have been reading carefully, you will have noticed that ask_player_for_move was already defined pages ago, and now we have changed its definition here. Previously, the method prompted either player one or player two for which turn she or he wanted to make, and then took the turn if it was valid. That code was relocated to the method human_move. The code for human_move is identical to our old ask_player_for_move method.

At this point, we have a mechanism for changing between the human’s and the computer’s turn, and we have slightly changed the definition of the human’s turn. From here it should be clear that the next logical step is to define the computer_move method, and it is defined in Example 12-14.

Example 12-14. computer_move method
     1 def computer_move(current_player)
     2 	row = -1
     3 	col = -1
     4 	found = "F"
     5 
     6 	check_rows(COMPUTER_PLAYER, found)
     7 	check_cols(COMPUTER_PLAYER, found)
     8 	check_diagonals(COMPUTER_PLAYER, found)
     9 
    10 	check_rows(HUMAN_PLAYER, found)
    11 	check_cols(HUMAN_PLAYER, found)
    12 	check_diagonals(HUMAN_PLAYER, found)
    13 
    14 	if found == "F"
    15 		if @board[1][1] == EMPTY_POS
    16 			row = 1
    17 			col = 1
    18 			@board[row][col] = current_player
    19 		elsif available_corner()
    20 			pick_corner(current_player)
    21 		else
    22 			until validate_position(row, col)
    23 				row = rand(@board.size)
    24 				col = rand(@board.size)
    25 			end
    26 			@board[row][col] = current_player
    27 		end
    28 	end
    29 end

If this method looks complicated, don’t worry. First, let’s walk through the code at an algorithmic level. The computer_move method does the following in order, picking the first rule it can successfully complete:

  1. Check the rows, columns, and diagonals to see if either the computer can win or the human can win. If such a spot exists, take it to either win the game or prevent the human from winning. Note that we intentionally do not include the code for those methods, as their implementation is straightforward and their details are unnecessary for the purposes of our discussion.

  2. If the middle cell is unoccupied, take the middle cell.

  3. If there is an available corner, take any of the available corner spots.

  4. If none of the prior conditions are true, pick a random cell.

    For simplicity, we did not include all the necessary code to guarantee at least a draw for the AI. However, in tic-tac-toe, correct play guarantees at least a draw. To guarantee at least a draw, the computer’s corner selection option should be modified as follows:

    If a corner spot is available, then select a corner spot, with the following corner selection preference. If the computer went first, randomly choose among the available corners that are not adjacent to the human’s noncenter spot(s). If the human went first, then check for one exception condition; otherwise, randomly choose among the available corners that are adjacent to the human’s noncenter spot(s). The exception condition is one in which only three squares are occupied, the computer has the center square, and the human has both corners on the same diagonal; in such a case, override the corner selection option and randomly choose a noncorner spot. If none of the aforementioned conditions are met, then choose any available corner.

This description defines a high-level algorithm for the game of tic-tac-toe. You now have all the needed skills to design, develop, and debug all the implementation specifics. Please do so and enjoy playing your computerized opponent.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.75.221