Tic-Tac-Toe GUI in Python Using Tkinter

Tic-Tac-Toe GUI in Python Using Tkinter

Hey folks, This tutorial will help you play and create Tic-Tac-Toe, a very renowned game we have all got our hands on since our childhood. To do this task, we will use some in-built libraries of Python namely which are Tkinter and Random.

Using:

from tkinter import *
from tkinter import messagebox
import random as r

 

Tic-Tac-Toe GUI in Python using Tkinter

We’ll kick off with learning the functions used in this project:

1)The Button function:

def button(frame):          #Function to define a button
    b=Button(frame,padx=1,bg="papaya whip",width=3,text="   ",font=('arial',60,'bold'),relief="sunken",bd=10)
    return b

The above function makes it possible to define a custom button with custom properties.

2) The Change function:

def change_a():             #Function to change the operand for the next player
    global a
    for i in ['O','X']:
        if not(i==a):
            a=i
            break

The change function switches the ‘O’ to ‘X’ and vice-versa for the other player to play his chance.

3)The Reset function:

def reset():                #Resets the game
    global a
    for i in range(3):
        for j in range(3):
                b[i][j]["text"]=" "
                b[i][j]["state"]=NORMAL

The reset function resets the state of all buttons to Normal and clears the text on them.

4)The Check function:

def check():                #Checks for victory or Draw
    for i in range(3):
            if(b[i][0]["text"]==b[i][1]["text"]==b[i][2]["text"]==a or b[0][i]["text"]==b[1][i]["text"]==b[2][i]["text"]==a):
                    messagebox.showinfo("Congrats!!","'"+a+"' has won")
                    reset()
    if(b[0][0]["text"]==b[1][1]["text"]==b[2][2]["text"]==a or b[0][2]["text"]==b[1][1]["text"]==b[2][0]["text"]==a):
        messagebox.showinfo("Congrats!!","'"+a+"' has won")
        reset()   
    elif(b[0][0]["state"]==b[0][1]["state"]==b[0][2]["state"]==b[1][0]["state"]==b[1][1]["state"]==b[1][2]["state"]==b[2][0]["state"]==b[2][1]["state"]==b[2][2]["state"]==DISABLED):
        messagebox.showinfo("Tied!!","The match ended in a draw")
        reset()

The check function checks the board row-wise,column-wise and diagonal-wise for equality and displays the result of the game.

5)The Click function:

def click(row,col):
        b[row][col].config(text=a,state=DISABLED,disabledforeground=colour[a])
        check()
        change_a()
        label.config(text=a+"'s Chance")def click(row,col):
        b[row][col].config(text=a,state=DISABLED,disabledforeground=colour[a])
        check()
        change_a()
        label.config(text=a+"'s Chance")

The above function handles button clicks on the board. This calls the check() function(mentioned as function 4 above) and the change_a() function(mentioned as function 2 above) and sets the state and text of the button clicked.

In our main program we follow the steps given below:

  1. First of all, define the tk window with the Tk() as the root variable.
  2. Then we create the title of the window.
  3. Next, we define a variable to store the playable character(say, ‘O’ and ‘X’).
  4. Then we define a list to store all the buttons and place them in the window.
  5. Finally, we display a label saying the character which has to be played next.
  6. We end by a root.mainloop() function to keep events on the main window active and all other widgets interactive.

Also, in our code, we are using a messagebox class from the Tkinter library to display prompts during the game for the results.

The Complete program looks like so:

from tkinter import *
from tkinter import messagebox
import random as r
def button(frame):          #Function to define a button
    b=Button(frame,padx=1,bg="papaya whip",width=3,text="   ",font=('arial',60,'bold'),relief="sunken",bd=10)
    return b
def change_a():             #Function to change the operand for the next player
    global a
    for i in ['O','X']:
        if not(i==a):
            a=i
            break
def reset():                #Resets the game
    global a
    for i in range(3):
        for j in range(3):
                b[i][j]["text"]=" "
                b[i][j]["state"]=NORMAL
    a=r.choice(['O','X'])
