12
Tic-tac-toe in Python
Today we are faced with the task of writing a game of tic-tac-toe on python. Recall that tic-tac-toe is a logical game for two players on a 3x3 square field.
To begin with, we will set the field. Our field will be a one-dimensional list with numbers from 1 to 9. To create it, we will use the range() function
board = range(1,10)
Now let's write a function that will output our field in the usual format
def draw_board(board):
print "-------------"
for i in range(3):
print "|", board[0+i*3], "|", board[1+i*3], "|", board[2+i*3], "|"
print "-------------"
It's time to allow users to enter data into our game. Writing the take_input function
ef take_input(player_token):
valid = False
while not valid:
player_answer = raw_input("Where do we put " + player_token+"? ")
try:
player_answer = int(player_answer)
except:
print "Incorrect input. Are you sure you entered a number?"
continue
if player_answer >= 1 and player_answer <= 9:
if (str(board[player_answer-1]) not in "XO"):
board[player_answer-1] = player_token
valid = True
else:
print "This cell is already occupied"
else:
print "Incorrect input. Enter a number from 1 to 9 to be like."
As you can see, the take_input function takes the player_token parameter - a cross or a toe, depending on whose turn it is now. We need to limit the user's choice to numbers from 1 to 9. To do this, we use the try/except and if/else constructs to make sure that the selected cell is not occupied. Note that the take_input function does not return any value, but only modifies the existing board list.
It remains to write a function for checking the playing field. Let's call this function check_win.
def check_win(board):
win_coord = ((0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6))
for each in win_coord:
if board[each[0]] == board[each[1]] == board[each[2]]:
return board[each[0]]
return False
Checking the results of the tic-tac-toe game is a fairly common programming task. As often happens, the same task in programming can be solved in several ways. In this case, we simply created a tuple with the winning coordinates and ran a for loop through it. If the symbols in all three specified cells are equal, we return the winning symbol, otherwise, we return the value False. At the same time, it is important to remember that not an empty string (our winning symbol) when converting it to a logical type, it will return True (we will need this in the future).
It remains to create the main function, in which we will put together all the described functions.
def main(board):
counter = 0
win = False
while not win:
draw_board(board)
if counter % 2 == 0:
take_input("X")
else:
take_input("O")
counter += 1
if counter > 4:
tmp = check_win(board)
if tmp:
print tmp, "won!"
win = True
break
if counter == 9:
print "drawn game!"
break
draw_board(board)def main(board):
counter = 0
win = False
while not win:
draw_board(board)
if counter % 2 == 0:
take_input("X")
else:
take_input("O")
counter += 1
if counter > 4:
tmp = check_win(board)
if tmp:
print tmp, "won!"
win = True
break
if counter == 9:
print "drawn game!"
break
draw_board(board)
The operation of the main function is extremely clear, except that lines 45 and 46 may cause misunderstanding. We are waiting for the counter variable to become greater than 4 to avoid a deliberately unnecessary call to the check_win function (no one can win for sure until the fifth movie). The tmp variable was created again in order not to call the check_in function once again, we just "remember" its value and, if necessary, use it on line 48. The benefits of this approach are not so noticeable when working with small amounts of data, but in general, such savings in processor time are good practice.
Now we can safely play by running the main(board)
Have a good game!
12