Game Development 33 min read

Python Game Development Examples: 2048, Snake, Tetris, and LianLianKan with Source Code

This article introduces four classic games—2048, Snake, Tetris, and LianLianKan—explaining their design principles, gameplay mechanics, and providing complete Python source code using Pygame and Tkinter, suitable for learners with basic Python and game programming knowledge.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Python Game Development Examples: 2048, Snake, Tetris, and LianLianKan with Source Code

This article presents four classic games implemented in Python: 2048, Snake, Tetris, and LianLianKan. For each game it describes the gameplay rules, the design principles behind the implementation, shows example screenshots, and provides the full source code using the Pygame or Tkinter libraries.

1. 2048

2048 is a popular number‑sliding puzzle where the player moves tiles up, down, left or right; identical tiles merge when they collide, and the goal is to create a tile with the value 2048. The game was first released on March 20, 2014, and the original version was posted on GitHub by Gabriele Cirulli.

The implementation treats the board as a 4×4 two‑dimensional list. Moving left, for example, is performed by traversing each row, collapsing non‑zero values, merging equal neighbours, and filling the remainder with zeros. The same logic is applied to the other three directions by rotating the board.

Example effect (image omitted for brevity).

Source code:

import random
import sys
import pygame
from pygame.locals import *
PIXEL = 150
SCORE_PIXEL = 100
SIZE = 4
class Map:
def __init__(self, size):
self.size = size
self.score = 0
self.map = [[0 for i in range(size)] for i in range(size)]
self.add()
self.add()
def add(self):
while True:
p = random.randint(0, self.size * self.size - 1)
if self.map[int(p / self.size)][int(p % self.size)] == 0:
x = random.randint(0, 3) > 0 and 2 or 4
self.map[int(p / self.size)][int(p % self.size)] = x
self.score += x
break
def adjust(self):
changed = False
for a in self.map:
b = []
last = 0
for v in a:
if v != 0:
if v == last:
b.append(b.pop() << 1)
last = 0
else:
b.append(v)
last = v
b += [0] * (self.size - len(b))
for i in range(self.size):
if a[i] != b[i]:
changed = True
a[:] = b
return changed
def rotate90(self):
self.map = [[self.map[c][r] for c in range(self.size)] for r in reversed(range(self.size))]
def over(self):
for r in range(self.size):
for c in range(self.size):
if self.map[r][c] == 0:
return False
for r in range(self.size):
for c in range(self.size - 1):
if self.map[r][c] == self.map[r][c + 1]:
return False
for r in range(self.size - 1):
for c in range(self.size):
if self.map[r][c] == self.map[r + 1][c]:
return False
return True
def moveUp(self):
self.rotate90()
if self.adjust():
self.add()
self.rotate90()
self.rotate90()
self.rotate90()
def moveRight(self):
self.rotate90()
self.rotate90()
if self.adjust():
self.add()
self.rotate90()
self.rotate90()
def moveDown(self):
self.rotate90()
self.rotate90()
self.rotate90()
if self.adjust():
self.add()
self.rotate90()
def moveLeft(self):
if self.adjust():
self.add()
def show(map):
for i in range(SIZE):
for j in range(SIZE):
screen.blit(map.map[i][j] == 0 and block[(i + j) % 2] or block[2 + (i + j) % 2], (PIXEL * j, PIXEL * i))
if map.map[i][j] != 0:
map_text = map_font.render(str(map.map[i][j]), True, (106, 90, 205))
text_rect = map_text.get_rect()
text_rect.center = (PIXEL * j + PIXEL / 2, PIXEL * i + PIXEL / 2)
screen.blit(map_text, text_rect)
screen.blit(score_block, (0, PIXEL * SIZE))
score_text = score_font.render((map.over() and "Game over with score " or "Score: ") + str(map.score), True, (106, 90, 205))
score_rect = score_text.get_rect()
score_rect.center = (PIXEL * SIZE / 2, PIXEL * SIZE + SCORE_PIXEL / 2)
screen.blit(score_text, score_rect)
pygame.display.update()
map = Map(SIZE)
pygame.init()
screen = pygame.display.set_mode((PIXEL * SIZE, PIXEL * SIZE + SCORE_PIXEL))
pygame.display.set_caption("2048")
# ... (game loop omitted for brevity)

