Editor

Python Program for Tic Tac Toe

Intermediate · Games and random numbers

Tic tac toe is played on a 3 x 3 grid: two players, X and O, take turns marking a square, and the first to get three in a row, column or diagonal wins. If all nine squares fill up with no winner, the game is a draw. This program plays a whole game from a list of moves and prints the board after every turn.

Program

tic_tac_toe.py
WIN_LINES = [(0, 1, 2), (3, 4, 5), (6, 7, 8), # rows
(0, 3, 6), (1, 4, 7), (2, 5, 8), # columns
(0, 4, 8), (2, 4, 6)] # diagonals
def show(board):
for r in (0, 3, 6):
print(f" {board[r]} | {board[r + 1]} | {board[r + 2]}")
if r < 6:
print("---+---+---")
def has_won(board, p):
for a, b, c in WIN_LINES:
if board[a] == board[b] == board[c] == p:
return True
return False
board = [" "] * 9 # squares 0 to 8, left to right, top to bottom
player = "X"
# The squares picked in turn (4 is picked twice, to show a taken square).
# To play for real: move = int(input(f"{player}, pick a square 0-8: "))
moves = [4, 0, 2, 4, 6, 3, 8, 5]
for move in moves:
if board[move] != " ":
print(f"Square {move} is taken, {player} must pick again")
continue
board[move] = player
print(f"{player} takes square {move}:")
show(board)
if has_won(board, player):
print(player, "wins!")
break
if " " not in board:
print("It's a draw!")
break
player = "O" if player == "X" else "X"
print()
Output
X takes square 4:
   |   |  
---+---+---
   | X |  
---+---+---
   |   |  

O takes square 0:
 O |   |  
---+---+---
   | X |  
---+---+---
   |   |  

X takes square 2:
 O |   | X
---+---+---
   | X |  
---+---+---
   |   |  

Square 4 is taken, O must pick again
O takes square 6:
 O |   | X
---+---+---
   | X |  
---+---+---
 O |   |  

X takes square 3:
 O |   | X
---+---+---
 X | X |  
---+---+---
 O |   |  

O takes square 8:
 O |   | X
---+---+---
 X | X |  
---+---+---
 O |   | O

X takes square 5:
 O |   | X
---+---+---
 X | X | X
---+---+---
 O |   | O
X wins!

How it works

  1. The board is a list of 9 strings, one per square, numbered 0 to 8 from the top left, and " " marks an empty square.
  2. WIN_LINES lists the 8 ways to win, 3 rows, 3 columns and 2 diagonals, and has_won() checks whether one player holds all three squares of any of them.
  3. Each move is checked first: square 4 is picked a second time, so the program refuses it and the same player picks again.
  4. After every move the board is printed, and the game stops when a player wins or when no empty square is left, which is a draw.
  5. player = "O" if player == "X" else "X" swaps turns, and the moves list stands in for the input() line in the comment.

Another way to write it

Two computer players picking at random

Two computer players picking at random
import random
WIN_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)]
board = [" "] * 9
player = "X"
result = "It's a draw!"
while " " in board:
free = [i for i in range(9) if board[i] == " "]
board[random.choice(free)] = player
if any(board[a] == board[b] == board[c] == player for a, b, c in WIN_LINES):
result = player + " wins!"
break
player = "O" if player == "X" else "X"
for r in (0, 3, 6):
print(" " + " | ".join(board[r:r + 3]))
print(result)
Output
 X | X | O
 X | X | O
 O | O | X
X wins!

Both players pick a random empty square until someone wins or the board fills, so the game and its result change on every run. any() checks all eight winning lines in one expression.

Try it yourself

Change the moves to [0, 4, 8, 2, 6, 3, 5, 7, 1] and check that the game ends in a draw.

Edit the program above and press Run, or open it in the full editor to save it and share it. To watch it run line by line, open it in the visualizer.

All Python programs · CBSE class 12 practical file · Python exercises