Skip to content

Instantly share code, notes, and snippets.

@hectorcorrea
Created June 30, 2026 12:52
Show Gist options
  • Select an option

  • Save hectorcorrea/64a182c4d08f829f85664bea9003d63a to your computer and use it in GitHub Desktop.

Select an option

Save hectorcorrea/64a182c4d08f829f85664bea9003d63a to your computer and use it in GitHub Desktop.
Game of Tic Tac Toe
# Version 4:
# draws the board
# allows a user to click on the cells
# only allows a cell to be used once
# detects when a user wins
# draws the winning line
# detects ties
from turtle import Turtle
def vertical_line(x, y):
t = Turtle()
t.speed('fastest')
t.hideturtle()
t.up()
t.goto(x, y)
t.color('blue')
t.down()
t.right(90)
t.forward(300)
def horizontal_line(x, y):
t = Turtle()
t.speed('fastest')
t.hideturtle()
t.up()
t.goto(x, y)
t.color('blue')
t.down()
t.forward(300)
def winning_line(x, y, type):
t = Turtle()
t.speed('slow')
t.width(10)
t.hideturtle()
t.up()
t.goto(x, y)
t.color('green')
t.down()
if type == "vertical":
t.right(90)
t.forward(225)
elif type == "horizontal":
t.forward(225)
elif type == "diagonal-a-i":
t.right(45)
t.forward(300)
elif type == "diagonal-c-g":
t.right(135)
t.forward(300)
else:
print(f"Type {type} is not valid")
def draw_x(x, y):
t = Turtle()
t.speed('fastest')
t.hideturtle()
t.color('red')
t.up()
t.goto(x-20, y+10)
t.down()
t.right(45)
t.forward(56)
t.up()
t.goto(x+20, y+10)
t.down()
t.right(90)
t.forward(56)
def draw_o(x, y):
t = Turtle()
t.speed('fastest')
t.hideturtle()
t.color('red')
t.up()
t.goto(x-10, y-20)
t.down()
t.circle(15)
def print_board():
vertical_line(-100, 200)
vertical_line(0, 200)
vertical_line(100, 200)
vertical_line(200, 200)
horizontal_line(-100, 200)
horizontal_line(-100, 100)
horizontal_line(-100, 0)
horizontal_line(-100, -100)
def cell_available(value):
if value == "":
return True
else:
return False
def player_wins(player):
# Horizontal win
if a == player and b == player and c == player:
winning_line(-50, 150, "horizontal")
return True
elif d == player and e == player and f == player:
winning_line(-50, 50, "horizontal")
return True
elif g == player and h == player and i == player:
winning_line(-50, -50, "horizontal")
return True
# Vertical win
if a == player and d == player and g == player:
winning_line(-50, 150, "vertical")
return True
elif b == player and e == player and h == player:
winning_line(50, 150, "vertical")
return True
elif c == player and f == player and i == player:
winning_line(150, 150, "vertical")
return True
# Diagonal win
if a == player and e == player and i == player:
winning_line(-50, 150, "diagonal-a-i")
return True
elif c == player and e == player and g == player:
winning_line(150, 150, "diagonal-c-g")
return True
# Player did not win
return False
def game_tied():
all_cells = a + b + c + d + e + f + g + h + i
# If all the cells have been played then it is a tie.
# This assumes we called player_wins() before and it
# returned false.
if len(all_cells) == 9:
t.color('green')
t.write("It's a tie", False, font=('Arial', 40, 'normal'))
return True
else:
return False
def handle_turn(click_x, click_y):
global turn
global a, b, c, d, e, f, g, h, i
global game_over
if game_over == True:
print("Game over!")
return
# Coordinates where we will draw the turn
x = None
y = None
valid_turn = False
cell_text = ""
# Clicked on first row?
if click_y >= 100 and click_y <= 200:
# A
if click_x >= -100 and click_x <= 0:
x = -50
y = 150
if cell_available(a):
a = turn
valid_turn = True
cell_text = "on cell A"
else:
cell_text = "cell A already taken"
# B
if click_x >= 0 and click_x <= 100:
x = 50
y = 150
if cell_available(b):
b = turn
valid_turn = True
cell_text = "on cell B"
else:
cell_text = "cell B already taken"
# C
if click_x >= 100 and click_x <= 200:
x = 150
y = 150
if cell_available(c):
c = turn
valid_turn = True
cell_text = "on cell C"
else:
cell_text = "cell C already taken"
# Clicked on second row?
if click_y >= 0 and click_y <= 100:
# D
if click_x >= -100 and click_x <= 0:
x = -50
y = 50
if cell_available(d):
d = turn
valid_turn = True
cell_text = "on cell D"
else:
cell_text = "cell D already taken"
# E
if click_x >= 0 and click_x <= 100:
x = 50
y = 50
if cell_available(e):
e = turn
valid_turn = True
cell_text = "on cell E"
else:
cell_text = "cell E already taken"
# F
if click_x >= 100 and click_x <= 200:
x = 150
y = 50
if cell_available(f):
f = turn
valid_turn = True
cell_text = "on cell F"
else:
cell_text = "cell F already taken"
# Clicked on third row?
if click_y <= 0 and click_y >= -100:
# G
if click_x >= -100 and click_x <= 0:
x = -50
y = -50
if cell_available(g):
g = turn
valid_turn = True
cell_text = "on cell G"
else:
cell_text = "cell G already taken"
# H
if click_x >= 0 and click_x <= 100:
x = 50
y = -50
if cell_available(h):
h = turn
valid_turn = True
cell_text = "on cell H"
else:
cell_text = "cell H already taken"
# I
if click_x >= 100 and click_x <= 200:
cell_text = "on cell I"
x = 150
y = -50
if cell_available(i):
i = turn
valid_turn = True
cell_text = "on cell I"
else:
cell_text = "cell I already taken"
# Draw the turn (x or o) and switch to the next turn
if valid_turn:
if turn == "x":
draw_x(x, y)
else:
draw_o(x, y)
if player_wins(turn):
print(f"Player {turn} wins the game!")
game_over = True
elif game_tied():
print(f"It's a tie")
game_over = True
else:
if turn == "x":
turn = "o"
else:
turn = "x"
# print the coordinates on the grid
# t.up()
# t.goto(x, y)
# t.down()
# t.write(f"x = {x}, y = {y} {cell_text}")
# print the coordinates on the terminal
print(f"click x = {click_x}, y = {click_y} {cell_text}")
# print(f"x = {x}, y = {y} {cell_text}")
# print(f" next player: {turn}")
a = ""
b = ""
c = ""
d = ""
e = ""
f = ""
g = ""
h = ""
i = ""
turn = "x"
game_over = False
t = Turtle()
t.hideturtle()
print_board()
t.screen.onscreenclick(handle_turn)
t.screen.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment