3
\$\begingroup\$

I recently made this tic-tac-toe program using tkinter, but I am quite new to tkinter, so I would be grateful for tips on how to improve the program. Note that the actual tic-tac-toe logic is being done by the python-tictactoe library.

This is my code:

import tkinter as tk
from tictactoe import Board
from tictactoe import X, O
root = tk.Tk()
root.geometry("400x400")
frame = tk.Frame(root, bg="white")
frame.pack()
board = Board()
def convert_to_str(player):
 return "X" if player == X else "O"
def push(i):
 pos = ((i + 1) % 3, i // 3)
 if board.is_empty(pos) and board.result() is None:
 squares[i].config(text=convert_to_str(board.turn))
 board.push(pos)
 # if there is a winner (use bool, because a draw is 0; so True only if board.result is 1 or 2)
 if bool(board.result()):
 for square in squares:
 if square.cget("text") == convert_to_str(board.result()):
 square.config(bg="green", fg="gold")
 # if it is a draw
 elif board.result() == 0:
 for square in squares:
 square.config(bg="yellow")
squares = [tk.Button(frame, text=" ", font=("Courier", 50), bg="white", command=lambda i=i: push(i)) for i in range(9)]
for i, square in enumerate(squares):
 square.grid(row=(i + 1) % 3, column=i // 3)
tk.mainloop()

This is what it looks like:

GUI:

An image of the tkinter window

Win:

An image of the tkinter window where X has won

Draw:

An image of the tkinter window where there is a draw

toolic
14.5k5 gold badges29 silver badges203 bronze badges
asked Sep 24, 2023 at 16:44
\$\endgroup\$
1
  • 1
    \$\begingroup\$ For a win wouldn't it be better if you only use the green background on the 3 squares that constituted the win? \$\endgroup\$ Commented Oct 10, 2023 at 11:41

1 Answer 1

1
\$\begingroup\$

Layout

Move the functions to top after the import lines. Having them in the middle of the code interrupts the natural flow of the code (from a human readability standpoint).

Imports

Since O is not used in the code, there is no need to import it. Change:

from tictactoe import Board
from tictactoe import X, O

to:

from tictactoe import Board, X

Documentation

Add a doctring at the top of the file to summarize the purpose of the code:

"""
tic-tac-toe game using tkinter.
The user plays against self.
"""

Instructions

Add instructions for the user in the GUI window. For example:

Tic-tac-toe game
For the 1st move, click in a square to add an X.
For the 2nd move, click in another square to add an O.
Etc.

Long line

Long lines of code like the following can be hard to read and maintain:

squares = [tk.Button(frame, text=" ", font=("Courier", 50), bg="white", command=lambda i=i: push(i)) for i in range(9)]

You could use the black program to automatically format the line:

squares = [
 tk.Button(
 frame, text=" ", font=("Courier", 50), bg="white", command=lambda i=i: push(i)
 )
 for i in range(9)
]

Naming

The following function name and variable are not very descriptive:

def push(i):

It looks like the function updates the board and checks the result. Perhaps a name like the following would be better:

def update_and_check_result(i):

Also, add a docstring to summarize the purpose if the function and to describe the input variable (expected range, etc.).

answered Oct 17, 2024 at 14:48
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.