用Pygame和PyTorch复刻经典AI实验:手把手教你搭建自己的Wumpus世界(Python 3.7环境) 用Pygame和PyTorch构建Wumpus世界从零实现经典AI实验在人工智能教学领域Wumpus世界一直被视为理解智能体决策过程的黄金标准。这个看似简单的洞穴探险游戏实则包含了感知、推理、规划等AI核心概念。本文将带你用Python 3.7环境结合Pygame 2.1.2和PyTorch 1.13.0完整复现这个经典实验。1. 环境准备与项目架构1.1 开发环境配置首先确保已安装Python 3.7.x版本。建议使用conda创建独立环境conda create -n wumpus python3.7 conda activate wumpus安装所需依赖库pip install pygame2.1.2 torch1.13.0 numpy1.18.5项目目录结构建议如下wumpus-world/ ├── assets/ # 存放游戏素材 │ ├── wumpus.png │ ├── gold.png │ └── pit.png ├── world.py # 游戏世界逻辑 ├── agent.py # 智能体实现 ├── dqn_trainer.py # 强化学习训练 └── main.py # 主入口文件1.2 核心类设计我们需要三个基础类来构建游戏世界class GameObject: 游戏对象基类 def __init__(self, x, y): self.x x self.y y self.visible False class Room: 洞穴房间实现 def __init__(self, x, y): self.x x self.y y self.has_wumpus False self.has_pit False self.has_gold False self.visited False2. 游戏世界构建2.1 世界初始化逻辑World类负责管理整个游戏状态class World: def __init__(self, size4): self.size size self.grid [[Room(x, y) for y in range(size)] for x in range(size)] self.agent_pos (0, 0) self.agent_has_gold False self.agent_has_arrow True self.game_over False # 随机放置危险和奖励 self._place_objects()关键初始化方法def _place_objects(self): 随机放置Wumpus、陷阱和黄金 locations self._get_random_locations(3) self.wumpus_pos locations[0] self.pit_pos locations[1] self.gold_pos locations[2] # 更新房间状态 self.grid[self.wumpus_pos[0]][self.wumpus_pos[1]].has_wumpus True self.grid[self.pit_pos[0]][self.pit_pos[1]].has_pit True self.grid[self.gold_pos[0]][self.gold_pos[1]].has_gold True2.2 感知系统实现智能体通过有限感知了解环境感知信号触发条件臭气(Stench)邻近Wumpus所在房间微风(Breeze)邻近无底洞房间金光(Glitter)当前房间有黄金撞击(Bump)撞到墙壁嚎叫(Scream)Wumpus被射杀实现代码示例def get_percepts(self): x, y self.agent_pos percepts [] # 检查当前房间 if self.grid[x][y].has_gold: percepts.append(Glitter) # 检查相邻房间 neighbors self._get_neighbors(x, y) for nx, ny in neighbors: if self.grid[nx][ny].has_wumpus: percepts.append(Stench) if self.grid[nx][ny].has_pit: percepts.append(Breeze) return percepts3. 智能体决策系统3.1 基于规则的决策逻辑基础智能体可以采用if-then规则class RuleBasedAgent: def decide_action(self, percepts): if Glitter in percepts: return Grab elif Stench in percepts and self.has_arrow: return Shoot elif self.safe_rooms: return Move else: return Turn3.2 强化学习实现使用PyTorch构建DQN网络import torch import torch.nn as nn class DQN(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(DQN, self).__init__() self.fc1 nn.Linear(input_size, hidden_size) self.fc2 nn.Linear(hidden_size, hidden_size) self.fc3 nn.Linear(hidden_size, output_size) def forward(self, x): x torch.relu(self.fc1(x)) x torch.relu(self.fc2(x)) return self.fc3(x)奖励函数设计def get_reward(self, action): reward -1 # 默认行动代价 if self.agent_has_gold and self.agent_pos (0, 0): reward 1000 # 成功带黄金逃脱 elif self.game_over and not self.agent_has_gold: reward - 1000 # 死亡惩罚 elif action Shoot: reward - 10 # 射箭代价 return reward4. Pygame可视化实现4.1 游戏界面构建初始化Pygame显示import pygame class WumpusVisualizer: def __init__(self, world_size4, cell_size100): pygame.init() self.cell_size cell_size self.screen pygame.display.set_mode( (world_size * cell_size, world_size * cell_size)) pygame.display.set_caption(Wumpus World) # 加载素材 self.images { wumpus: pygame.image.load(assets/wumpus.png), gold: pygame.image.load(assets/gold.png), pit: pygame.image.load(assets/pit.png) }4.2 游戏主循环def run_game(self): clock pygame.time.Clock() running True while running: for event in pygame.event.get(): if event.type pygame.QUIT: running False elif event.type pygame.KEYDOWN: self._handle_key_event(event) self._draw_world() pygame.display.flip() clock.tick(30) pygame.quit()5. 常见问题与调试技巧5.1 典型错误解决方案错误类型可能原因解决方案图片加载失败路径错误或文件缺失使用绝对路径或检查assets目录智能体卡死决策逻辑缺陷添加随机探索机制训练不收敛奖励设计不合理调整奖励函数参数内存泄漏未正确释放资源使用del显式释放对象5.2 性能优化建议状态表示压缩使用位掩码表示房间状态经验回放实现Replay Buffer存储训练样本并行训练使用多环境同时收集数据可视化调试添加调试信息覆盖层# 示例状态压缩表示 def get_state_representation(self): state 0 if self.has_wumpus: state | 0b0001 if self.has_pit: state | 0b0010 if self.has_gold: state | 0b0100 if self.visited: state | 0b1000 return state6. 项目扩展方向多智能体协作添加多个智能体共同探索动态环境实现移动的Wumpus和变化的地形高级感知添加视觉输入替代简单感知信号混合决策结合规则系统和强化学习实现动态Wumpus的示例代码def move_wumpus(self): if random.random() 0.3: # 30%概率移动 current_x, current_y self.wumpus_pos neighbors self._get_neighbors(current_x, current_y) new_pos random.choice(neighbors) self._update_wumpus_position(new_pos)在完成基础版本后可以尝试添加更多游戏元素如多种武器系统时间限制机制能量消耗系统地图编辑器功能