当前位置: 首页 > news >正文

Python语言自动玩游戏的数字拼图游戏程序代码ZXQMQZQ

import pygame
import sys
import random
import time
from queue import PriorityQueue
from pygame.locals import *

# 初始化pygame
pygame.init()

# 游戏常量
WIDTH, HEIGHT = 400, 500
GRID_SIZE = 3
TILE_SIZE = 100
MARGIN = 5
FPS = 60

# 颜色定义
BACKGROUND = (240, 240, 240)
GRID_COLOR = (200, 200, 200)
TILE_COLOR = (70, 130, 180)
TEXT_COLOR = (255, 255, 255)
HIGHLIGHT_COLOR = (100, 160, 210)
INFO_COLOR = (50, 50, 50)

# 中文数字
CHINESE_NUMBERS = ["1", "2", "3", "4", "5", "6", "7", "8", ""]

# 创建游戏窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("数字拼图游戏")
clock = pygame.time.Clock()

# 字体
font = pygame.font.SysFont('simhei', 24)
small_font = pygame.font.SysFont('simhei', 18)


class PuzzleGame:
def __init__(self):
self.reset_game()
self.mode = "manual" # "manual" 或 "ai"
self.ai_speed = 0.3 # AI移动速度(秒)
self.last_ai_move = 0
self.moving_tile = None
self.move_start_pos = None
self.move_target_pos = None
self.move_start_time = 0
self.move_duration = 0.2 # 移动动画持续时间(秒)

def reset_game(self):
# 创建初始拼图状态(已解决状态)
self.board = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
self.empty_pos = (2, 2) # 空白块位置

# 随机打乱拼图
self.shuffle_board(50)
self.moves = 0
self.start_time = time.time()
self.ai_solving = False
self.solution_path = []
self.current_step = 0
self.moving_tile = None # 重置移动动画状态

def shuffle_board(self, moves=50):
# 通过随机移动来打乱拼图
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 右, 下, 左, 上

# 先重置到完成状态
self.board = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
self.empty_pos = (2, 2)

for _ in range(moves):
valid_moves = []
r, c = self.empty_pos

for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < GRID_SIZE and 0 <= nc < GRID_SIZE:
valid_moves.append((dr, dc))

if valid_moves:
dr, dc = random.choice(valid_moves)
self.swap_tiles(r + dr, c + dc, r, c) # 交换空白块和相邻块

def swap_tiles(self, r1, c1, r2, c2):
# 交换两个拼图块
self.board[r1][c1], self.board[r2][c2] = self.board[r2][c2], self.board[r1][c1]
self.empty_pos = (r1, c1) # 更新空白块位置

def move_tile(self, r, c):
# 检查是否可以移动拼图块(只能移动与空白块相邻的块)
er, ec = self.empty_pos
if (abs(r - er) == 1 and c == ec) or (abs(c - ec) == 1 and r == er):
# 设置移动动画
self.moving_tile = (r, c)
self.move_start_pos = (c * (TILE_SIZE + MARGIN) + MARGIN,
r * (TILE_SIZE + MARGIN) + MARGIN)
self.move_target_pos = (ec * (TILE_SIZE + MARGIN) + MARGIN,
er * (TILE_SIZE + MARGIN) + MARGIN)
self.move_start_time = time.time()

# 实际交换拼图块
self.swap_tiles(r, c, er, ec)
self.moves += 1
return True
return False

def is_solved(self):
# 检查拼图是否已解决
solved = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
return self.board == solved

def draw(self, screen):
# 绘制背景
screen.fill(BACKGROUND)

# 绘制拼图网格
for r in range(GRID_SIZE):
for c in range(GRID_SIZE):
rect = pygame.Rect(
c * (TILE_SIZE + MARGIN) + MARGIN,
r * (TILE_SIZE + MARGIN) + MARGIN,
TILE_SIZE,
TILE_SIZE
)

# 跳过空白块(不绘制)
if self.board[r][c] == 0:
pygame.draw.rect(screen, GRID_COLOR, rect)
continue

# 绘制拼图块
pygame.draw.rect(screen, TILE_COLOR, rect, border_radius=5)

# 绘制数字
number_text = CHINESE_NUMBERS[self.board[r][c] - 1]
text_surface = font.render(number_text, True, TEXT_COLOR)
text_rect = text_surface.get_rect(center=rect.center)
screen.blit(text_surface, text_rect)

# 绘制移动动画
if self.moving_tile and time.time() - self.move_start_time < self.move_duration:
progress = (time.time() - self.move_start_time) / self.move_duration
progress = min(1.0, progress)

