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.mzph.cn/news/925233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何找出集合的两个子集使得和相等?

给定一个大小为 \(n\) 的整数集合 \(S\subseteq [0,V]\),找出他的两个子集 \(s_1,s_2\) 使得其元素的和相等,或报告无解。对于所有的 \(T\subseteq S\),\(T\) 中元素的和满足 \(0\le \sum_{x\in T} x\le V|T|\)。 所…

Python语言自动玩游戏的俄罗斯方块游戏程序代码QZQ

import randomimport mathimport sysimport numpy as npimport pygame # -------------------- 常量 --------------------CELL = 30 # 像素COLS, ROWS = 10, 20SCREEN_W, SCREEN_H = 20 * CELL, ROWS * CELLFPS = 60…

Spring AI(七)Spring AI 的RAG搭建集合火山向量模型+阿里云Tair(企业版)

Spring AI(七)Spring AI 的RAG搭建集合火山向量模型+阿里云Tair(企业版)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fami…

sw网站建设合肥网站seo服务

前言-什么是数据幻觉&#xff1f;它到底有什么危害呢 我们直接来举例&#xff1a; 我是金银花一区的&#xff0c;附近有什么小学&#xff1f; 此时RAG带出如下信息&#xff1a; 金银花小区一区、二区、三区附近教育资源有&#xff1a;银树大学、建设小学金银花校区、金树高…

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

import sysimport randomimport pygame # 初始化pygamepygame.init() # 游戏常量SIZE = 3 # 3x3 拼图CELL = 120 # 每个格子的像素大小WIDTH = CELL * SIZEHEIGHT = CELL * SIZEEMPTY = SIZE * SIZE # 空格的表示值…

温州网站开发培训北京网站制作外包

http://blog.csdn.net/dandelion_gong/article/details/51673085 Unix下可用的I/O模型一共有五种&#xff1a;阻塞I/O 、非阻塞I/O 、I/O复用 、信号驱动I/O 、异步I/O。此处我们主要介绍第三种I/O符复用。 I/O复用的功能&#xff1a;如果一个或多个I/O条件满足&#xff08;输…

看动漫什么网站好企业网站的分类有哪三种

目录&#xff1a;系统学习 Java IO---- 目录&#xff0c;概览 PipedInputStream 类使得可以作为字节流读取管道的内容。 管道是同一 JVM 内的线程之间的通信通道。 使用两个已连接的管道流时&#xff0c;要为每个流操作创建一个线程&#xff0c; read() 和 write() 都是阻塞方法…

浙江自己如何做网站鹰潭手机网站建设

xin3721网络学院为广大学员&#xff0c;准备了丰富了教学视频。为了更好的让大学配合视频进行学习&#xff0c;拓展学员的知识面&#xff0c;我站特整理了大量的&#xff0c;技术文章&#xff0c;供学员参考。因此本教案需配合视频教程学习&#xff0c;视频教程地址为&#xff…

赛前训练4 字符串哈希

A 显然长度具有单调性,于是二分长度+map存储哈希值判断即可。实现 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <…

wordpress企业网站建设智慧农业项目方案

EventBus是android 下高效的发布/订阅事件总线机制&#xff0c;可以代替传统的Intent&#xff0c;Handler&#xff0c;BroadCast 或者Fragment&#xff0c;Activity&#xff0c;Service&#xff0c;线程之间传递数据&#xff0c;是一种发布订阅设计模式&#xff08;观察者模式&…

上海著名的网站制作公司杭州网站商场开发

美术教案第三课:曲曲直直(三年级美术下册教案)教学目标:认知目标:能够认识生活中的各种曲线和直线,说说曲线、直线给自己的感受.能力目标:能够用绘画、剪贴等方法表现曲线和直线的画面,培养学生自主探究的能力和创造能力.情感目标:通过收集不同直线、曲线材料进行创作,培养学生…

处处吻

你爱热吻却永不爱人 练习为乐但是怕熟人 你爱路过去索取见闻 陌路人变得必有份好感 你热爱别离 再合再离 似花瓣献技 叫花粉遍地 噢噢 你在播弄这穿线游戏 跟他结束 他与她再一起 你小心 一吻便颠倒众生 一吻便救一个人…

ThreadLocal原理与使用详解

ThreadLocal原理与使用详解 一、ThreadLocal 介绍 1.1 定义与核心特性定义:Java 官方文档描述,ThreadLocal 类用于提供线程内部的局部变量,多线程环境下通过 get() 和 set() 方法访问时,能保证各线程变量相对独立于…

WinCC监控框架实战解析:打通物联网网关的关键步骤

WinCC监控框架实战解析:打通物联网网关的关键步骤pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

2025国庆Day1

模拟赛 T1 对h离散化,枚举x,分类讨论某些位置淹没后段的个数的变化情况即可 可恶的毒瘤出题人竟然造了一个高度全0的hack 注意特判此时答案为0 #include<iostream> #include<cstdio> #include<cstdli…

网站内部链接有什么作用wordpress极慢

1005 K 次取反后最大化的数组和 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数组 可能…

2025 年包装印刷厂家 TOP 企业品牌推荐排行榜,西安,陕西,咸阳包装印刷,礼盒,定制,设计,优质,品质,环保,生产包装印刷公司推荐!

引言在当前包装印刷行业发展进程中,企业面临着诸多亟待解决的问题。一方面,部分企业设备陈旧,难以满足市场对高精度、高质量包装印刷产品的需求,色彩还原度不足、套印偏差等问题频发,影响产品外观质感与品牌形象;…

python-dotenv正则表达式应用:麻烦变量名的匹配技巧

python-dotenv正则表达式应用:麻烦变量名的匹配技巧2025-10-02 18:54 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; dis…