Just Made a Tic-Tac-Toe Game in Python (How You Can Too)

Just Made a Tic-Tac-Toe Game in Python (How You Can Too)


It’s easy to think that making a tic-tac-toe game using Python is complicated, time-consuming, and just for really advanced developers. In reality it isn’t, and in just a few steps, I’ll show you how to make a simple tic-tac-toe game.



Step 1: Create the Layout

We’ll start by creating a Python file. Afterwards, we’ll import Tkinter (module for creating GUIs in Python) then define things such as fonts, the GUI’s size and background, and so on:

from tkinter import *
from tkinter import font

root = Tk()
root.title("Python-Tic-Tac-Toe Game")
root.configure(bg='lightblue') # Sets GUI background to lightblue
root.geometry("300x400") # Defines size of GUI
root.resizable(False, False) # Says GUI can't be resized

f = font.Font(family='Courier', size=24) 
o = font.Font(family='Courier', size=18) 
Enter fullscreen mode

Exit fullscreen mode

Great! Now, wouldn’t it be good to have a welcome page w/ a ‘Yes’ or ‘No’ button? I bet you said yes (and if you didn’t, go back to Ohio!). To do that, simply type/copy and paste:

l = Label(root, text="Python Tic\nTac Toe Game", font=f, bg='lightblue')
l.place(x=30, y=30)

b = Label(root, text="Wish to continue?", font=o, bg='lightblue')
b.place(x=30, y=150)

c = Button(root, text="Yes", font=o, width=10, height=1, bg='white')
c.place(x=70, y=220)

d = Button(root, text="No", font=o, width=10, height=1, bg='white')
d.place(x=70, y=290)
Enter fullscreen mode

Exit fullscreen mode

Our program should now look something like this:

Image description

Our program looks great! But if you notice, the buttons won’t do anything. To solve that, underneath d.place(), type/copy and paste:

d.config(command=da) 
Enter fullscreen mode

Exit fullscreen mode

and underneath c.place(), type/copy and paste:

c.config(command=ca) 
Enter fullscreen mode

Exit fullscreen mode

After that, create and fill in functions da and ca, like so:

def da():
    root.destroy() #This deletes the GUI when someone clicks the button 'No'

def ca():
   l.destroy()
   b.destroy()
   d.destroy()
   c.destroy()

    global vas
    global av
    global ab

    vas = Label(root, text="Which one would\nyou like to use?", font=o, bg='lightblue')
    vas.place(x=30, y=30)

    av = Button(root, text="X", font=o, bg='white', width=5, height=2)
    av.place(x=30, y=150)

    ab = Button(root, text="O", font=o, bg='white', width=5, height=2)
    ab.place(x=170, y=150)


Enter fullscreen mode

Exit fullscreen mode

This will delete the contents from the welcome page and replace them with new text (that being ‘Which one would you like to use?’) and new buttons (that being X or O). Now, once we click ‘Yes’, or GUI should like this:

Image description



Step 2: Create the Tic-Tac-Toe board

We’ve now created a welcome page, and given the user the ability to choose either X or O. But sadly, the buttons don’t do anything, and we still haven’t made the actual tic-tac-toe board. To fix that, underneath av.place() type/copy and paste:

av.config(command=x)
Enter fullscreen mode

Exit fullscreen mode

and underneath ab.place() type/copy and paste:

ab.config(command=ask)
Enter fullscreen mode

Exit fullscreen mode

Once finished, create and fill in functions x and ask, like so:

def x():
    global vas, av, ab, ba, bb, bc, bd, be, bf, bg, bh, bi, label, i, buttons
    vas.destroy()
    av.destroy()
    ab.destroy()



    # Row 1
    ba = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(ba, buttons))
    ba.place(x=30, y=70)


    bb = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bb, buttons))
    bb.place(x=110, y=70)


    bc = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bc, buttons))
    bc.place(x=190, y=70)

    # Row 2
    bd = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bd, buttons))
    bd.place(x=30, y=145)


    be = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(be, buttons))
    be.place(x=110, y=145)

    bf = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bf, buttons))
    bf.place(x=190, y=145)


    # Row 3
    bg = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bg, buttons))
    bg.place(x=30, y=220)

    bh = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bh, buttons))
    bh.place(x=110, y=220)

    bi = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action(bi, buttons))
    bi.place(x=190, y=220)

    label = Label(root, text=f'TIMER:\nO:15', font=o, bg='lightblue')
    label.place(x=100, y=10)

    buttons = [ba, bb, bc, bd, be, bf, bg, bh, bi]

    start_time = Time.time()

    for i in range(15, -1, -1):
        label.config(text=f'TIMER:\nO:{i}')
        root.update() #force the label to update.
        Time.sleep(0.8) #add a one second delay, so the user can see the change.

    end = Time.time()

    r = end - start_time
    result = 12 - r



    if result < 1:
        for button in buttons:
            button.config(state=DISABLED)
        label.destroy()
        d = Label(root, text="No Winner: Tie!!!!", font=o, bg='lightblue')
        d.place(x=20, y=30)


