Tkinter Programs

In [10]:
import tkinter as Tk
import random

Your homework this week is to make a Tkinter program that is a knight's tour game. We'll practice for this by building our own Tkinter game from scratch.

We will be making a Simon Says game. The Tkinter window will be a 2x2 grid of squares. One of them will blue and the rest will be red. The goal of the game will be for the player to click on the blue square without clicking on the red squares. We'll discuss the details of the game as we get to them.

Part 1: Let's create the base for the game. We'll put it in a class called SimonSaysGame. We want to create the 2x2 grid of red squares first.

In [9]:
class SimonSaysGame:
    def __init__(self):
        self.root = Tk.Tk()
        self.c = Tk.Canvas(self.root, width=500, height=500)
        self.r1 = self.c.create_rectangle(0,  0,  250,250, fill='red')
        self.r2 = self.c.create_rectangle(251,0,  500,250, fill='red')
        self.r3 = self.c.create_rectangle(0,  251,250,500, fill='red')
        self.r4 = self.c.create_rectangle(251,251,500,500, fill='red')
        self.c.pack()
        self.root.mainloop()
        
s = SimonSaysGame()

Part 2: Give the SimonSaysGame class a method that picks the next blue rectangle. We will need to randomly choosen a rectangle, set the old blue rectangle to red, set the new rectangle to blue, store some variable indciating which rectangle was picked. We will also need to modify the __init__() method to call our new method.

In [17]:
class SimonSaysGame:
    def __init__(self):
        self.root = Tk.Tk()
        self.c = Tk.Canvas(self.root, width=500, height=500)
        self.r1 = self.c.create_rectangle(0,  0,  250,250, fill='red')
        self.r2 = self.c.create_rectangle(251,0,  500,250, fill='red')
        self.r3 = self.c.create_rectangle(0,  251,250,500, fill='red')
        self.r4 = self.c.create_rectangle(251,251,500,500, fill='red')
        self.c.pack()
        
        # we need to initialize self.blue_rectangle before we call
        # self.pick_rectangle(), but it doesn't matter what value we pick.
        self.blue_rectangle = self.r1
        self.pick_rectangle()
        self.root.mainloop()
        
    def pick_rectangle(self):
        # This would be better if we just had a list of rectangle references
        # and then indexed the one we wanted.  Feel free to modify the solution
        # if you're following along!
        
        if self.blue_rectangle == 1:
            self.c.itemconfig(self.r1, fill='red')
        elif self.blue_rectangle == 2:
            self.c.itemconfig(self.r2, fill='red')
        elif self.blue_rectangle == 3:
            self.c.itemconfig(self.r3, fill='red')
        elif self.blue_rectangle == 4:
            self.c.itemconfig(self.r4, fill='red')
        
        self.blue_rectangle = random.randint(1,4)
        
        if self.blue_rectangle == 1:
            self.c.itemconfig(self.r1, fill='blue')
        elif self.blue_rectangle == 2:
            self.c.itemconfig(self.r2, fill='blue')
        elif self.blue_rectangle == 3:
            self.c.itemconfig(self.r3, fill='blue')
        elif self.blue_rectangle == 4:
            self.c.itemconfig(self.r4, fill='blue')
        
s = SimonSaysGame()

Part 3: Add an event for a mouse click. The function we add should check to see if the blue square was clicked. If it was, it will pick another blue rectangle. Otherwise it will do nothing.

