In this tutorial, I want to discuss a step-by-step guide on How To Make Tic Tac Toe In Python, which you can learn with the help of source codes.
What is Tic Tac Toe In Python?
Tic Tac Toe Python is one of the most popular games, and you can play it anywhere with just a pen and paper to pass the time. Don’t worry if you don’t know how to play this game. Let’s figure it out first.
Only two people can play the game. First, we make a 33 grid on a piece of paper. The first player chooses “X” and draws it anywhere on the square grid.
The second player then gets to choose “O” and draw it anywhere on the square grid. So, the players switch between drawing an “X” and an “O” on the empty spaces until one of them draws three marks in a row, either horizontally, vertically, or diagonally.
If that happens, the player wins the game. If not, the game ends when all the spaces are taken.
How To Make Tic Tac Toe In Python With Source Code?
Here’s a step-by-step process on How To Make A Tic Tac Toe Game With Source Codes.
Step 1: Install Libraries
First, Install all the required libraries.
import pygame as pg,sys
from pygame.locals import *
import timeStep 2: Create A Form
Next, we will create a form to display.
import pygame as pg,sys
from pygame.locals import *
import time
#initialize global variables
width = 400
height = 400
white = (255, 255, 255)
line_color = (10,10,10)
#TicTacToe 3x3 board
TTT = [[None]*3,[None]*3,[None]*3]
#initializing pygame window
pg.init()
fps = 30
CLOCK = pg.time.Clock()
screen = pg.display.set_mode((width, height+100),0,32)
pg.display.set_caption("Tic Tac Toe By Python For Free")
# run the game loop forever
while(True):
pg.display.update()
CLOCK.tick(fps)
Step 3: Create Game Opening
Next, we will create a game-opening to display the image of our game.
import pygame as pg,sys
from pygame.locals import *
import time
#initialize global variables
width = 400
height = 400
white = (255, 255, 255)
line_color = (10,10,10)
#TicTacToe 3x3 board
TTT = [[None]*3,[None]*3,[None]*3]
#initializing pygame window
pg.init()
fps = 30
CLOCK = pg.time.Clock()
screen = pg.display.set_mode((width, height+100),0,32)
pg.display.set_caption("Tic Tac Toe By Python For Free")
#loading the images
opening = pg.image.load('display.png')
#resizing images
opening = pg.transform.scale(opening, (width, height+100))
def game_opening():
screen.blit(opening,(0,0))
pg.display.update()
time.sleep(1)
screen.fill(white)
game_opening()
Step 4: Draw Line
Next, we will draw a line before gameplay.
import pygame as pg,sys
from pygame.locals import *
import time
#initialize global variables
XO = 'x'
winner = None
draw = False
width = 400
height = 400
white = (255, 255, 255)
line_color = (10,10,10)
#TicTacToe 3x3 board
TTT = [[None]*3,[None]*3,[None]*3]
#initializing pygame window
pg.init()
fps = 30
CLOCK = pg.time.Clock()
screen = pg.display.set_mode((width, height+100),0,32)
pg.display.set_caption("Tic Tac Toe By Python For Free")
#loading the images
opening = pg.image.load('display.png')
x_img = pg.image.load('x.png')
o_img = pg.image.load('o.png')
#resizing images
x_img = pg.transform.scale(x_img, (80,80))
o_img = pg.transform.scale(o_img, (80,80))
opening = pg.transform.scale(opening, (width, height+100))
def game_opening():
screen.blit(opening,(0,0))
pg.display.update()
time.sleep(1)
screen.fill(white)
# Drawing vertical lines
pg.draw.line(screen,line_color,(width/3,0),(width/3, height),7)
pg.draw.line(screen,line_color,(width/3*2,0),(width/3*2, height),7)
# Drawing horizontal lines
pg.draw.line(screen,line_color,(0,height/3),(width, height/3),7)
pg.draw.line(screen,line_color,(0,height/3*2),(width, height/3*2),7)
game_opening()
# run the game loop forever
while(True):
for event in pg.event.get():
pg.display.update()
CLOCK.tick(fps)
Step 5: Add Functions
Now, we will add functions to every row and column that will display (X, O).
import pygame as pg,sys
from pygame.locals import *
import time
#initialize global variables
XO = 'x'
winner = None
draw = False
width = 400
height = 400
white = (255, 255, 255)
line_color = (10,10,10)
#TicTacToe 3x3 board
TTT = [[None]*3,[None]*3,[None]*3]
#initializing pygame window
pg.init()
fps = 30
CLOCK = pg.time.Clock()
screen = pg.display.set_mode((width, height+100),0,32)
pg.display.set_caption("Tic Tac Toe By Python For Free")
#loading the images
opening = pg.image.load('display.png')
x_img = pg.image.load('x.png')
o_img = pg.image.load('o.png')
#resizing images
x_img = pg.transform.scale(x_img, (80,80))
o_img = pg.transform.scale(o_img, (80,80))
opening = pg.transform.scale(opening, (width, height+100))
def game_opening():
screen.blit(opening,(0,0))
pg.display.update()
time.sleep(1)
screen.fill(white)
# Drawing vertical lines
pg.draw.line(screen,line_color,(width/3,0),(width/3, height),7)
pg.draw.line(screen,line_color,(width/3*2,0),(width/3*2, height),7)
# Drawing horizontal lines
pg.draw.line(screen,line_color,(0,height/3),(width, height/3),7)
pg.draw.line(screen,line_color,(0,height/3*2),(width, height/3*2),7)
def drawXO(row,col):
global TTT,XO
if row==1:
posx = 30
if row==2:
posx = width/3 + 30
if row==3:
posx = width/3*2 + 30
if col==1:
posy = 30
if col==2:
posy = height/3 + 30
if col==3:
posy = height/3*2 + 30
TTT[row-1][col-1] = XO
if(XO == 'x'):
screen.blit(x_img,(posy,posx))
XO= 'o'
else:
screen.blit(o_img,(posy,posx))
XO= 'x'
pg.display.update()
#print(posx,posy)
#print(TTT)
def userClick():
#get coordinates of mouse click
x,y = pg.mouse.get_pos()
#get column of mouse click (1-3)
if(x<width/3):
col = 1
elif (x<width/3*2):
col = 2
elif(x<width):
col = 3
else:
col = None
#get row of mouse click (1-3)
if(y<height/3):
row = 1
elif (y<height/3*2):
row = 2
elif(y<height):
row = 3
else:
row = None
#print(row,col)
if(row and col and TTT[row-1][col-1] is None):
global XO
#draw the x or o on screen
drawXO(row,col)
def reset_game():
global TTT, winner,XO, draw
time.sleep(3)
XO = 'x'
draw = False
game_opening()
winner=None
TTT = [[None]*3,[None]*3,[None]*3]
game_opening()
# run the game loop forever
while(True):
for event in pg.event.get():
if event.type == QUIT:
pg.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
# the user clicked; place an X or O
userClick()
pg.display.update()
CLOCK.tick(fps)
Step 6: Add Functions To Check Which Is The Winner
Lastly, we will add functions to check which of the two players got to win in the tic tac toe game.
import pygame as pg,sys
from pygame.locals import *
import time
#initialize global variables
XO = 'x'
winner = None
draw = False
width = 400
height = 400
white = (255, 255, 255)
line_color = (10,10,10)
#TicTacToe 3x3 board
TTT = [[None]*3,[None]*3,[None]*3]
#initializing pygame window
pg.init()
fps = 30
CLOCK = pg.time.Clock()
screen = pg.display.set_mode((width, height+100),0,32)
pg.display.set_caption("Tic Tac Toe By Python For Free")
#loading the images
opening = pg.image.load('display.png')
x_img = pg.image.load('x.png')
o_img = pg.image.load('o.png')
#resizing images
x_img = pg.transform.scale(x_img, (80,80))
o_img = pg.transform.scale(o_img, (80,80))
opening = pg.transform.scale(opening, (width, height+100))
def game_opening():
screen.blit(opening,(0,0))
pg.display.update()
time.sleep(1)
screen.fill(white)
# Drawing vertical lines
pg.draw.line(screen,line_color,(width/3,0),(width/3, height),7)
pg.draw.line(screen,line_color,(width/3*2,0),(width/3*2, height),7)
# Drawing horizontal lines
pg.draw.line(screen,line_color,(0,height/3),(width, height/3),7)
pg.draw.line(screen,line_color,(0,height/3*2),(width, height/3*2),7)
draw_status()
def draw_status():
global draw
if winner is None:
message = XO.upper() + "'s Turn"
else:
message = winner.upper() + " won!"
if draw:
message = 'Game Draw!'
font = pg.font.Font(None, 30)
text = font.render(message, 1, (255, 255, 255))
# copy the rendered message onto the board
screen.fill ((135, 206, 235), (0, 400, 500, 100))
text_rect = text.get_rect(center=(width/2, 500-50))
screen.blit(text, text_rect)
pg.display.update()
def check_win():
global TTT, winner,draw
# check for winning rows
for row in range (0,3):
if ((TTT [row][0] == TTT[row][1] == TTT[row][2]) and(TTT [row][0] is not None)):
# this row won
winner = TTT[row][0]
pg.draw.line(screen, (250,0,0), (0, (row + 1)*height/3 -height/6),\
(width, (row + 1)*height/3 - height/6 ), 4)
break
# check for winning columns
for col in range (0, 3):
if (TTT[0][col] == TTT[1][col] == TTT[2][col]) and (TTT[0][col] is not None):
# this column won
winner = TTT[0][col]
#draw winning line
pg.draw.line (screen, (250,0,0),((col + 1)* width/3 - width/6, 0),\
((col + 1)* width/3 - width/6, height), 4)
break
# check for diagonal winners
if (TTT[0][0] == TTT[1][1] == TTT[2][2]) and (TTT[0][0] is not None):
# game won diagonally left to right
winner = TTT[0][0]
pg.draw.line (screen, (250,70,70), (50, 50), (350, 350), 4)
if (TTT[0][2] == TTT[1][1] == TTT[2][0]) and (TTT[0][2] is not None):
# game won diagonally right to left
winner = TTT[0][2]
pg.draw.line (screen, (250,70,70), (350, 50), (50, 350), 4)
if(all([all(row) for row in TTT]) and winner is None ):
draw = True
draw_status()
def drawXO(row,col):
global TTT,XO
if row==1:
posx = 30
if row==2:
posx = width/3 + 30
if row==3:
posx = width/3*2 + 30
if col==1:
posy = 30
if col==2:
posy = height/3 + 30
if col==3:
posy = height/3*2 + 30
TTT[row-1][col-1] = XO
if(XO == 'x'):
screen.blit(x_img,(posy,posx))
XO= 'o'
else:
screen.blit(o_img,(posy,posx))
XO= 'x'
pg.display.update()
#print(posx,posy)
#print(TTT)
def userClick():
#get coordinates of mouse click
x,y = pg.mouse.get_pos()
#get column of mouse click (1-3)
if(x<width/3):
col = 1
elif (x<width/3*2):
col = 2
elif(x<width):
col = 3
else:
col = None
#get row of mouse click (1-3)
if(y<height/3):
row = 1
elif (y<height/3*2):
row = 2
elif(y<height):
row = 3
else:
row = None
#print(row,col)
if(row and col and TTT[row-1][col-1] is None):
global XO
#draw the x or o on screen
drawXO(row,col)
check_win()
def reset_game():
global TTT, winner,XO, draw
time.sleep(3)
XO = 'x'
draw = False
game_opening()
winner=None
TTT = [[None]*3,[None]*3,[None]*3]
game_opening()
# run the game loop forever
while(True):
for event in pg.event.get():
if event.type == QUIT:
pg.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
# the user clicked; place an X or O
userClick()
if(winner or draw):
reset_game()
pg.display.update()
CLOCK.tick(fps)
Download Full Source Code!
Visit this page to download the Full Source Code of the Tic Tac Toe Game Using Tkinter for Free!
Frequently Asked Questions
How do you play this Python Tic Tac Toe game?
Two players take turns placing X and O on a 3×3 grid. Click any empty cell to place your mark (the current player’s symbol toggles after each move). The first player to align 3 marks horizontally, vertically, or diagonally wins. If all 9 cells fill without a winner, the game is a draw. The simple AI version included uses the minimax algorithm so the computer never loses, useful for demonstrating game-tree search algorithms in your defense.
What Python version do I need to run this game?
Python 3.8 or newer works. We recommend Python 3.11 or 3.12 because Pygame ships pre-built wheels for those versions (faster pip install, no compilation errors). Python 3.13 may need a slightly older Pygame release because some wheels lag the latest CPython. Verify your version with python –version on Windows or python3 –version on Mac/Linux.
How do I install Pygame for this project?
Run pip install pygame in your terminal (Windows: open Command Prompt, Mac/Linux: open Terminal). On Windows, if pip is not recognized, try python -m pip install pygame instead. On Linux, you may need sudo apt install python3-pygame if pip fails. Verify with python -c “import pygame; print(pygame.version.ver)”.
Can I use this Python game as my BSIT capstone project?
On its own, no, most Philippine BSIT panels expect a full system with users, data, reports, and a real-world problem. A single Pygame game is too narrow for capstone scope. BUT, you can use this game as ONE module inside a larger capstone (e.g. a gamified learning system, a math practice tool for elementary students with this game as the reward layer, or an arcade-style POS for an internet cafe). Pair the game with a Django backend, a database, and analytics for a defensible capstone.
Can I package this game as a standalone .exe to distribute?
Yes, use PyInstaller. Run pip install pyinstaller then pyinstaller –onefile –windowed your_game.py from the project folder. PyInstaller bundles Python and Pygame into a single .exe (Windows) or .app (Mac) that runs without Python installed on the target machine. Include asset files (images, sounds) with –add-data “assets;assets”. Output goes to the dist/ folder.
Where do I get help if the game does not run?
Check the top 3 most common failures: (1) Pygame is not installed correctly, re-run pip install pygame. (2) The game cannot find an asset file (image/sound), make sure you run python from the project folder so relative paths resolve. (3) Wrong Python version, this code expects Python 3.8+; older Python 2.x or 3.6 raises syntax errors. If you still hit a wall, drop a comment on this article with the exact error message, our team monitors comments daily.
Conclusion
We have completely discussed a step-by-step guide on How To Make Tic Tac Toe In Python, which we learned with the help of source codes. I hope this Python Game Tutorial will help you a lot!
