import pygame
import random
import time
# 初始化 pygame
pygame.init()
# 定义阶数变量
order = 4
# 屏幕大小
SCREEN_WIDTH = order * 100
SCREEN_HEIGHT = order * 100
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (128, 255, 128)
GRAY = (255, 128, 128) # 用于填充边框内区域的颜色
# 生成可解的数字华容道布局
def generate_solvable_layout(order1):
layout1 = list(range(1, order1 * order1))
layout1.append(0) # 空位
# 打乱顺序
random.shuffle(layout1)
# 检查是否可解,若不可解则继续重新打乱
while not is_solvable(layout1):
random.shuffle(layout1)
return layout1
# 判断布局是否可解
def is_solvable(layout1):
inversion_count = 0
for i in range(len(layout1) - 1):
for j in range(i + 1, len(layout1)):
if layout1[i] != 0 and layout1[j] != 0 and layout1[i] > layout1[j]:
inversion_count += 1
empty_pos = layout1.index(0)
# 计算逆序对奇偶性和空位行号奇偶性
return (inversion_count % 2) == ((empty_pos // order) % 2)
# 绘制数字华容道界面,包括数字边框和内部填充及数字位置精确调整
def draw_layout(layout1):
screen.fill(BLACK)
for i in range(order):
for j in range(order):
index1 = i * order + j
if layout1[index1] != 0:
font1 = pygame.font.SysFont(None, 48)
text1 = font1.render(str(layout1[index1]), 1, WHITE)
# 绘制边框,精确调整位置
pygame.draw.rect(screen, WHITE, (j * 100 + 15, i * 100 + 15, 70, 70), 1)
# 填充边框内区域
pygame.draw.rect(screen, GRAY, (j * 100 + 16, i * 100 + 16, 68, 68))
# 精确计算并设置数字位置
text_rect = text1.get_rect()
text_rect.centerx = j * 100 + 50
text_rect.centery = i * 100 + 50
screen.blit(text1, text_rect)
# 检查是否胜利
def check_win(layout1):
for i in range(order * order - 1):
if layout1[i] != i + 1:
return False
return True
# 获取可移动位置
def get_movable_positions(layout1):
empty_pos = layout1.index(0)
movable_positions = []
if empty_pos % order > 0:
movable_positions.append(empty_pos - 1)
if empty_pos % order < order - 1:
movable_positions.append(empty_pos + 1)
if empty_pos // order > 0:
movable_positions.append(empty_pos - order)
if empty_pos // order < order - 1:
movable_positions.append(empty_pos + order)
return movable_positions
# 移动数字
def move_number(layout1, pos1):
empty_pos = layout1.index(0)
layout1[empty_pos], layout1[pos1] = layout1[pos1], layout1[empty_pos]
# 主循环
layout = generate_solvable_layout(order)
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
col = pos[0] // 100
row = pos[1] // 100
index = row * order + col
if index in get_movable_positions(layout):
move_number(layout, index)
draw_layout(layout)
if check_win(layout):
font = pygame.font.SysFont(None, 64)
text = font.render("you win!", 1, WHITE)
screen.blit(text, (50, 150))
pygame.display.flip()
time.sleep(1) # 停留 1 秒
running = False
pygame.display.flip()
clock.tick(60)
# 退出程序
pygame.quit()