In [19]:
class SimonSaysGame:
    def __init__(self):
        self.root = Tk.Tk()
        self.c = Tk.Canvas(self.root, width=500, height=500)
        self.r1 = self.c.create_rectangle(0,  0,  250,250, fill='red')
        self.r2 = self.c.create_rectangle(251,0,  500,250, fill='red')
        self.r3 = self.c.create_rectangle(0,  251,250,500, fill='red')
        self.r4 = self.c.create_rectangle(251,251,500,500, fill='red')
        self.c.pack()
        
        self.blue_rectangle = self.r1
        self.pick_rectangle()
        
        self.c.bind('<Button-1>',self.mouse_click)
        self.root.mainloop()
        
    def mouse_click(self, event):
        # get which rectangle was clicked
        if event.x <= 250 and event.y <= 250:
            rect = 1
        elif event.x >= 251 and event.y <= 250:
            rect = 2
        elif event.x <= 250 and event.y >= 251:
            rect = 3
        elif event.x >= 251 and event.y >= 251:
            rect = 4
            
        if rect == self.blue_rectangle:
            self.pick_rectangle()
        
    def pick_rectangle(self):
        if self.blue_rectangle == 1:
            self.c.itemconfig(self.r1, fill='red')
        elif self.blue_rectangle == 2:
            self.c.itemconfig(self.r2, fill='red')
        elif self.blue_rectangle == 3:
            self.c.itemconfig(self.r3, fill='red')
        elif self.blue_rectangle == 4:
            self.c.itemconfig(self.r4, fill='red')
        
        self.blue_rectangle = random.randint(1,4)
        
        if self.blue_rectangle == 1:
            self.c.itemconfig(self.r1, fill='blue')
        elif self.blue_rectangle == 2:
            self.c.itemconfig(self.r2, fill='blue')
        elif self.blue_rectangle == 3:
            self.c.itemconfig(self.r3, fill='blue')
        elif self.blue_rectangle == 4:
            self.c.itemconfig(self.r4, fill='blue')
        
s = SimonSaysGame()

Part 4: Add a score for the game. The score should go up by 1 each time the blue square is clicked and be reset to 0 each time a red square is picked. Display the score below the grid.

In [28]:
class SimonSaysGame:
    def __init__(self):
        self.root = Tk.Tk()
        self.c = Tk.Canvas(self.root, width=500, height=500)
        self.r1 = self.c.create_rectangle(0,  0,  250,250, fill='red')
        self.r2 = self.c.create_rectangle(251,0,  500,250, fill='red')
        self.r3 = self.c.create_rectangle(0,  251,250,500, fill='red')
        self.r4 = self.c.create_rectangle(251,251,500,500, fill='red')
        self.c.pack()
        
        self.blue_rectangle = self.r1
        self.pick_rectangle()
        
        self.c.bind('<Button-1>',self.mouse_click)
        
        self.score = 0
        self.score_box = Tk.Label(self.root, text="Score: 0")
        self.score_box.pack()
        
        self.root.mainloop()
        
    def mouse_click(self, event):
        if event.x <= 250 and event.y <= 250:
            rect = 1
        elif event.x >= 251 and event.y <= 250:
            rect = 2
        elif event.x <= 250 and event.y >= 251:
            rect = 3
        elif event.x >= 251 and event.y >= 251:
            rect = 4
            
        if rect == self.blue_rectangle:
            self.score += 1
            self.pick_rectangle()
        else:
            self.score = 0
            
        self.score_box['text'] = f"Score: {self.score}"
        
    def pick_rectangle(self):
        
        if self.blue_rectangle == 1:
            self.c.itemconfig(self.r1, fill='red')
        elif self.blue_rectangle == 2:
            self.c.itemconfig(self.r2, fill='red')
        elif self.blue_rectangle == 3:
            self.c.itemconfig(self.r3, fill='red')
        elif self.blue_rectangle == 4:
            self.c.itemconfig(self.r4, fill='red')
        
        self.blue_rectangle = random.randint(1,4)
        
        if self.blue_rectangle == 1:
            self.c.itemconfig(self.r1, fill='blue')
        elif self.blue_rectangle == 2:
            self.c.itemconfig(self.r2, fill='blue')
        elif self.blue_rectangle == 3:
            self.c.itemconfig(self.r3, fill='blue')
        elif self.blue_rectangle == 4:
            self.c.itemconfig(self.r4, fill='blue')
        
s = SimonSaysGame()