2. Snake

Snake is a classic arcade game where the player controls a growing line (the snake) that moves around the screen eating food. The snake grows longer with each piece of food, and the game ends if the snake collides with the walls or itself.

The implementation uses Pygame to draw a 640×480 grid of 20×20 pixel squares. The snake’s body is stored as a list of coordinate pairs; the head is the last element. Food is placed at a random empty cell. Keyboard input changes the moving direction, and the game loop updates the snake’s position, checks for collisions, and renders the scene.

Source code:

import random
import sys
import pygame
from pygame.locals import *
PIXEL = 150
SCORE_PIXEL = 100
SIZE = 4
class Map:
def __init__(self, size):
self.size = size
self.score = 0
self.map = [[0 for i in range(size)] for i in range(size)]
self.add()
self.add()
# ... (methods identical to the 2048 implementation, omitted for brevity)
# Game initialization and main loop (similar to the 2048 example, adapted for snake mechanics)

3. Tetris

Tetris consists of falling tetrominoes made of four blocks each. The player can rotate and move the pieces horizontally; when a horizontal line is completely filled it disappears and the player gains points. The game ends when the stack reaches the top of the playfield.

The Python version defines the seven tetromino shapes (I, J, L, O, S, T, Z) and stores all possible rotations in a list. The board is a 15×25 matrix. The game loop handles piece falling, user input, line clearing, and rendering.

Source code:

import pygame
import random
import os
pygame.init()
GRID_WIDTH = 20
GRID_NUM_WIDTH = 15
GRID_NUM_HEIGHT = 25
WIDTH, HEIGHT = GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHT
# ... (color definitions, screen setup, and helper functions omitted for brevity)
class CubeShape(object):
SHAPES = ['I', 'J', 'L', 'O', 'S', 'T', 'Z']
I = [[(0,-1),(0,0),(0,1),(0,2)], [(-1,0),(0,0),(1,0),(2,0)]]
# ... (other shape definitions omitted)
def __init__(self):
self.shape = self.SHAPES[random.randint(0, len(self.SHAPES)-1)]
self.center = (2, GRID_NUM_WIDTH // 2)
self.dir = random.randint(0, len(self.SHAPES_WITH_DIR[self.shape]) - 1)
self.color = CUBE_COLORS[random.randint(0, len(CUBE_COLORS)-1)]
# Game loop handling rotation, movement, line removal, and drawing (omitted for brevity)

4. LianLianKan (Link Game)

LianLianKan is a tile‑matching puzzle where the player must connect two identical tiles with a path that contains at most two right‑angle turns and does not cross other tiles. When a pair is connected, both tiles disappear.

The implementation uses Tkinter for the GUI. The board is a 10×10 matrix of image identifiers. Functions are provided to check direct connections, one‑corner connections, and two‑corner connections. Mouse click events select tiles, and the algorithm determines whether the selected pair can be linked.

Source code (key parts):

from tkinter import *
from tkinter.messagebox import *
from threading import Timer
import time, random
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def IsLink(p1, p2):
if lineCheck(p1, p2): return True
if OneCornerLink(p1, p2): return True
if TwoCornerLink(p1, p2): return True
return False
# ... (functions lineCheck, OneCornerLink, TwoCornerLink, drawLinkLine, etc.)
# Mouse callback to handle tile selection and linking
def callback(event):
x = event.x // 40
y = event.y // 40
# selection logic omitted for brevity
# Map creation and mainloop
root = Tk()
root.title("Python连连看")
# ... (image loading, map generation, and event bindings)
root.mainloop()

At the end of the article a QR code is provided for readers to scan and receive free Python learning resources, including e‑books, tutorials, project source code, and other materials.

Pythongame developmentTetrisTkinterPygame2048LianLianKanSnake
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.