[Python] 纯文本查看 复制代码
import pygame
import random
import copy
# 游戏参数
BOARD_SIZE = 4 # 棋盘大小
TILE_SIZE = 80 # 每个格子大小
SCORE_FONT_SIZE = 30 # 分数字体大小
# 配色方案
BACKGROUND_COLOR = (250, 248, 239)
TILE_COLORS = {
0: (205, 193, 180),
2: (238, 228, 218),
4: (237, 224, 200),
8: (242, 177, 121),
16: (245, 149, 99),
32: (246, 124, 95),
64: (246, 94, 59),
128: (237, 207, 114),
256: (237, 204, 97),
512: (237, 200, 80),
1024: (237, 197, 63),
2048: (237, 194, 46),
'other': (60, 58, 50)
}
TEXT_COLOR = (119, 110, 101)
# 初始化Pygame
pygame.init()
pygame.display.set_caption('2048')
# 创建窗口
screen = pygame.display.set_mode((
BOARD_SIZE * TILE_SIZE,
BOARD_SIZE * TILE_SIZE
))
# 加载字体
FONT = pygame.font.Font(None, 40)
SCORE_FONT = pygame.font.Font(None, SCORE_FONT_SIZE)
def draw_board(board, score):
"""
在屏幕上绘制棋盘,包括所有已经有数字的方块。
"""
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
value = board[i][j]
# 绘制每个格子
pygame.draw.rect(
screen, TILE_COLORS[value if value in TILE_COLORS else 'other'],
(j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE, TILE_SIZE)
)
# 绘制方块中的数字
if value:
text_surface = FONT.render(
str(value), True, TEXT_COLOR
)
rect = text_surface.get_rect()
rect.center = (
(j+0.5) * TILE_SIZE,
(i+0.5) * TILE_SIZE
)
screen.blit(text_surface, rect)
# 绘制分数
score_text_surface = SCORE_FONT.render(
f'Score: {score}', True, TEXT_COLOR
)
score_rect = score_text_surface.get_rect()
score_rect.bottomright = (
BOARD_SIZE * TILE_SIZE - 10,
BOARD_SIZE * TILE_SIZE - 10
)
screen.blit(score_text_surface, score_rect)
pygame.display.update()
def get_random_location(board):
"""
从棋盘中随机选择一个空位置(值为0)。
"""
empty_locations = []
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
if board[i][j] == 0:
empty_locations.append((i, j))
if empty_locations:
return random.choice(empty_locations)
else:
return None
def add_random_tile(board):
"""
在棋盘上随机添加一个2或4。
"""
location = get_random_location(board)
if location:
i, j = location
board[i][j] = random.choice([2, 4])
return board
def transpose_board(board):
"""
矩阵转置。
"""
return [list(row) for row in zip(*board)]
def reverse_rows(board):
"""
翻转每一行。
"""
return [row[::-1] for row in board]
def merge_tiles(row, score):
"""
将一行里的所有方块合并。
"""
new_row = [0] * BOARD_SIZE
index = 0
for i in range(BOARD_SIZE):
if row[i] != 0:
if new_row[index] == 0:
new_row[index] = row[i]
elif new_row[index] == row[i]:
new_row[index] *= 2
score += new_row[index]
index += 1
else:
index += 1
new_row[index] = row[i]
return new_row, score
def move_up(board, score):
"""
将棋盘上的数字全部往上移动。
"""
transposed_board = transpose_board(board)
new_board = []
for row in transposed_board:
new_row, score = merge_tiles(row, score)
new_board.append(new_row)
new_board = transpose_board(new_board)
return new_board, score
def move_down(board, score):
"""
将棋盘上的数字全部往下移动。
"""
transposed_board = transpose_board(board)
reversed_board = reverse_rows(transposed_board)
new_board = []
for row in reversed_board:
new_row, score = merge_tiles(row, score)
new_board.append(new_row)
new_board = reverse_rows(new_board)
new_board = transpose_board(new_board)
return new_board, score
def move_left(board, score):
"""
将棋盘上的数字全部往左移动。
"""
new_board = []
for row in board:
new_row, score = merge_tiles(row, score)
new_board.append(new_row)
return new_board, score
def move_right(board, score):
"""
将棋盘上的数字全部往右移动。
"""
reversed_board = reverse_rows(board)
new_board = []
for row in reversed_board:
new_row, score = merge_tiles(row, score)
new_board.append(new_row)
new_board = reverse_rows(new_board)
return new_board, score
def is_game_over(board):
"""
检查游戏是否结束。
"""
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
if board[i][j] == 0:
# 如果还有空位置,则游戏未结束
return False
elif j < BOARD_SIZE - 1 and board[i][j] == board[i][j+1]:
# 如果存在相邻两个方块相等,则游戏未结束
return False
elif i < BOARD_SIZE - 1 and board[i][j] == board[i+1][j]:
# 如果存在相邻两个方块相等,则游戏未结束
return False
return True
def game_loop():
"""
游戏主循环。
"""
board = [[0 for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
score = 0
board = add_random_tile(board)
board = add_random_tile(board)
draw_board(board, score)
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
pygame.quit()
return
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
board_new, score = move_up(board, score)
elif event.key == pygame.K_DOWN:
board_new, score = move_down(board, score)
elif event.key == pygame.K_LEFT:
board_new, score = move_left(board, score)
elif event.key == pygame.K_RIGHT:
board_new, score = move_right(board, score)
else:
continue
if board != board_new:
# 如果棋盘有更新,则添加新的方块并更新分数
board = board_new
board = add_random_tile(board)
draw_board(board, score)
if is_game_over(board):
# 如果游戏结束,则打印结束信息并重新开始游戏
print('Game over!')
board = [[0 for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
score = 0
board = add_random_tile(board)
board = add_random_tile(board)
draw_board(board, score)
if __name__ == '__main__':
game_loop()