# 计算当前位置
current_x = self.move_start_pos[0] + (self.move_target_pos[0] - self.move_start_pos[0]) * progress
current_y = self.move_start_pos[1] + (self.move_target_pos[1] - self.move_start_pos[1]) * progress

# 绘制移动中的拼图块
rect = pygame.Rect(current_x, current_y, TILE_SIZE, TILE_SIZE)
pygame.draw.rect(screen, HIGHLIGHT_COLOR, rect, border_radius=5)

# 绘制数字(使用移动前的数字)
r, c = self.moving_tile
number_value = self.board[self.empty_pos[0]][self.empty_pos[1]] # 移动后的空白块位置是原来的数字
number_text = CHINESE_NUMBERS[number_value - 1]
text_surface = font.render(number_text, True, TEXT_COLOR)
text_rect = text_surface.get_rect(center=rect.center)
screen.blit(text_surface, text_rect)
else:
self.moving_tile = None

# 绘制游戏信息
elapsed_time = time.time() - self.start_time
time_text = f"时间: {int(elapsed_time)}秒"
moves_text = f"移动步数: {self.moves}"
mode_text = f"模式: {'人工操作' if self.mode == 'manual' else 'AI自动'}"
help_text = "F1 切换模式 | F2 重置游戏"

time_surface = small_font.render(time_text, True, INFO_COLOR)
moves_surface = small_font.render(moves_text, True, INFO_COLOR)
mode_surface = small_font.render(mode_text, True, INFO_COLOR)
help_surface = small_font.render(help_text, True, INFO_COLOR)

screen.blit(time_surface, (10, HEIGHT - 120))
screen.blit(moves_surface, (10, HEIGHT - 90))
screen.blit(mode_surface, (10, HEIGHT - 60))
screen.blit(help_surface, (10, HEIGHT - 30))

