Python project 19
Python Tic Tac Toe Game Project
Build a complete two-player Tic-Tac-Toe game for the terminal. The program displays numbered empty squares, rejects invalid or occupied moves, checks all eight winning lines, recognises a draw, and supports repeat games.
Learn Python with mentor-guided projectsView all project ideas
What you will build
Two local players alternate as X and O. Empty positions display numbers 1 through 9, making moves easy to enter, while the board stores empty strings and player marks internally.
Skills practised
- Lists and indexes
- Tuples of winning positions
- Turn-based loops
- Validation and return values
Requirements
- Python 3.10 or later
- A terminal or command prompt
- No external packages
- About 35 minutes to build
Full Python code
Save this code as tic_tac_toe.py, then follow the run instructions below.
"""A two-player command-line Tic-Tac-Toe game."""
from __future__ import annotations
WINNING_LINES = (
(0, 1, 2),
(3, 4, 5),
(6, 7, 8),
(0, 3, 6),
(1, 4, 7),
(2, 5, 8),
(0, 4, 8),
(2, 4, 6),
)
def display_board(board: list[str]) -> None:
cells = [value if value else str(index + 1) for index, value in enumerate(board)]
print(f"\n {cells[0]} | {cells[1]} | {cells[2]}")
print("---+---+---")
print(f" {cells[3]} | {cells[4]} | {cells[5]}")
print("---+---+---")
print(f" {cells[6]} | {cells[7]} | {cells[8]}\n")
def winner(board: list[str]) -> str | None:
for first, second, third in WINNING_LINES:
if board[first] and board[first] == board[second] == board[third]:
return board[first]
return None
def read_move(board: list[str], player: str) -> int:
while True:
value = input(f"Player {player}, choose an empty square [1-9]: ").strip()
if not value.isdigit() or not 1 <= int(value) <= 9:
print("Enter a number from 1 to 9.")
continue
index = int(value) - 1
if board[index]:
print("That square is already occupied.")
continue
return index
def play_game() -> str | None:
board = [""] * 9
player = "X"
for _ in range(9):
display_board(board)
board[read_move(board, player)] = player
if winner(board):
display_board(board)
print(f"Player {player} wins!")
return player
player = "O" if player == "X" else "X"
display_board(board)
print("The game is a draw.")
return None
def main() -> None:
print("Python Tic-Tac-Toe")
while True:
play_game()
if input("Play again? [y/N]: ").strip().lower() != "y":
break
if __name__ == "__main__":
main()
How the project works
display_board() substitutes a position number only when a board cell is empty. read_move() converts the chosen number to a zero-based list index and refuses occupied squares.
winner() checks three cells for each possible row, column, and diagonal. The game can finish immediately after a win; if nine accepted moves finish without a winner, the board is full and the result is a draw.
Run the project
- Run
python tic_tac_toe.py. - Player X chooses an empty position from 1 to 9.
- Player O chooses the next position.
- Continue until someone wins or the board is full.
Accuracy and safety notes
- Indexes: displayed positions 1-9 map to list indexes 0-8.
- State: one list stores the complete board.
- Separation: display, input, win checking, and game flow use different functions.
Ways to extend it
Add a computer opponent using minimax, match scores, player names, colour output, or a graphical board with Tkinter.
Continue learning Python
Build the next project, return to the Softenant project library, or explore the Python programming course in Vizag for structured lessons, mentor feedback, and portfolio practice.