def ask():
    global vas, av, ab, b1, b2, b3, b4, b5, b6, b7, b8, b9, label, buttons1 
    vas.destroy()
    av.destroy()
    ab.destroy()



    # Row 1
    b1 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b1, buttons1))
    b1.place(x=30, y=70)


    b2 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b2, buttons1))
    b2.place(x=110, y=70)


    b3 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b3, buttons1))
    b3.place(x=190, y=70)

    # Row 2
    b4 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b4, buttons1))
    b4.place(x=30, y=145)


    b5 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b5, buttons1))
    b5.place(x=110, y=145)

    b6 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b6, buttons1))
    b6.place(x=190, y=145)


    # Row 3
    b7 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b7, buttons1))
    b7.place(x=30, y=220)

    b8 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b8, buttons1))
    b8.place(x=110, y=220)

    b9 = Button(root, font=o, bg='white', width=5, height=2, text=" ", command=lambda: u_action1(b9, buttons1))
    b9.place(x=190, y=220)


    label = Label(root, text=f'TIMER:\nO:15', font=o, bg='lightblue')
    label.place(x=100, y=10)

    buttons1 = [b1, b2, b3, b4, b5, b6, b7, b8, b9]

    start_time = Time.time()

    for i in range(15, -1, -1):
            label.config(text=f'TIMER:\nO:{i}')
            root.update() #force the label to update.
            Time.sleep(0.8) #add a one second delay, so the user can see the change.

    end = Time.time()

    r = end - start_time
    result = 12 - r


    if result < 1:
        for button in buttons1:
            button.config(state=DISABLED)
        label.destroy()
        d = Label(root, text="No Winner: Tie!!!!", font=o, bg='lightblue')
        d.place(x=20, y=30)

Enter fullscreen mode

Exit fullscreen mode

With these functions, you should have the tic-tac-toe board as well as a 15 second timer:

Image description

(P.S: If the timer isn’t what you wish it to be, you can always change it in text=f’TIMER:\nO:15′ and for i in range(15, -1, -1) )

Again, we’re faced with the issue of the buttons not doing anything. To solve that, we’ll have to…



Step 3: Allow User to Play

Start by creating functions, u_action and u_action1, and fill them in with the code below:

def u_action(button, buttons):
    button.config(text="X")
    button.config(state=DISABLED)

def u_action1(button, buttons1):
    button.config(text="O")
    button.config(state=DISABLED)
Enter fullscreen mode

Exit fullscreen mode

Now, once we click a button, it becomes filled with X or O and is then disabled (as in it can’t be clicked again). It’s progress, but tic-tac-toe wasn’t made for just one player. To fix that, we’ll need to create a bot, and since I said this tutorial would be easy, simply download the Logic module (link: https://drive.google.com/file/d/1aWYqNuVPvVdRNNtXuo670ULCxJMiJ8Bq/view?usp=sharing), then import it into your file:

import Logic #make sure 'l' is uppercase to avoid errors.
Enter fullscreen mode

Exit fullscreen mode

Afterwards, add the line below to u_action():

Logic.b_action(root, buttons, label, o)
Enter fullscreen mode

Exit fullscreen mode

and add this code to u_action1():

Logic.b_action1(root, buttons1, label, o)
Enter fullscreen mode

Exit fullscreen mode

Congrats 🎉🎉🎉! You’ve officially made your very own tic-tac-toe game, with a welcome page, ability to choose X or O, and a bot to play against! Hopefully you’ve enjoyed making it as much as I did, and if you have any questions, please leave a comment. PEACE!✌️✌️✌️



Source link

Leave a Reply

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