软件工程第二次个人作业
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 202601 软件工程 |
| 这个作业要求在哪里 | 第二次个人作业要求 |
| 这个作业的目标 | 使用 Python 与 AIGC 从零实现“一箭又一箭”箭头益智小游戏 |
| 学号 | 102401505 |
| GitHub 仓库 | StarrLin7/yijian-you-yijian |
AIGC 声明: 本文的梳理、代码结构建议和文字初稿使用了 Codex 辅助;我根据作业要求运行、检查并整理了界面截图和测试结果。
一、项目展示
本项目从零使用 Python 标准库 Tkinter 编写,正式名称为 一箭又一箭。棋盘为 6×6,共设计 3 个固定关卡。玩家点击箭头后,程序检查它指向的路径:没有障碍时箭头离开棋盘;有障碍时显示碰撞提示并扣除一次机会。
1. 欢迎界面

欢迎页说明了游戏目标和三次机会的规则,点击“开始旅程”进入第一关。
2. 6×6 游戏棋盘

游戏页同时显示当前关卡、剩余箭头、剩余机会和重新本关按钮。四个方向的箭头使用不同颜色,便于初学者观察路径。
3. 碰撞反馈

当点击的箭头前方仍有其他箭头时,格子会出现红色边框和叉号,右上角提示“前方被挡住了,少一次机会”。
4. 通关结果

清空当前关卡后显示“本关完成!”。前两关可以进入下一关,最后一关可以回到欢迎页。
5. 失败结果

三次机会全部用完后,程序显示“本关暂停”,并提供“再试一次”按钮。
二、项目介绍
1. 游戏规则
- 每个箭头只会沿自己的上、下、左、右方向移动。
- 从箭头的下一格开始检查,直到走出棋盘。
- 路径上没有箭头时,本箭头可以离开棋盘。
- 路径上遇到箭头时,本箭头不能移动,机会减一。
- 本关所有箭头离开棋盘即通关;机会为 0 时本关失败,可以重试。
2. 主要功能
- 欢迎页、游戏页、通关页和失败页;
- 6×6 棋盘和三个可通关的固定关卡;
- 四方向路径扫描、鼠标点击和箭头离场动画;
- 碰撞高亮、剩余箭头和机会显示;
- 重新本关、下一关和返回首页。
3. 运行方式
仓库只使用 Python 标准库,不需要安装第三方库。在项目根目录执行:
python3 main.py
自动化测试命令为:
python3 -m unittest discover -s tests -v
三、设计与实现
1. 文件划分
为了降低初学时把界面和规则混在一起的难度,我把项目分为三个部分:
- main.py:ArrowJourneyApp 负责 Tkinter 页面、棋盘绘制、点击事件和结果页;
- game_rules.py:保存 Arrow、Puzzle、方向增量和三关关卡数据;
- tests/test_game_rules.py:只测试规则层,不依赖图形窗口。
箭头使用 row、column 和 symbol 保存。例如 Arrow(0, 0, "→") 表示第一行第一列向右的箭头。
2. 四方向路径扫描
用一个方向字典保存行、列的变化量,避免把上、下、左、右写成四段重复代码:

被点击后,从下一格开始循环。若循环中找到了另一个箭头,返回“被阻挡”;若坐标超出 6×6 棋盘,说明路线畅通。
这个写法还能自然处理边缘箭头:如果箭头本来就朝向棋盘外,循环不会进入,直接判定为可以离开。
3. 界面流程
点击空格时只提示“这里没有箭头”;点击可离开的箭头时,画布用 after() 让箭头逐步移动,离开后从列表删除;点击被挡住的箭头时,机会减一并画红框。箭头数量为 0 时显示通关页,机会为 0 时显示失败页。
四、AIGC 使用过程
开发中使用 Codex 作为学习辅助。下面是本次作业中实际使用的记录:
| 子任务 | AIGC 提供的帮助 | 我采用或调整的结果 |
|---|---|---|
| 理解题目与拆分功能 | 根据题目把需求整理为欢迎页、关卡、路径判断、结果页和测试 | 选择 Tkinter 与 6×6 棋盘,保留三关基础难度 |
| 设计规则层 | 给出方向增量和“从下一格开始扫描”的思路 | 单独编写 Puzzle,让界面层只调用 choose(row, column) |
| 处理交互和测试 | 提供碰撞提示、after() 动画和单元测试的检查点 | 加入碰撞红框、重复点击锁定,以及三关通关顺序测试 |
AIGC 可以快速给出思路,但我仍需要实际运行程序并检查边界情况。例如,被阻挡的箭头不能从列表删除,点击空格也不能扣除机会。
五、测试结果
在项目目录执行 python3 -m unittest discover -s tests -v,共运行 5 个规则层自动化测试,结果为 OK。界面流程另外按下表检查。
| 编号 | 测试内容 | 预期结果 | 实际结果 | 结论 |
|---|---|---|---|---|
| T01 | 查找棋盘上的箭头 | 能返回该箭头,空格返回空 | arrow_at 返回符合预期 | 通过 |
| T02 | 点击前方无障碍箭头 | 箭头离开并从列表移除 | 状态为 leave,剩余数减少 | 通过 |
| T03 | 点击被阻挡箭头 | 箭头留下,机会减一 | 状态为 blocked,出现碰撞提示 | 通过 |
| T04 | 点击空格 | 不扣机会 | 返回空,机会数不变 | 通过 |
| T05 | 依次执行三关解法 | 每一关都能清空 | 三组关卡均得到通关状态 | 通过 |
| T06 | 用完三次机会 | 显示失败并能重试 | 显示“本关暂停”界面 | 通过 |
六、PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) |
|---|---|---|
| 阅读题目和设计规则 | 0.5 | 0.8 |
| 学习 Tkinter 基础控件 | 1.0 | 1.5 |
| 编写游戏界面 | 1.5 | 2.0 |
| 编写路径判断和关卡 | 1.0 | 1.2 |
| 编写测试并试玩 | 0.8 | 1.0 |
| 截图、整理仓库和博客 | 0.7 | 1.0 |
| 合计 | 5.5 | 7.5 |
七、心得体会
这次作业让我第一次把一个小游戏从规则、数据、界面到测试完整串起来。最容易出错的地方是判断路径时应该从“下一格”开始,而不是把自己也当成障碍物。把方向统一成行列变化量后,四种箭头能共用同一段循环,代码比为每个方向分别写判断更容易检查。
我也体会到图形界面不只是把功能画出来:碰撞提示、剩余机会和重新开始按钮能让玩家知道当前发生了什么。AIGC 能帮助我理解和搭建骨架,但真正能发现问题的是运行、点击和测试。以后我会继续保留规则层测试,让改动界面时不会影响核心判断。
浙公网安备 33010602011771号