DEV Community

Cover image for Tic-tac-toe in Python
Ilya
Ilya

Posted on • Originally published at dev.to

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!

Top comments (0)