# 如果AI正在解谜,显示进度
if self.ai_solving and self.solution_path:
progress_text = f"AI解谜进度: {self.current_step}/{len(self.solution_path)}"
progress_surface = small_font.render(progress_text, True, INFO_COLOR)
screen.blit(progress_surface, (WIDTH // 2 - 60, HEIGHT - 60))

def handle_key(self, key):
if key == K_F1:
self.mode = "ai" if self.mode == "manual" else "manual"
print(f"切换到{self.mode}模式")
if self.mode == "ai" and not self.ai_solving:
self.start_ai_solve()
elif key == K_F2:
print("重置游戏")
self.reset_game()

def handle_click(self, pos):
# 检查是否点击了拼图块
x, y = pos
if y < GRID_SIZE * (TILE_SIZE + MARGIN) + MARGIN:
c = x // (TILE_SIZE + MARGIN)
r = y // (TILE_SIZE + MARGIN)

if 0 <= r < GRID_SIZE and 0 <= c < GRID_SIZE and self.board[r][c] != 0:
self.move_tile(r, c)

def start_ai_solve(self):
# 开始AI解谜
self.ai_solving = True
self.solution_path = self.solve_puzzle()
self.current_step = 0
self.last_ai_move = time.time()
if self.solution_path:
print(f"AI找到解决方案,共{len(self.solution_path)}步")
else:
print("AI未找到解决方案")
self.ai_solving = False

def solve_puzzle(self):
# 使用A*算法解决拼图
goal_state = ((1, 2, 3), (4, 5, 6), (7, 8, 0))

# 将当前状态转换为元组
start_state = tuple(tuple(row) for row in self.board)

# 定义启发式函数(曼哈顿距离)
def heuristic(state):
distance = 0
for r in range(GRID_SIZE):
for c in range(GRID_SIZE):
if state[r][c] != 0:
# 目标位置
target_r = (state[r][c] - 1) // GRID_SIZE
target_c = (state[r][c] - 1) % GRID_SIZE
distance += abs(r - target_r) + abs(c - target_c)
return distance

# 定义移动方向
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]

# 初始化优先队列
open_set = PriorityQueue()
open_set.put((heuristic(start_state), 0, start_state, [])) # (f, g, state, path)

# 记录访问过的状态
visited = set()
visited.add(start_state)

while not open_set.empty():
f, g, current, path = open_set.get()

if current == goal_state:
return path # 返回移动路径

# 找到空白块的位置
empty_r, empty_c = 0, 0
for r in range(GRID_SIZE):
for c in range(GRID_SIZE):
if current[r][c] == 0:
empty_r, empty_c = r, c
break

# 生成可能的移动
for dr, dc in directions:
nr, nc = empty_r + dr, empty_c + dc
if 0 <= nr < GRID_SIZE and 0 <= nc < GRID_SIZE:
# 创建新状态
new_state = [list(row) for row in current]
new_state[empty_r][empty_c], new_state[nr][nc] = new_state[nr][nc], new_state[empty_r][empty_c]
new_state = tuple(tuple(row) for row in new_state)

if new_state not in visited:
visited.add(new_state)
new_g = g + 1
new_f = new_g + heuristic(new_state)
new_path = path + [(nr, nc)] # 记录移动的拼图块位置
open_set.put((new_f, new_g, new_state, new_path))

return [] # 无解

def ai_move(self):
# AI自动移动
current_time = time.time()
if current_time - self.last_ai_move >= self.ai_speed and self.solution_path:
if self.current_step < len(self.solution_path):
# 获取下一步移动
r, c = self.solution_path[self.current_step]
self.move_tile(r, c)
self.current_step += 1
self.last_ai_move = current_time
print(f"AI移动第{self.current_step}步")

# 检查是否完成
if self.current_step >= len(self.solution_path):
self.ai_solving = False
print("AI完成拼图!")


# 创建游戏实例
game = PuzzleGame()

# 主游戏循环
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
game.handle_key(event.key)
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
if game.mode == "manual":
game.handle_click(event.pos)

# AI自动移动
if game.mode == "ai" and game.ai_solving:
game.ai_move()

# 绘制游戏
game.draw(screen)

# 检查是否完成
if game.is_solved():
solved_text = font.render("拼图完成!", True, (0, 150, 0))
text_rect = solved_text.get_rect(center=(WIDTH // 2, HEIGHT - 150))
screen.blit(solved_text, text_rect)

pygame.display.flip()
clock.tick(FPS)

pygame.quit()
sys.exit()

http://www.hskmm.com/?act=detail&tid=23094

相关文章:

  • 如何找出集合的两个子集使得和相等?
  • Python语言自动玩游戏的俄罗斯方块游戏程序代码QZQ
  • Spring AI(七)Spring AI 的RAG搭建集合火山向量模型+阿里云Tair(企业版)
  • Python语言自动玩游戏的数字拼图游戏程序代码QZQ
  • 赛前训练4 字符串哈希
  • 英语
  • 处处吻
  • ThreadLocal原理与使用详解
  • WinCC监控框架实战解析:打通物联网网关的关键步骤
  • 2025国庆Day1
  • 2025 年包装印刷厂家 TOP 企业品牌推荐排行榜,西安,陕西,咸阳包装印刷,礼盒,定制,设计,优质,品质,环保,生产包装印刷公司推荐!
  • 2025 绝对式编码器厂家 TOP 企业品牌推荐排行榜,增量绝对式编码器,多圈绝对式编码器,二进制绝对式编码器 /ssi 绝对式编码器,拉线绝对式编码器公司推荐!
  • 2025 编码器厂家 TOP 企业品牌推荐排行榜,无磁,光学,脉冲,绝对型,伺服,机械多圈,工业,二进制,拉线编码器公司推荐
  • 2025 年玻璃钢水箱厂家 TOP 企业品牌推荐排行榜,30 吨,订做,消防,专业,方形,拼装式,屋顶,大型玻璃钢水箱推荐这十家公司!
  • 禁止DataGridView自动根据数据源的结构生成列
  • 2025 年压球机厂家 TOP 企业品牌推荐排行榜,新型,高压,节能,双螺旋干粉,对辊,煤粉,超低压压球机公司推荐!
  • 2025 年磨粉机厂家 TOP 企业品牌推荐排行榜,新型磨粉机,超细磨粉机,立式双动力磨粉机,节能磨粉机公司推荐!
  • 2025 年等离子清洗机厂家 TOP 企业品牌推荐排行榜,大气,真空,宽幅,微波,自动化,常压,低温,大腔体,射频,DBD,介质阻挡放电等离子清洗机公司推荐!
  • 完整教程:如何优雅的布局,height: 100% 的使用和 flex-grow: 1 的 min-height 陷阱
  • MyBatis缓存架构深度拆解:从PerpetualCache的LRU陷阱到Redis分布式二级缓存防穿透实战 - 详解
  • 2025柔版印刷机厂家 TOP 企业品牌推荐排行榜,塑编袋,编织袋,阀口袋,重包膜,机组式,卫星式,不换版,FFS 重载膜,水泥袋柔版印刷机公司推荐!
  • 9 30 -
  • Spring 基础核心 - SpringMVC 入门与请求流程
  • (数据结构)链表OJ——刷题练习 - 实践
  • 阿尔法开发板移植ov5640时候一个小的注意事项
  • 使用kraken2 命令对重测序数据进行物种分类
  • 2025/10/2
  • 重测序数据fastp数据质控及fastQC质量评估
  • 8. Spring AI tools/function-call - 教程
  • electron 安装失败