软件工程第二次个人作业
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/ |
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/homework/16718 |
| 这个作业的目标 | 使用Python和AIGC完成“一箭又一箭”小游戏 |
| 学号 | 102401625 |
| GitHub 仓库 | https://github.com/Ruiii1124/arrow-game |
一、项目展示
开始界面

游戏过程演示

结束界面

二、项目介绍
游戏规则
棋盘上分布若干箭头,方向为上、下、左、右。点击箭头时:
- 若其方向到边界之间没有其他箭头 → 飞出棋盘并消除;
- 若前方有箭头阻挡 → 不能消除,失误 +1;
- 每关 3 次失误,用尽即失败;
- 清空全部箭头即通关,进入下一关;
- 通关全部 3 关后显示胜利。
界面设计
- 开始界面:标题、玩法提示、“开始游戏”按钮。
- 游戏界面:顶部显示关卡、剩余箭头、剩余失误;中部为棋盘;左上角有“重新开始”按钮。
- 结果界面:显示“恭喜通关全部关卡”或“失败!失误次数用尽”,点击任意处返回开始。
主要功能
- 四种方向箭头显示与点击;
- 路径阻挡检测;
- 飞出动画与碰撞抖动反馈;
- 失误计数与胜负判断;
- 3 个可通关关卡;
- 重新开始功能。
特色
- 路径检测使用方向向量表,四个方向共用一段代码;
- 使用 pygame 时间参数实现飞出与抖动动画;
- 提供 pytest 自动化测试。
三、实现思路
1. 箭头与方向表示
用二维列表存储棋盘,每个格子为 None 或 0~3:
0=上 1=右 2=下 3=左
方向向量表:
DIRS = {0: (-1, 0), 1: (0, 1), 2: (1, 0), 3: (0, -1)}
2. 关卡表示
每个关卡是一个二维列表,例如:
[
[None, None, 1, None],
[None, 0, None, None],
[3, None, None, None],
[None, None, None, 1],
]
3. 路径检测(核心)
def can_fly(self, row, col):
d = self.grid[row][col]
dr, dc = DIRS[d]
r, c = row + dr, col + dc
while 0 <= r < self.rows and 0 <= c < self.cols:
if self.grid[r][c] is not None:
return False
r += dr
c += dc
return True
从当前格沿方向逐步前进,遇到非空格返回 False;越界说明畅通。
边界处理:循环条件 0 <= r < rows 保证不会数组越界。
4. 点击处理
def click(self, row, col):
if self.grid[row][col] is None:
return "empty"
if self.can_fly(row, col):
self.grid[row][col] = None
self.remaining -= 1
return "fly"
else:
self.mistakes += 1
return "block"
5. 动画与状态机
主循环采用 START / PLAY / RESULT 三状态机;
飞出动画记录起始格与方向,每帧按时间平移绘制;
碰撞抖动通过对 x 坐标叠加正弦偏移实现。
四、AIGC使用过程
| 子任务 | 借助何种 AIGC | AI 实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| 路径检测 | DeepSeek | 生成四方向检测代码 | 初版把方向用 if-elif 写四遍,且向上检测未处理边界 | 改为方向向量表 + while 循环,修复越界 |
| 关卡设计 | DeepSeek | 生成3个关卡数组 | 关卡2、3初版死锁,无法通关 | 手工重排,避免同行/同列方向相对,并逐关试玩验证 |
| 飞出/碰撞动画 | DeepSeek | 提供飞出平移与抖动动画思路 | 抖动幅度过大、飞出速度过快 | 调整幅度为 8px、时长 0.25s,飞出时长 1.2s |
| 界面布局 | DeepSeek | 给出 pygame 状态机框架 | 基本可用 | 调整字体回退逻辑,兼容中文显示 |
| 自动化测试 | DeepSeek | 生成 pytest 测试用例 | 覆盖飞,阻挡,胜负,重开 | 补充T06重开恢复测试 |
以上记录均来自开发过程中的真实对话,非事后虚构。
五、测试过程
运行 python main.py 启动游戏,按下列测试用例逐项手工验证:
- T01:进入关卡 1,点击边缘朝外的箭头,观察箭头是否飞出消失。
- T02:点击一个前方有阻挡的箭头,观察是否抖动、失误是否 +1。
- T03:点击棋盘边缘朝外的箭头,观察是否正常飞出且无报错。
- T04:按正确顺序清空关卡 1 全部箭头,观察是否自动进入关卡 2。
- T05:故意点击 3 次被阻挡的箭头,观察是否显示“失败”。
- T06:游戏中点击“重新开始”,观察箭头布局和失误次数是否恢复。
六、测试结果
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出并消失 | 与预期一致 | ✅ |
| T02 | 点击前方有阻挡的箭头 | 不消失,失误-1 | 与预期一致 | ✅ |
| T03 | 点击边缘朝外箭头 | 正常消失,无越界 | 与预期一致 | ✅ |
| T04 | 清空本关全部箭头 | 显示通关进入下一关 | 与预期一致 | ✅ |
| T05 | 失误次数耗尽 | 显示失败并可重开 | 与预期一致 | ✅ |
| T06 | 游戏进行中重新开始 | 布局与失误恢复 | 与预期一致 | ✅ |
同时编写了 test_game.py,使用 pytest 覆盖路径检测、失误累加、胜负判断与重开逻辑,全部通过。
运行命令:
python -m pytest test_game.py -v
七、PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1.0 | 1.0 | 0 |
| Python 与图形库学习 | 1.5 | 1.0 | -0.5 |
| 游戏界面实现 | 2.5 | 3.0 | +0.5 |
| 路径与碰撞逻辑实现 | 2.0 | 1.5 | -0.5 |
| 关卡设计 | 1.0 | 2.0 | +1.0 |
| AIGC 辅助开发 | 2.0 | 2.5 | +0.5 |
| 测试与修改 | 1.5 | 2.0 | +0.5 |
| README 与博客撰写 | 2.0 | 2.5 | +0.5 |
| 合计 | 13.5 | 15.5 | +2.0 |
八、心得体会
本次作业中,AIGC 工具在框架搭建、路径检测思路、动画实现和测试用例生成上给了我很大帮助,尤其是把“四个方向分别写检测”优化为“方向向量表 + while 循环”,代码量大幅减少。
但AI也存在明显不足:
- 关卡数据虽然语法正确,但常常无解,必须我自己逐个试玩验证;
- 动画参数AI给的值往往偏大,需要人工调参;
- 边界条件AI第一版没有处理好,需要自己补
0 <= r < rows。
通过本次实践,我理解了:
- 路径检测本质是沿方向向量的“射线步进”;
- 游戏状态机(开始/进行/结束)能让主循环结构清晰;
- AI 是加速器而不是替代品,理解并验证每一行代码才是关键。
最大的收获是:实现能读懂、能改、能讲清楚自己提交的代码,比代码本身更重要。
九、参考资料
- pygame 官方文档:https://www.pygame.org/docs/
- 方向向量与网格寻路基础概念(自整理)
- AIGC 工具:DeepSeek(对话辅助)

浙公网安备 33010602011771号