Tic-Tac-Toe in Python
Tic-Tac-Toe is one of those simplest two-player games. It appears at times as one of the most introductory projects to a programming language. In this explanation, I will break the entire process of building a Tic-Tac-Toe game in Python from scratch.
Understanding the Game
Tic-Tac-Toe is played on a 3×3 grid. Two players take turns placing their marks:
- Player 1:
X - Player 2:
O
The game ends when:
- A player gets three of their marks in a row (horizontally, vertically, or diagonally).
- The board is full (resulting in a draw).
Steps to Build Tic-Tac-Toe in Python
We will break the project into these steps:
- Display the board
- Take player input
- Check for a win or a draw
- Switch turns between players
- Repeat until the game ends
Step 1: Creating the Board
We need a data structure to store the game board. A list of lists is a good choice, where:
- Each row is a list.
- Each column contains either
'X','O', or a blank space' '.
def create_board():
return [[' ' for _ in range(3)] for _ in range(3)]
Explanation
- This function creates a 3×3 grid filled with spaces (
' '). - The
forloops generate a 3-row list with 3 empty spaces in each row.
Initial Board Output
[[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']]
Step 2: Displaying the Board
We need a function to print the board in a readable format.
Explanation
- This function loops through each row and prints the values separated by
|to mimic a real Tic-Tac-Toe grid. - It prints
-----between rows to create horizontal lines.
Example Output
| |
-----
| |
-----
| |
Step 3: Taking Player Input
Players should enter a row (0-2) and column (0-2) to place their mark.
def get_player_input(board, player):
while True:
try:
row = int(input(f"Player {player}, enter row (0-2): "))
col = int(input(f"Player {player}, enter column (0-2): "))
if row in range(3) and col in range(3) and board[row][col] == ' ':
board[row][col] = player
break
else:
print("Invalid move. Try again.")
except ValueError:
print("Please enter numbers between 0 and 2.")
Explanation
- The function solicits row and column numbers.
- It will check if the cell is blank before placing the mark.
- If input is invalid, it asks again.
- This loop prevents crashes when the user inputs non-numeric values.
Example Interaction
Player X, enter row (0-2): 1
Player X, enter column (0-2): 1
Board After Input
| |
-----
|X|
-----
| |
Step 4: Checking for a Win
We need to check if a player has won.
def check_winner(board, player):
# Check rows
for row in board:
if all(cell == player for cell in row):
return True
# Check columns
for col in range(3):
if all(board[row][col] == player for row in range(3)):
return True
# Check diagonals
if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)):
return True
return False
Explanation
- Checks rows (
X X XorO O O). - Checks columns (
XorOin all three rows in the same column). - Checks diagonals (
XorOfrom top-left to bottom-right OR top-right to bottom-left).
Example Winning Board
Win by Row:
X|X|X
-----
O| |
-----
O| |
Win by Column:
X|O|
-----
X|O|
-----
X| |
Win by Diagonal:
X|O|
-----
O|X|
-----
O| |X
Step 5: Checking for a Draw
If the board is full and no player has won, the game is a draw.
def check_draw(board):
return all(cell != ' ' for row in board for cell in row)
Explanation
- The function checks if all cells are filled.
- If there are no empty spaces left and no winner, it’s a draw.
Example Draw Board
X|O|X
-----
O|X|O
-----
O|X|O
Step 6: Switching Players
After every turn, we switch between ‘X’ and ‘O’.
def switch_player(player):
return 'O' if player == 'X' else 'X'
Example Switches
Player X → Player O
Player O → Player X
Step 7: Running the Game
We now combine all functions into one game loop.
def play_tic_tac_toe():
board = create_board()
player = 'X'
while True:
display_board(board)
get_player_input(board, player)
if check_winner(board, player):
display_board(board)
print(f"Player {player} wins!")
break
elif check_draw(board):
display_board(board)
print("It's a draw!")
break
player = switch_player(player)
play_tic_tac_toe()
- The game runs in a loop.
- It displays the board, takes input, and checks for a winner or draw.
- If the game is not over, it switches players and repeats.
Final Working Code
Here is the complete Python program:
def create_board():
return [[' ' for _ in range(3)] for _ in range(3)]
def display_board(board):
for row in board:
print('|'.join(row))
print('-' * 5)
def get_player_input(board, player):
while True:
try:
row = int(input(f"Player {player}, enter row (0-2): "))
col = int(input(f"Player {player}, enter column (0-2): "))
if row in range(3) and col in range(3) and board[row][col] == ' ':
board[row][col] = player
break
else:
print("Invalid move. Try again.")
except ValueError:
print("Please enter numbers between 0 and 2.")
def check_winner(board, player):
for row in board:
if all(cell == player for cell in row):
return True
for col in range(3):
if all(board[row][col] == player for row in range(3)):
return True
if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)):
return True
return False
def check_draw(board):
return all(cell != ' ' for row in board for cell in row)
def switch_player(player):
return 'O' if player == 'X' else 'X'
def play_tic_tac_toe():
board = create_board()
player = 'X'
while True:
display_board(board)
get_player_input(board, player)
if check_winner(board, player):
display_board(board)
print(f"Player {player} wins!")
break
elif check_draw(board):
display_board(board)
print("It's a draw!")
break
player = switch_player(player)
play_tic_tac_toe()
How to Play
- Run the script in Python.
- Players take turns entering row and column numbers (0, 1, or 2).
- The game ends when a player wins or the board is full (draw).
Summary
- We built a 3×3 board as lists.
- We also wrote functions to print the board, take input, check for wins, check for draws, and switch player.
- It runs in a loop until somebody wins or it results in a draw.