Created
June 30, 2026 12:52
-
-
Save hectorcorrea/64a182c4d08f829f85664bea9003d63a to your computer and use it in GitHub Desktop.
Game of Tic Tac Toe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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