def check():                #Checks for victory or Draw
    for i in range(3):
            if(b[i][0]["text"]==b[i][1]["text"]==b[i][2]["text"]==a or b[0][i]["text"]==b[1][i]["text"]==b[2][i]["text"]==a):
                    messagebox.showinfo("Congrats!!","'"+a+"' has won")
                    reset()
    if(b[0][0]["text"]==b[1][1]["text"]==b[2][2]["text"]==a or b[0][2]["text"]==b[1][1]["text"]==b[2][0]["text"]==a):
        messagebox.showinfo("Congrats!!","'"+a+"' has won")
        reset()   
    elif(b[0][0]["state"]==b[0][1]["state"]==b[0][2]["state"]==b[1][0]["state"]==b[1][1]["state"]==b[1][2]["state"]==b[2][0]["state"]==b[2][1]["state"]==b[2][2]["state"]==DISABLED):
        messagebox.showinfo("Tied!!","The match ended in a draw")
        reset()
def click(row,col):
        b[row][col].config(text=a,state=DISABLED,disabledforeground=colour[a])
        check()
        change_a()
        label.config(text=a+"'s Chance")
###############   Main Program #################
root=Tk()                   #Window defined
root.title("Tic-Tac-Toe")   #Title given
a=r.choice(['O','X'])       #Two operators defined
colour={'O':"deep sky blue",'X':"lawn green"}
b=[[],[],[]]
for i in range(3):
        for j in range(3):
                b[i].append(button(root))
                b[i][j].config(command= lambda row=i,col=j:click(row,col))
                b[i][j].grid(row=i,column=j)
label=Label(text=a+"'s Chance",font=('arial',20,'bold'))
label.grid(row=3,column=0,columnspan=3)
root.mainloop()

To learn more about Random:

random() module in Python

More games like this:

Rock Paper Scissors in Python using GUI Tkinter

Hangman Game with GUI in Python using Tkinter

Color Game with GUI in Python using Tkinter

 

4 responses to “Tic-Tac-Toe GUI in Python Using Tkinter”

  1. Laly Papa says:

    Exception in Tkinter callback
    Traceback (most recent call last):
    File “C:\Users\nagyuborka\Python37\lib\tkinter\__init__.py”, line 1705, in __call__
    return self.func(*args)
    File “C:/Users/nagyuborka/Python_programok/szotar_jatekok_toto_naptar_otlet/Tkinter_tic_tac_toe/Tkinter_t_t_t_00.py”, line 65, in
    b[i][j].config(command=lambda row=i, col=j: click(row, col))
    File “C:/Users/nagyuborka/Python_programok/szotar_jatekok_toto_naptar_otlet/Tkinter_tic_tac_toe/Tkinter_t_t_t_00.py”, line 52, in click
    label.config(text=a+”‘s Chance”)
    TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’

    • Satyam Singh Niranjan says:

      Works perfectly fine for me. I checked it right now. Try to make a new file and copy the code again into it and then run the same program. Maybe its a problem with the file name or something, because the code is tested several times and proved to work efficiently. If you have further queries don’t hesitate to reach me at my email id:
      [email protected]

  2. Nico Mapeso says:

    Hi, sir Good Sir I’m new to Tkinter I just would like to ask what is the process that undergoes in the check function? I’m kind of confused, the other functions are easy to understand but I’m just having a hard time understanding your conditions on the check function. Thank you and good day!

    • Satyam Singh Niranjan says:

      The variables ‘a’ is the current player’s sign(X or O). What the check() function does is to checks the board ‘b’ for 3 matching signs in a row/column/diagonal and also, if the board has been completely used i.e. all buttons are Disabled.
      1) Now the Loop has a condition which checks each Row and Column for 3 matching signs. Thus, the code checks the 1,2 and 3 Column for each Row and 1,2 and 3 Row for each Column.
      2) After the loop, there is another condition which checks the Diagonals for 3 matching signs, and thus the code checks the indices of the diagonals.
      3) The last part of the function is another condition which checks if the state of all buttons is Disabled. This is done to ensure if the game is tied.

      If any of the above conditions are satisfied a prompt is displayed to declare the result of the game.

Leave a Reply

Your email address will not be published. Required fields are marked *