How to Code Tic Tac Toe in Python using Tkinter

Image Credits: https://en.wikipedia.org/wiki/File:Tic_tac_toe.svgIn this article, we will code the classic paper-pen game with a nice GUI. We will be coding it in Python and we will be using Tkinter for the interface. So let’s get started!What is the g…


This content originally appeared on Level Up Coding - Medium and was authored by Riya Tendulkar

Image Credits: https://en.wikipedia.org/wiki/File:Tic_tac_toe.svg

In this article, we will code the classic paper-pen game with a nice GUI. We will be coding it in Python and we will be using Tkinter for the interface. So let’s get started!

What is the game?

Tic Tac Toe is a 2 player game where each player has a symbol (either X or O) and plays alternately to mark their symbol on a 3x3 grid. If any player gets their symbol consecutively 3 times in a row, column or diagonal then that player is the winner.

A sample grid- the numbers in the boxes are just for reference.

As we can see over here, we have a 3x3 grid. Each player will play alternately. Lets say player X goes first and selects box 1. So grid[0][0] will have the value as X. The player O will go next now and if he selects the box 5, grid[1][1] will have the value O. This will continue till either all boxes have been filled or there is a winner. Let us look at what the winning conditions are.

Winning Conditions

If any 3 consecutive boxes have the same value (X or O) then we have a winner. So in total, we have 8 winning conditions — 3 for the rows, 3 for the columns and 2 for the diagonals.

Row Winning Conditions

Row Winning Conditions- X symbol is just for reference

Row Winning Conditions ( X is just for example)

So the box values for the conditions are:

  1. 1=2=3 i.e. grid[0][0]=grid[0][1]=grid[0][2]
  2. 4=5=6 i.e. grid[1][0]=grid[1][1]=grid[1][2]
  3. 7=8=9 i.e. grid[2][0]=grid[2][1]=grid[2][2]

Column Winning Conditions

Column Winning Conditions- X is just for reference

So the box values for the winning conditions are:

  1. 1=4=7 i.e. grid[0][0]=grid[1][0]=grid[2][0]
  2. 2=5=8 i.e. grid[0][1]=grid[1][1]=grid[2][1]
  3. 3=6=9 i.e. grid[0][2]=grid[1][2]=grid[2][2]

Diagonal Winning Conditions

Diagonal Winning Conditions — X is just for reference

So the winning conditions are:

  1. 1=5=9 i.e. grid[0][0]=grid[1][1]=grid[2][2]
  2. 3=5=7 i.e. grid[0][2]=grid[1][1]=grid[2][0]

So now we have listed out all the 8 winning conditions. It is important to note the row and column values of the winning conditions as we will be using them in the code.

Coding in Python

We will need the following functions for coding the game:

  1. The game interface- a proper window where the users can the game
  2. Check winner — After every move we need to check for the winner
  3. Change Value- After every move, we need to update the GUI which the user sees
  4. Display Winner- A window to display the winner
  5. Quit- A function which quits the game

The first thing we need to do is import the tkinter library.

We then initialize two important variables- count and board.

The count variable keeps a track of how many turns have been played. After every turn, the count variable is incremented by 1.

As seen in the winning conditions, we have a 3x3 grid. While coding, we will transform this grid into a double dimensional array called board having 3 rows and 3 columns.

from tkinter import *
from tkinter import messagebox
count=0
board=[[‘’,’’,’’,],
[‘’,’’,’’,],
[‘’,’’,’’,]]

TicTacToeGUI(): Game Window

Now we need to create the user interface. For that we have a function TicTacToeGUI().

Game Window

We have 9 square buttons which are packed together to form a square matrix. At the top we will display which player’s turn it is. The first player is X so at the top it is displayed as PLAYER: 1(X). After every move the player will change. So after one turn the top will have PLAYER: 2(O). We also provide a quit button whenever the user wants to quit. Initially the button will have text value as blank. Whenever the user clicks on a button to play, the text of the button will change to the player’s value (X or O).

To do this placing, we keep the layout of the window in the form of a grid. Row 0, column 0 will have the player and row 0 column 3 will have the quit button. The next 3 rows and columns will have the game buttons.

