Flipping Tiles (memory game) using Python3

A memory game where players flip tiles to match colors is a classic puzzle that helps improve concentration and memory skills. In this tutorial, we'll build a 4×4 grid memory game using Python's tkinter library.

Required Libraries

The game uses these built-in Python packages ?

  • tkinter ? Creates the graphical user interface

  • random ? Shuffles tile colors randomly

  • itertools ? Simplifies grid iteration

  • ctypes ? Handles Windows display scaling

Game Logic

The memory game follows these rules ?

  • Click a tile to reveal its hidden color

  • Click a second tile to compare colors

  • If colors match, both tiles stay revealed

  • If colors don't match, both tiles flip back to white

  • Game ends when all tiles are matched

  • Score is tracked by number of clicks

Complete Game Implementation

import itertools
import tkinter as tk
import random
import ctypes

# Windows display scaling
ctypes.windll.shcore.SetProcessDpiAwareness(1)

# Global game variables
pressed = -1
tile_flipped = 16
count_move = 0
maxscore = 0

def is_winner():
    global maxscore, count_move
    if tile_flipped == 0:
        if count_move <= maxscore or maxscore == -1:
            maxscore = count_move
            with open('maxscore.txt', 'w') as f:
                f.write(str(maxscore))
        win_lbl['text'] = f'CLICKS: {str(count_move)}, BEST: {str(maxscore)}'

def print_count_move():
    win_lbl['text'] = f'CLICKS: {str(count_move)}'

def new_game():
    global pressed, tile_flipped, btns, colours, count_move, win_lbl, maxscore
    pressed = -1
    tile_flipped = 16
    count_move = 0
    btns = {}
    win_lbl['text'] = ''

    # Create score file if it doesn't exist
    try:
        with open('maxscore.txt', 'r') as f:
            pass
    except FileNotFoundError:
        with open('maxscore.txt', 'w') as f:
            f.write('-1')
             
    with open('maxscore.txt', 'r') as f:
        maxscore = int(f.readline().strip())
    
    random.shuffle(colours)

    # Create buttons
    k = 0
    for _, _ in itertools.product(range(4), range(4)):
        btn = Button(k)
        btns[k] = btn
        if k != len(colours) - 1: 
            k += 1

    # Position buttons in grid
    k = 0
    for i, j in itertools.product(range(4), range(4)):
        btns[k].bttn.grid(row=i, column=j, sticky='nsew')
        if k != len(colours) - 1: 
            k += 1

class Button:
    def __init__(self, k):
        self.index = k
        self.bttn = tk.Button(
            frm, 
            width=6, 
            height=2, 
            borderwidth=6, 
            bg='white', 
            activebackground=colours[self.index], 
            command=self.btn_press
        )
        
    def btn_press(self):
        global pressed, count_move
        self.bttn.configure(bg=colours[self.index])
        count_move += 1
        print_count_move()
        
        if pressed == -1:
            pressed = self.index
        else:
            self.compare_pressed_btns()
    
    def compare_pressed_btns(self):
        global pressed, tile_flipped

        if colours[self.index] != colours[pressed]:
            # Colors don't match - flip back
            self.bttn.configure(bg='white')
            btns[pressed].bttn.configure(bg='white')
        elif self.index != pressed:
            # Colors match - disable buttons
            self.bttn['state'] = tk.DISABLED
            btns[pressed].bttn['state'] = tk.DISABLED
            tile_flipped -= 2
            is_winner()
        else:
            # Same button clicked twice
            self.bttn.configure(bg='white')
        
        pressed = -1

# Create main window
window = tk.Tk()
window.title('Memory Tile Game')
window.config(bg='black')

window.rowconfigure([0, 1], weight=1, pad=2)
window.columnconfigure(0, weight=1, pad=2)

# Game board frame
frm = tk.Frame(window, bg='Gray')
frm.grid(row=0, column=0, sticky='nsew')
frm.rowconfigure(list(range(4)), minsize=50, pad=2)
frm.columnconfigure(list(range(4)), minsize=50, pad=2)

# Initialize game components
btns = {}
colours = ['YellowGreen', 'Violet', 'Tomato', 'SlateBlue', 'DarkCyan', 'Orange', 'DodgerBlue', 'ForestGreen'] * 2
random.shuffle(colours)

# Score and control frame
frm2 = tk.Frame(window, bg='Khaki')
win_lbl = tk.Label(frm2, width=19, height=1, bg='PowderBlue', relief=tk.GROOVE, borderwidth=2)
win_lbl.grid(row=0, column=0, padx=5, pady=5, sticky='nsew')

new_game_btn = tk.Button(
    text='NEW GAME', 
    master=frm2, 
    width=10, 
    height=1, 
    borderwidth=3, 
    bg='Plum', 
    command=new_game
)
new_game_btn.grid(row=0, column=1, padx=5, pady=5, sticky='nsew')
frm2.grid(row=1, column=0, sticky='nsew')

# Start the game
new_game()
window.mainloop()

How It Works

The game creates a 4×4 grid with 8 color pairs randomly distributed. When you click a tile, it reveals its color and waits for a second click. If the colors match, both tiles remain visible and are disabled. If they don't match, both tiles flip back to white after a brief display.

Key Components

  • Button class ? Handles individual tile behavior and color matching logic

  • new_game() ? Resets the game state and shuffles colors

  • is_winner() ? Checks win condition and updates high score

  • Score tracking ? Saves best score to 'maxscore.txt' file

Game Features

  • Click counter tracks your moves

  • Best score persistence across game sessions

  • New Game button to restart anytime

  • Visual feedback with color reveals

Conclusion

This memory tile game demonstrates GUI development with tkinter, file handling for score persistence, and game logic implementation. It's an excellent project for learning Python GUI programming while creating an engaging memory training game.

Updated on: 2026-03-27T13:13:43+05:30

620 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements