This post will demonstrate how to make Tic Tac Toe in Python. Hopefully this will help someone relatively new to Python see how to make a simple program. Note that Python 3.7 is used for this tutorial although most versions of Python 3 should work.
Chances are high you have heard of Tic Tac Toe but I will briefly explain the game just in case. The game is played on a 3x3 grid that starts out initially blank. Players then alternate placing their letter (X for player 1, O for player 2) inside a blank square of the grid. If one player gets 3 in a line either vertically, horizontally, or diagonally, they win the game. If the grid is filled and there are no 3-in-a-rows, then the game is a tie which is the result if both players play properly.
We will encode the rules of the game in Python with the program asking for the moves of each player and then displaying the current state of the board. To build the game, we will need:
- a way to display the current state of the game
- a way to update to grid with a move
- a way to check for the end of the game
- a way to verify if a move is valid
- prompts for players to make their moves
A sample run of the game
0 1 2
3 4 5
6 7 8
Player 1 [X], make your move: 4
0 1 2
3 X 5
6 7 8
Player 2 [O], make your move: 1
0 O 2
3 X 5
6 7 8
Player 1 [X], make your move: 3
0 O 2
X X 5
6 7 8
Player 2 [O], make your move: 5
0 O 2
X X O
6 7 8
Player 1 [X], make your move: 6
0 O 2
X X O
X 7 8
Player 2 [O], make your move: 0
O O 2
X X O
X 7 8
Player 1 [X], make your move: 2
O O X
X X O
X 7 8
Player 1 Wins
Good Game!
a way to display the current state of the game
Our program will be a console program since it will not have a GUI. Instead, it will collect moves in the console through the players typing input and it will display the board after each move. We can display the current state of the game by printing out the 3x3 grid row by row with spaces between each square. Player 1 will use 'X', Player 2 will use 'Y', and blanks will be represented as '-'. The board will start out initially with all squares as blank. For displaying purposes, blanks will show a number corresponding to what a player will type to place their letter in that square (0 to 8).
PLAYER_ONE_MOVE = "X"
PLAYER_TWO_MOVE = "O"
BLANK = "-"
BOARD_SIZE = 3
VALID_MOVES = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
board = [[BLANK, BLANK, BLANK], [BLANK, BLANK, BLANK], [BLANK, BLANK, BLANK]]
def print_board():
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
next_square = board[i][j]
if next_square == BLANK:
next_square = BOARD_SIZE * i + j
print(next_square, end = " ")
print("")
a way to update to grid with a move
A move is a number from 0 to 8 which corresponds to a specific square. If we think about it, move // BOARD_SIZE gives us the row number and move % BOARD_SIZE gives us the column number. Note that in Python, "//" is integer division where as "/" will give a floating point result. We will place an "X" or "O" depending on which player is making the move. We will always print the board after a move so that the next player can see the current state of the board.
def update_board(move, is_player_one):
row = move // BOARD_SIZE
column = move % BOARD_SIZE
if is_player_one:
board[row][column] = PLAYER_ONE_MOVE
else:
board[row][column] = PLAYER_TWO_MOVE
print_board()
a way to check for the end of the game
A game can end because the board becomes full or because one player gets 3-in-a-row. We will make one function for checking if the board is full and another to check for 3-in-a-rows. The board is full if all squares are not blank so we can just use nested for loops to check for this. Detecting 3-in-a-rows can be done by checking for 1 of 8 of the possible ways to get one (3 horizontal, 3 vertical, 2 diagonals). Note that "\" is used to have the boolean condition across multiple lines.
def board_full():
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
if board[i][j] == BLANK:
return False
return True
def is_win(letter):
if (board[0][0] == letter and board[0][1] == letter and board[0][2] == letter) \
or (board[1][0] == letter and board[1][1] == letter and board[1][2] == letter) \
or (board[2][0] == letter and board[2][1] == letter and board[2][2] == letter) \
or (board[0][0] == letter and board[1][0] == letter and board[2][0] == letter) \
or (board[0][1] == letter and board[1][1] == letter and board[2][1] == letter) \
or (board[0][2] == letter and board[1][2] == letter and board[2][2] == letter) \
or (board[0][0] == letter and board[1][1] == letter and board[2][2] == letter) \
or (board[0][2] == letter and board[1][1] == letter and board[2][0] == letter):
return True
return False
a way to verify if a move is valid
An attempted move is valid if it is a number from 0 to 8 (representing a square) and if that square is not already taken. We can first check if the move is in a predetermined list of valid moves and return False otherwise. If it is a valid move, we just need to make sure that square currently has a blank.
def valid_move(move):
if move not in VALID_MOVES:
return False
move = int(move)
row = move // BOARD_SIZE
column = move % BOARD_SIZE
return board[row][column] == BLANK
prompts for players to make their moves
Unlike languages such as Java, there is not a sense of a main method. if __name__ == '__main__' will evaluate to true if the source file is run as the main program. The game loop and player input will be placed in this if block.
One iteration of the game loop consists of two player moves. The game loop runs until the board is full or a win is detected early. Input for player moves is retrieved through input() and is re-prompted repeatedly if the move is not a valid one. The board is updated and printed after each move so that the next player can make an informed decision. The final result is printed to the console in the case of a player win or a tie.
if __name__ == '__main__':
print_board()
while not board_full():
# player 1
player_one_move = input("Player 1 [X], make your move: ")
while not valid_move(player_one_move):
player_one_move = input("Player 1 [X], please enter a proper move: ")
update_board(int(player_one_move), True)
if is_win(PLAYER_ONE_MOVE):
print("Player 1 Wins")
break
elif board_full():
print("Tie")
break
# player 2
player_two_move = input("Player 2 [O], make your move: ")
while not valid_move(player_two_move):
player_two_move = input("Player 2 [O], please enter a proper move: ")
update_board(int(player_two_move), False)
if is_win(PLAYER_TWO_MOVE):
print("Player 2 Wins")
break
print("Good Game!")
Challenge
Hopefully you got something out of this. You can test if you understand it by seeing if you can build Connect Four!
Top comments (2)
''''
import random
board = [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
game_letters = ['X', 'O']
# 0 | 1 | 2
#---+---+---
# 3 | 4 | 5
#---+---+---
# 6 | 7 | 8
''''''
drawing 3x3 board.
def draw_board(board):
print('---------')
print(board[0] , '|' , board[1] , '|' , board[2])
print('---------')
print(board[3] , '|' , board[4] , '|' , board[5])
print('---------')
print(board[6] , '|' , board[7] , '|' , board[8])
print('---------')
game introduction and choosing which player take what letter.
def main():
draw_board(board)
print("Welcome to TIC TAC TOE Game")
player_1 = print("Player 1 please enter your name: ")
player_1 = input()
player_2 = print("Player 2 please enter your name: ")
player_2 = input()
turn = input("Player " + str(player_1) + " would you like to
choose X or O?")
player_2_turn = player_turn(player_1)
if(turn != str("X") and turn != str("O")):
turn = input("Please enter X or O: ")
print(str(player_1) + " take " + (turn) + str(player_2) +
" take " + str(player_2_turn) )
switch players 2-->1, 1-->2
def player_turn(player_1):
if player_turn == "X":
return "O"
else:
return "X"
if name == 'main':
main()
good day, im trying to create the same tic tac toe project but after testing the code it didnt really work well , kindly could you assist in looking up my code.
thanks in advance.