Community post
Tic Tac Toe Game in Python
What's up HIVE Community, ππ For quite some time now I have been procrastinating getting started with sharing some different beginner programming projects.
I decided to start with sharing this small Python Project I was working on yesterday. It is pretty straightforward, probably some of you have tried the implementing the game out in different programming languages.
I will provide the image files at the end of the post for anyone interested in aggregating the different code blocks and giving the game a try.
I am currently working on my Python skills, will be sharing more projects in the community for anyone also learning Python.

Tic-Tac-Toe | Python
Steps To Build a Python Tic Tac Toe Game
- Create the display window for the game.
- Draw the grid on the canvas where to play the Tic Tac Toe Game.
- Draw a status bar below the canvas to show which player's turn it is and who wins the game.
- Reset the game when a person wins or both players draw.
1. Initializing the Game Components
- Start by importing the
pygameandtimelibrary.
import pygame as pg,sys
from pygame.locals import *
import time
- The
timelibrary provides us with thetime.sleep()method to pause the game. - Also initialize all the
Global Variablesto be used in the reset of the code.
#initialize the 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]
- TTT is the main 3Γ3 Tic Tac Toe board. The height and width of the canvas where to play the game are 400Γ400.
2. Intializing the Display Window
- Use
pygameto initialize a new window on where to play the game.
pg.init()
fps = 30
CLOCK = pg.time.Clock()
- The
pg.display.set_mode()initializes the display, reference it with the
screen variable. This screen variable will be used to draw something on the display.
screen = pg.display.set_mode((width, height+100),0,32)
- The
pg.display.set_caption()method is used to set a name that will appear at
the top of the display window.
pg.display.set_caption("Tic Tac Toe")
3. Loading and Transforming images
The game requires 3 Images:
- Opening Image which loads when the game start or resets.
- X Image which will draw Xwhen mouse clicks on the game grid.
- O Image which will draw O when mouse clicks on the game grid.
#Loading the Images
opening = pg.image.load('opening.png')
x_img = pg.image.load('x.png')
o_img = pg.image.load('o.png')
The images have to be resized to fit in the display window previously initialized.
#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))
4. Defining The Necessary Functions
game_opening() Function that Starts and Restarts the game
-
pygameprovides the functionblit()which allows drawing an image on top of another image. -
Draw the opening image, after which the display has to be always updated using
pg.display.update() -
Using
time.sleep(1)wait for 1 second and fill the screen with white color -
To make the 3x3 grid, draw 2 horizonatal and vertical lines on the white background.
# Function that starts and restarts the game
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()
draw_status() Function
- The function draws a black rectangle where the update status updates, showing which playerβs turn is it and whether the game ends or draws.
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 ((0, 0, 0), (0, 400, 500, 100))
text_rect = text.get_rect(center=(width/2, 500-50))
screen.blit(text, text_rect)
pg.display.update()
check_win() Function
- The function checks the Tic Tac Toe board to see all the marks of
βXβ and βOβ. - It calculates whether a player has won the game or not. They can
either win when the player has marked 3 consecutive marks in a row, column
or diagonally. - This function is called every time when a mark βXβ or
βOβ is drawn on the board.
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()
drawXO(row, col) Function
- The function takes the row and column where the mouse is
clicked and then it draws the βXβ or βOβ mark. - Calculate the x and y coordinates of the starting point from where to draw the png image of the mark.
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()
userClick() Function
- The function is triggered every time the user presses the mouse button.
- When the user clicks the mouse, first take the x and y coordinates of where the mouse is clicked on the display window and then if that place is not occupied draw the βXOβ on the canvas.
- Check if the player wins or not after drawing βXOβ on the board.
def userClick():
# Get coordinates of mouse click
x,y = pg.mouse.get_pos()
# Get column of mouse click
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
if (y < height/3):
row = 1
elif (y < height / 3 * 2):
row = 2
elif (y < height):
row = 3
else:
row = None
# Print row and 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()
reset_game() Function
The function restarts the game and also
resets all the variables to the beginning of the game.
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()
5. The last part: Loop the game infinitely
-
To start the game, invoke
game_opening()function. -
Then, run an infinite loop and continuously check for any event made by the user.
- If the user presses mouse button, the
MOUSEBUTTONDOWNevent will be captured and then trigger theuserClick()function. - If the user wins or the game draws, reset the game by invoking
reset_game()function.
- If the user presses mouse button, the
-
In each iteration the display is updated, having set the frames per second to 30.
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)
π₯³π₯³ The game is complete and ready to play.
The expected output on running the code. π


As promised here are the image files necessary for successful running of the game. ππ



Inspiration and Image files from [Tech Vidvan](https://techvidvan.com/tutorials/python-game-project-tic-tac-toe/)
See you in my next update! Cheers βοΈ
Replies (5)
Thanks for sharing this in the programming community. I havenβt used pygame much but may eventually get round to jumping back in!
It is pretty fun to play around with, you should definitely give it a try.
Looks Interesting, will try to implement the code myself. Good Jobπ
Thank you. It is definitely worth trying!
I am sure it is, as soon as my heart wants some programming I am definitely going to build that.