def TicTacToeGUI():
global t
t=Tk()
t.title("TIC TAC TOE")
t.configure(bg="white")
#Making the background of the window as white#Displaying the player
l1=Label(t,text="PLAYER: 1(X)",height=3,font=("COMIC SANS MS",10,"bold"),bg="white")
l1.grid(row=0,column=0)#Quit button
exitButton=Button(t,text="Quit",command=Quit,font=("COMIC SANS MS",10,"bold"))
exitButton.grid(row=0,column=2)#Grid buttons
b1=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b1,0,0))
b2=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b2,0,1))
b3=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b3,0,2))
b4=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b4,1,0))
b5=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b5,1,1))
b6=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b6,1,2))
b7=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b7,2,0))
b8=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b8,2,1))
b9=Button(t,text="",height=4,width=8,bg="black",activebackground="white",fg="white",font="Times 15 bold",command=lambda: changeVal(b9,2,2))b1.grid(row=2,column=0)
b2.grid(row=2,column=1)
b3.grid(row=2,column=2)b4.grid(row=3,column=0)
b5.grid(row=3,column=1)
b6.grid(row=3,column=2)b7.grid(row=4,column=0)
b8.grid(row=4,column=1)
b9.grid(row=4,column=2)

As we can see that we have 9 buttons b1,b2,b3,b4,b5,b6,b7,b8,b9 and the window t is in grid format. You can correlate the button numbers and their row and column values with the numbers we had given to the sample grid we saw above.

The buttons have initial text value as blank and the height is 4 and width is 8. Background color is black and text is white. The activebackground is white, i.e. when we click on a button the color becomes white.

On clicking every button, a function changeVal is called. The statement for that is: command=lambda:changeVal().

changeVal(): Change Value of Button and Update Board

Whenever a players clicks on the button, we need to change the text of the button and also add the player’s symbol to the board. The changeVal function does exactly that. The parameters of the function are button, boardValRow, boardValCol which corresponds to the button variable, the value of the row of the button and the column of the button.

