Hardware Reference
In-Depth Information
Listing 3-7 continued
for square in range(0, len(board) ) :
if testBoard[square] == ' ' and moveMade == False:
testBoard[square] = 'X'
if checkWin('X',testBoard):
board[square] = 'O'
moveMade = True
print 'My move is ',square + 1
else:
testBoard[square] = ' ' # retract move
return moveMade
Again, I am just showing the functions that have changed. his time the generateMove()
function is a little more structured. It irst calls the canIwin() function as part of an if
statement; when this returns true there is nothing else you want to do. However, Python will
throw an error if there is no line there, so you must use the dummy statement pass . As its
name implies pass does nothing but tells the computer speciically you want to do nothing
and that you haven't just made a mistake. However, if the function returns false - that is, it
cannot win - it then calls the canYouWin() function. Note here the elif keyword, a con-
catenation of else if , which means it is an if statement that controls whether the line
following it gets executed. In the event of none of these two functions producing a true
value, the inal else calls the randomMove() function, which contains the code you used
last time for generating a valid, but random, move.
he canIwin() function itself irst makes a copy of the board, and then visits every square
and puts the O symbol in it. After that, it checks for a win. If this returns as true, that move
is made to the real board, and the moveMade variable is set to true to stop it from making
any more moves. Finally, the move that has just been made is printed out. If the trial move
returns false, the move is retracted by placing a blank in the place where the O was just tried.
If you look now at the canYouWin() function, this is just the opposite; it scans the board,
placing an X in each blank square. If it inds that one of these trial moves will result in a win
for the human opponent, it uses this position to place its O, thus blocking the winning move.
If you examine the code you wrote for those two functions, you will see that they are nearly
identical. When you ind this happening it is good to shorten the code by consolidating the
two functions into one. You will see that the main diference is the symbol being used. When
this happens, as a general rule you make the symbol into a variable, enclose one of the func-
tions in a for loop and use the loop index to switch over the variable. his is shown in
Listing 3-8; give it a new, more descriptive name of win_block() .
Listing 3-8 Consolidating the Two Win Check Functions
def generateMove():
if win_block():
pass
 
Search WWH ::




Custom Search