# Game case based on pygame

### Game case based on pygame

• ##### Rules of the game:

The keyboard controls which direction all the squares will move. Two squares with the same number will be added when they collide. Each time the number moves, the blank will randomly refresh a number of squares. When the interface is not moving (when the interface is full of numbers), the game ends; when the maximum number in the interface is 2048, the game wins.

#### Three. 2048

###### code analysis

New figures

``````    # Add 2 or 4, with 1 / 4 probability to produce 4
while True:
p = random.randint(0, self.size * self.size - 1)
if self.map[p // self.size][p % self.size] == 0:
x = random.randint(0, 3) > 0 and 2 or 4
self.map[p // self.size][p % self.size] = x
self.score += x
break
``````

The map moves to the left and rotates in other directions

``````    # The map moves to the left, and other directions can be moved by proper rotation to return whether the map is updated or not
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
``````

Counter clockwise rotation

``````    # Rotate the map 90 degrees counter clockwise
def rotate90(self):
self.map = [[self.map[c][r] for c in range(self.size)] for r in reversed(range(self.size))]
``````

Judge the end of the game

``````    # Judge the end of the game
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
``````

Score display

``````# Score display
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()
``````

Set color

``````# Set color
block[0].fill((152, 251, 152))
block[1].fill((240, 255, 255))
block[2].fill((0, 255, 127))
block[3].fill((225, 255, 255))
score_block = pygame.Surface((PIXEL * SIZE, SCORE_PIXEL))
score_block.fill((245, 245, 245))
``````

Set font

``````# Set font
map_font = pygame.font.Font(None, PIXEL)
score_font = pygame.font.Font(None, SCORE_PIXEL)
clock = pygame.time.Clock()
show(map)
``````
###### Part of code
``````import random
import sys
import pygame
from pygame.locals import *

PIXEL = 150
SCORE_PIXEL = 100
SIZE = 4

# Class of map
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)]

# Add 2 or 4, with 1 / 4 probability to produce 4
while True:
p = random.randint(0, self.size * self.size - 1)
if self.map[p // self.size][p % self.size] == 0:
x = random.randint(0, 3) > 0 and 2 or 4
self.map[p // self.size][p % self.size] = x
self.score += x
break

# The map moves to the left, and other directions can be moved by proper rotation to return whether the map is updated or not
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

# Rotate the map 90 degrees counter clockwise
def rotate90(self):
self.map = [[self.map[c][r] for c in range(self.size)] for r in reversed(range(self.size))]

# Judge the end of the game
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()
self.rotate90()
self.rotate90()
self.rotate90()

def moveRight(self):
self.rotate90()
self.rotate90()
self.rotate90()
self.rotate90()

def moveDown(self):
self.rotate90()
self.rotate90()
self.rotate90()
self.rotate90()

def moveLeft(self):

# Update screen
def show(map):
for i in range(SIZE):
for j in range(SIZE):
# Background color block
screen.blit(map.map[i][j] == 0 and block[(i + j) % 2] or block[2 + (i + j) % 2], (PIXEL * j, PIXEL * i))
# Numerical display
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)
# Score display
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")
block = [pygame.Surface((PIXEL, PIXEL)) for i in range(4)]
# Set color
block[0].fill((152, 251, 152))
block[1].fill((240, 255, 255))
block[2].fill((0, 255, 127))
block[3].fill((225, 255, 255))
score_block = pygame.Surface((PIXEL * SIZE, SCORE_PIXEL))
score_block.fill((245, 245, 245))
# Set font
map_font = pygame.font.Font(None, PIXEL)
score_font = pygame.font.Font(None, SCORE_PIXEL)
clock = pygame.time.Clock()
show(map)

while not map.over():
# 12 is the experimental parameter
clock.tick(12)
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
pressed_keys = pygame.key.get_pressed()
if pressed_keys[K_w] or pressed_keys[K_UP]:
map.moveUp()
elif pressed_keys[K_s] or pressed_keys[K_DOWN]:
map.moveDown()
elif pressed_keys[K_a] or pressed_keys[K_LEFT]:
map.moveLeft()
elif pressed_keys[K_d] or pressed_keys[K_RIGHT]:
map.moveRight()
show(map)

# Game over
pygame.time.delay(3000)
``````

Tags: Python Pycharm

Posted on Tue, 17 Mar 2020 09:09:13 -0700 by elis