#Changes the value of the button
def changeVal(button,boardValRow,boardValCol):
global count#Checking if button is available
if button["text"]=="":
if count%2==0:
button["text"]="X"
l1=Label(t,text="PLAYER: 2(O)",height=3,font=("COMIC
SANS MS",10,"bold"),bg="white").grid(row=0,column=0)
board[boardValRow][boardValCol]="X"
else:
button["text"]="O"
l1=Label(t,text="PLAYER: 1(X)",height=3,font=("COMIC
SANS MS",10,"bold"),bg="white").grid(row=0,column=0)
board[boardValRow][boardValCol]="O"
count=count+1
if count>=5:
checkWinner()
else:
messagebox.showerror("Error","This box already has a value!")

Before changing the text of the button, we need to check if the button is available as sometimes it happens that a user may accidentally click on a button which has been played already. So we first check if the button text value is empty. If it is not then display an error.

If the button is available, we display the symbol of the player. To check which player’s turn it is, we use the count variable. As mentioned above, after every turn we increment the count variable and every player plays alternately. So whenever count has an even value, it will be player X’s turn and whenever the value is odd, it will be O’s turn. So depending on the player, we change the text of the button and then we also have to update which players turn it is next. So whenever we change a button value to X, we display that the next player is O and vice versa.

At the start we made a 2D array board which is a representation of the actual board. So after every turn, whenever we change the value of a button, we also change the board array. We use the variables boardValRow and boardValCol to access the array and change the value to the symbol: board[boardValRow][boardValCol]=symbol.

Now that we have done the necessary changes, we increment count by 1 and call the check winner function to see if there is any winner. For a winner, a player must have played at least 3 times. Since a player plays after every alternate turn, there will be no winner for the first 4 turns, so we call the check winner function after count≥5.

checkWinner(): Checking for winner

In this function we basically check all the board values for the winning conditions we have seen in detail in the above section(Winning Conditions). We do the checking for both the symbols.

Tie Condition: A tie will occur when all 9 places have been selected and still there is no winner. So when the variable count is 9, there will be a tie.

We call the function displayWinner to display the winner or if it is a tie.

#Checks for the winner        
def checkWinner():
global count,board
if (board[0][0]==board[0][1]==board[0][2]=="X" or board[1]
[0]==board[1][1]==board[1][2]=="X" or board[2][0]==board[2]
[1]==board[2][2]=="X" or board[0][0]==board[1][0]==board[2]
[0]=="X" or board[0][1]==board[1][1]==board[2][1]=="X" or
board[0][2]==board[1][2]==board[2][2]=="X" or
board[0][0]==board[1][1]==board[2][2]=="X" or board[0]
[2]==board[1][1]==board[2][0]=="X"):
displayWinner("Player X")
elif (board[0][0]==board[0][1]==board[0][2]=="O" or board[1]
[0]==board[1][1]==board[1][2]=="O" or board[2][0]
==board[2][1]==board[2][2]=="O" or
board[0][0]==board[1][0]==board[2][0]=="O" or board[0]
[1]==board[1][1]==board[2][1]=="O" or board[0]
[2]==board[1][2]==board[2][2]=="O" or board[0]
[0]==board[1][1]==board[2][2]=="O" or board[0]
[2]==board[1][1]==board[2][0]=="O"):
displayWinner("Player O")
elif count==9:
displayWinner("NONE! IT IS A TIE!")

The if conditions have the exact some conditions that we have seen above, but if you want you can use for loops to loop through the board.

displayWinner(): Display the winner/tie in a new window

This function has a parameter- winner which has the winner symbol. We create a new window and display the winner or a tie.

We have a button proceed, which upon clicking will call the destruct function which will destroy the game window and winner window.

#Displays the winning condition
def displayWinner(winner):
global t,winnerWindow,ID
winnerWindow=Tk()
winnerWindow.title("Winner Window")
winnerWindow.configure(bg="Black")
l1=Label(winnerWindow,text="THE WINNER IS: ",font=("COMIC SANS
MS",15),bg="Black",fg="White")
l1.pack()
l2=Label(winnerWindow,text=winner,font=("COMIC SANS
MS",15),bg="Black",fg="White")
l2.pack()
bproceed=Button(winnerWindow,text="Proceed",font=("COMIC SANS
MS",10,"bold"),command=destruct)
bproceed.pack()

destruct(): Destroying game and winner window

#Destructs the winner window and game window
def destruct():
global t,winnerWindow
t.destroy()
winnerWindow.destroy()

Quit(): Finishing the game

In the GUI function, we had a button named Quit. This function destroys the game window but before that confirms if the user still wants to quit. If the user says yes, then we destruct the game. We use the messagebox library to display the message

def Quit():
global t
msg=messagebox.askquestion(“Confirm”,”Are you want to Quit? You still have chances!”)
if msg==’yes’:
t.destroy()

Here are a few snaps of how the game will look:

In the 1st image it is X’s turn and so on the top is displays Player: 1(X). In the second image X plays and the in the 3rd O plays.
In the 1st image X plays again, in the 2nd image O plays and in the last image X plays and wins.

After this, the winner will be displayed in another window.

Winner Window

Check out the entire code over here :


How to Code Tic Tac Toe in Python using Tkinter was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Riya Tendulkar


Print Share Comment Cite Upload Translate Updates
APA

Riya Tendulkar | Sciencx (2021-03-16T13:29:15+00:00) How to Code Tic Tac Toe in Python using Tkinter. Retrieved from https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/

MLA
" » How to Code Tic Tac Toe in Python using Tkinter." Riya Tendulkar | Sciencx - Tuesday March 16, 2021, https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/
HARVARD
Riya Tendulkar | Sciencx Tuesday March 16, 2021 » How to Code Tic Tac Toe in Python using Tkinter., viewed ,<https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/>
VANCOUVER
Riya Tendulkar | Sciencx - » How to Code Tic Tac Toe in Python using Tkinter. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/
CHICAGO
" » How to Code Tic Tac Toe in Python using Tkinter." Riya Tendulkar | Sciencx - Accessed . https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/
IEEE
" » How to Code Tic Tac Toe in Python using Tkinter." Riya Tendulkar | Sciencx [Online]. Available: https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/. [Accessed: ]
rf:citation
» How to Code Tic Tac Toe in Python using Tkinter | Riya Tendulkar | Sciencx | https://www.scien.cx/2021/03/16/how-to-code-tic-tac-toe-in-python-using-tkinter/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.