软件工程第二次作业
使用 Python 与 AIGC 完成“一箭又一箭”小游戏
一、作业基本信息
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 202601软件工程 |
| 这个作业要求在哪里 | 2026秋软件工程个人作业(第二次) |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏 |
| 学号 | 102401615 |
| GitHub 仓库 | ArrowEscapeGame |
二、项目展示
“一箭又一箭”是一款方格箭头消除游戏。棋盘中的每个非空方格包含一个上、下、左或右方向的箭头。玩家点击箭头后,程序会检查箭头前方直到棋盘边界之间是否存在其他箭头。
- 前方没有阻挡:箭头沿自身方向飞出棋盘并消失;
- 前方存在阻挡:箭头不能消失,扣除一次失误机会;
- 清空本关全部箭头:显示通关界面并进入下一关;
- 失误次数耗尽:显示失败界面,可以重新开始。
项目包含开始界面、关卡选择界面、游戏界面以及通关/失败界面。游戏界面会显示当前关卡、剩余箭头数量、剩余失误次数、得分、用时以及重新开始按钮。
2.1 开始界面

2.2 游戏过程

2.3 通关与失败界面


2.4 游玩画面显示

三、项目介绍
3.1 游戏规则
玩家使用鼠标点击箭头所在方格。程序根据箭头方向检查同一行或同一列中位于它前方的所有方格。如果全部为空,箭头可以离开;如果其中任意方格仍有箭头,则本次操作判定为碰撞。
每关开始时有 3 次失误机会。成功消除箭头可以获得分数,错误点击会扣分并减少一次机会。清空全部箭头后,根据剩余机会和是否使用辅助功能给出星级评价。
3.2 主要功能
基础功能包括:
- 正常显示和操作的图形化界面;
- 上、下、左、右四种箭头;
- 鼠标点击选择箭头;
- 四个方向的路径判断;
- 无阻挡时消除箭头;
- 有阻挡时给出碰撞反馈并扣除失误次数;
- 5 个可以正常通关的关卡以及可以随机生成关卡;
- 通关、失败、下一关和重新开始流程。
在基础功能上,我选择实现了以下 7 项扩展:
- 更多关卡和关卡选择;
- 得分、计时和星级评价;
- 提示功能;
- 撤销上一步;
- 保存游戏进度;
- 随机生成可通关关卡;
- 自动求解当前关卡。
3.3 开发环境与运行方法
本项目使用以下环境开发:
- Windows;
- Python 3.12.10 64 位;
- Pygame 2.6.1;
- Visual Studio。
安装 Pygame:
py -3.12 -m pip install pygame
运行项目:
py -3.12 ArrowEscapeGame.py
四、实现思路
4.1 棋盘和箭头表示
棋盘使用二维列表表示。每个元素只有五种可能值:
"U":向上;"D":向下;"L":向左;"R":向右;None:空方格。
四个方向对应的行列增量为:
DIRECTIONS = {
"U": (-1, 0),
"D": (1, 0),
"L": (0, -1),
"R": (0, 1),
}
这种表示方法使绘图、点击定位和路径判断都可以使用统一的行列坐标。
4.2 路径检测
路径检测是本项目的核心。程序从箭头相邻的方格开始,按照方向增量逐格向前移动:
def path_is_clear(board, row, col, direction):
dr, dc = DIRECTIONS[direction]
row += dr
col += dc
while 0 <= row < len(board) and 0 <= col < len(board):
if board[row][col] is not None:
return False
row += dr
col += dc
return True
如果循环中遇到非空格子,立即返回 False;如果坐标越过边界仍未遇到箭头,则返回 True。这个方法同时适用于四个方向,也能正确处理位于边缘且朝向棋盘外的箭头。
4.3 飞出与碰撞反馈
路径畅通时,程序先把对应棋盘元素改为 None,再保存箭头的当前位置和方向。每帧根据经过时间更新箭头坐标,直到整支箭头越过棋盘边界。路径受阻时,箭头会短暂变红并晃动,同时剩余失误次数减 1。
图形动画和棋盘逻辑相互分离,可以避免动画尚未结束时重复点击导致状态混乱。
4.4 游戏状态与界面
程序使用状态变量区分不同页面:
menu → select → playing → won / lost
menu:开始界面;select:关卡选择;playing:游戏进行中;won:通关界面;lost:失败界面。
事件处理、状态更新和界面绘制分别放在不同方法中,使程序结构更清晰。
4.5 可通关关卡的生成
随机放置箭头可能形成没有任何箭头能够离开的死局。为避免这一问题,程序采用逆向构造方法:逐个放入箭头时,只选择当前前方没有阻挡的方向。
假设箭头的放入顺序为 A、B、C,那么按照 C、B、A 的顺序移除时,每一个箭头都至少存在一条已验证的离开路径。因此生成的关卡一定存在可通关顺序。开发过程中还批量生成并求解了不同尺寸的测试棋盘,用于检查算法是否出现死局。
4.6 提示、撤销、存档和自动求解
- 提示:搜索当前所有
path_is_clear为真的箭头,并高亮其中一个; - 撤销:操作前保存棋盘、生命值和得分的副本,撤销时恢复;
- 存档:将当前棋盘和进度保存为 JSON,重新运行时可以继续;
- 自动求解:反复搜索当前可以离开的箭头并执行,直到棋盘清空。
五、AIGC 辅助开发过程
本项目使用 ChatGPT/Codex 进行辅助开发。AIGC 主要用于分析需求、提供代码思路和排查问题,最终游戏规则、代码取舍和测试结果由我确认。以下记录来自实际开发过程。
5.1 第一次:开发环境与编码问题
| 项目 | 内容 |
|---|---|
| 子任务 | 配置 Python、Pygame 和 Visual Studio 开发环境 |
| 使用工具 | ChatGPT/Codex |
| 我提出的要求 | 在 Visual Studio 中运行 Python 图形游戏,并解决解释器和中文代码报错 |
| AI 提供的内容 | 建议安装 Python 3.12 64 位和 Pygame;分析 No Python interpreters found;指出源文件需要使用 UTF-8 编码 |
| 实际效果 | Python 和 Pygame 安装成功,程序窗口能够正常打开 |
| 人工修改 | 将源文件保存为 UTF-8;把系统字体调用改为读取可用字体,避免字体兼容异常 |
5.2 第二次:纠正游戏规则和界面理解
| 项目 | 内容 |
|---|---|
| 子任务 | 确认箭头的显示形式与核心玩法 |
| 使用工具 | ChatGPT/Codex |
| 我提出的要求 | 根据作业要求实现点击箭头、判断前方阻挡和清空棋盘 |
| AI 提供的内容 | 初期曾把题目理解成传统迷宫人物游戏,后来又尝试过长路线箭头方案 |
| 实际效果 | 初期方案与题目示例不一致 |
| 人工修改 | 我重新审题并提供清晰截图,明确要求采用“方格中放置短箭头”的形式,最终重构棋盘和箭头表示 |
这一过程让我认识到,AIGC 给出的方案必须结合原始题目逐条检查,不能只看程序能否运行。
5.3 第三次:四方向路径判断
| 项目 | 内容 |
|---|---|
| 子任务 | 实现箭头前方路径检测 |
| 使用工具 | ChatGPT/Codex |
| 我提出的要求 | 四个方向都要能判断阻挡,边缘箭头不能发生数组越界 |
| AI 提供的内容 | 使用方向增量表统一处理上、下、左、右,并逐格检查到棋盘边界 |
| 实际效果 | 基本逻辑可用,能够区分可消除与受阻箭头 |
| 人工修改 | 根据实际点击结果检查方向和边界条件,并在最终代码中将棋盘逻辑与动画分离 |
5.4 第四次:关卡生成与完整功能整合
| 项目 | 内容 |
|---|---|
| 子任务 | 设计多关卡并整合附加功能 |
| 使用工具 | ChatGPT/Codex |
| 我提出的要求 | 至少 3 关可正常通关,并选择 5~7 项扩展功能完成 |
| AI 提供的内容 | 逆向构造可通关棋盘;整合选关、计时计分、提示、撤销、存档、随机关卡和自动求解 |
| 实际效果 | 完整程序可以运行并能够通关 |
| 人工修改 | 我在 Visual Studio 中完整复制运行,对界面和通关流程进行测试,并继续记录发现的问题 |
六、项目测试
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 箭头沿自身方向飞出,剩余箭头数量减1 | 通过 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数减1 | 箭头保留并出现红色晃动反馈,剩余失误次数减1 | 通过 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 正常消失,不发生数组越界 | 箭头正常飞出,程序未报错或闪退 | 通过 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 清空棋盘后显示通关界面,可以进入下一关 | 通过 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 3次机会耗尽后显示失败界面,可以重新挑战 | 通过 |
| T06 | 游戏进行中重新开始 | 箭头布局、得分和失误次数恢复 | 棋盘恢复初始布局,得分、计时和失误次数重新计算 | 通过 |
| T07 | 使用提示功能 | 高亮一个当前可消除的箭头 | 点击提示后,一个可消除箭头显示金色边框 | 通过 |
| T08 | 撤销上一步 | 恢复操作前的棋盘、得分和机会 | 撤销后箭头和操作前的游戏数据均正确恢复 | 通过 |
| T09 | 关闭程序后继续游戏 | 恢复保存的棋盘和进度 | 重新运行并选择继续游戏后,棋盘和进度正确恢复 | 通过 |
| T10 | 自动求解固定或随机关卡 | 自动清空棋盘并显示通关 | 程序依次消除可用箭头,最终清空棋盘并显示通关 | 通过 |
七、PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1.0 | 1.0 | 0 |
| Python 与图形库学习 | 0.5 | 1.0 | +0.5 |
| 游戏界面实现 | 1.0 | 1.5 | +0.5 |
| 路径与碰撞逻辑实现 | 3.0 | 1.5 | -1.5 |
| 关卡设计 | 2.0 | 0.5 | -0.5 |
| AIGC 辅助开发 | 1.5 | 1.0 | -0.5 |
| 测试与修改 | 1.0 | 1.0 | 0 |
| README 与博客撰写 | 1.5 | 1.5 | 0 |
| 合计 | 11.5 | 10.0 | -1.5 |
八、项目心得体会
这次作业让我第一次比较完整地经历了从需求理解、环境配置、代码实现到测试和文档整理的过程。最开始,我对游戏示例理解得不够准确,导致实现方向出现偏差。虽然早期版本也能运行,但并不符合题目要求。重新阅读任务说明后,我把长路线箭头改成了方格短箭头,并重新设计棋盘结构和路径判断。
AIGC 在配置环境、解释错误和提供代码框架方面提高了开发效率。例如,解释器未识别、文件编码错误和字体调用异常都可以通过错误信息快速定位。但 AIGC 也可能在信息不完整时做出错误假设,因此我需要根据题目截图和实际运行效果进行审核,而不能直接接受所有输出。
在程序实现方面,我对二维列表、鼠标事件、游戏状态切换和路径检测有了更具体的理解。路径判断代码本身不长,但必须认真处理四个方向和棋盘边界。加入提示、撤销、存档和自动求解后,我也认识到功能越多,越需要把棋盘逻辑、动画和界面状态分开管理。
最大的收获不是让 AI 一次生成完整程序,而是学会明确提出要求、验证结果、指出错误并不断修改。最终提交的代码仍需要由我本人运行、测试和解释,这也是使用 AIGC 完成软件项目时最重要的责任。

浙公网安备 33010602011771号