软件工程第二次作业:一箭又一箭
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 202601 软件工程 |
| 这个作业要求在哪里 | 第二次个人作业要求 |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏 |
| 学号 | 102401504 |
| GitHub 仓库 | Machenxii/arrow-after-arrow |
一、项目展示
本项目使用 Python 标准库中的 Tkinter 制作,不需要额外安装第三方库。完成了开始界面、游戏界面、通关/失败界面、3 个关卡、失误次数和重新开始功能。
1.1 开始界面

开始界面给出简单的操作规则,点击“开始游戏”进入第一关。
1.2 游戏过程

游戏界面显示当前关卡、剩余箭头、失误次数和重新开始按钮。箭头用不同颜色区分四个方向:上为绿色、下为蓝色、左为橙色、右为紫色。
1.3 碰撞反馈

如果点击的箭头前方被挡住,棋盘会出现红色边框提示,底部显示原因,并扣除一次失误机会。
1.4 通关界面

清空当前关卡全部箭头后显示通关界面,可以重新开始、进入下一关或返回首页。
二、项目介绍
2.1 游戏规则
棋盘上放有上、下、左、右四种方向的箭头。点击一支箭头后,程序沿它所指方向检查同一行或同一列:
- 到棋盘边界之间没有其他箭头:该箭头可以飞出并消失;
- 中途有其他箭头:该箭头不能消失,扣除一次失误机会;
- 清空全部箭头:本关通过,进入下一关;
- 失误次数用完:本关失败,可以重新开始。
2.2 界面设计
窗口大小为 760×650。上方蓝色区域显示标题、关卡信息和游戏状态;中间是 5×5 的方格棋盘;下方显示操作反馈,并放置“重新开始”和“返回首页”按钮。界面没有使用外部图片素材,箭头通过 Tkinter 的文字和图形绘制。
2.3 已实现功能
| 类别 | 功能 |
|---|---|
| 基础玩法 | 四方向箭头、鼠标点击、路径判断、消除、碰撞反馈、失误次数 |
| 游戏流程 | 开始界面、3 个可通关关卡、通关界面、失败界面、下一关、重新开始、返回首页 |
| 测试与文档 | 核心路径检测自动化测试、README 运行说明、界面截图 |
三、实现思路
3.1 箭头、方向和关卡表示
每支箭头用 Arrow 数据类保存行、列和方向。方向用字典转换为行和列的变化量。这样程序不需要为四个方向分别编写一套判断代码。
@dataclass(frozen=True)
class Arrow:
row: int
col: int
direction: str
DIRECTIONS = {
"up": (-1, 0), "down": (1, 0),
"left": (0, -1), "right": (0, 1),
}
关卡是一个 Arrow 列表。游戏开始和重新开始时,都根据该关卡列表重新创建棋盘。项目共有 3 关,均按可消除顺序试玩过。
3.2 路径检测(核心)
路径检测从被点击箭头的下一格开始,沿方向逐格向前。若遇到任意其他箭头,说明它被挡住;若走出棋盘仍未遇到箭头,说明路径畅通。
def is_path_clear(self, arrow):
row_step, col_step = DIRECTIONS[arrow.direction]
row = arrow.row + row_step
col = arrow.col + col_step
occupied = {(item.row, item.col) for item in self.arrows if item != arrow}
while 0 <= row < self.rows and 0 <= col < self.cols:
if (row, col) in occupied:
return False
row += row_step
col += col_step
return True
边界箭头不需要单独特判。例如最右列的右箭头,下一格已经越界,while 不会进入,函数直接返回 True,因此不会数组越界。
3.3 碰撞与流程处理
路径畅通时从箭头列表删除该对象,然后重绘棋盘;路径被挡住时将 errors_left 减一,重绘后用短暂的红色边框和文字作为反馈。箭头数为 0 时显示通关界面;失误数为 0 时显示失败界面。
四、AIGC 使用过程
开发过程使用了 Codex。以下三项记录对应本项目实际完成和调整的过程。
| 子任务 | 借助何种 AIGC | AI 实现或提供了什么 | 实际效果 | 人工修改 |
|---|---|---|---|---|
| 界面与项目结构 | Codex | 根据作业要求梳理了 Tkinter 的开始、游戏、结果三种界面及 Board、ArrowGame 的职责 | 结构清楚,先能运行基础流程 | 将功能控制为 3 个基础关卡,没有加入复杂机关,便于自己理解和讲解 |
| 路径检测与边界 | Codex | 给出了用方向向量和 while 循环统一处理四个方向的检测思路 | 逻辑可以同时处理上下左右 | 增加了“边缘且朝向棋盘外”的测试,并验证有阻挡和无阻挡两种结果 |
| 运行报错与测试文档 | Codex | 协助定位 Tkinter 画布文本参数和测试组织方式 | 首次启动时出现 TclError: unknown option "-spacing",默认 unittest 也没有发现 tests 目录 | 删除不被 Canvas 支持的 spacing 参数;把测试命令改为 python3 -m unittest discover -s tests -v,之后 4 项自动化测试均通过 |
这次实践让我认识到:AI 能快速提供代码骨架和排查方向,但生成的代码仍然要自己实际运行。尤其是图形库参数和边界情况,只有测试后才会暴露问题。
五、测试结果
核心路径检测测试文件为 tests/test_board.py,在项目根目录执行:
python3 -m unittest discover -s tests -v
自动化测试结果:4 项通过。界面流程按下表进行手工检查。
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 路径检测返回 True,箭头从棋盘列表移除,剩余箭头数减少 | 通过 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数减 1 | 箭头保留;界面显示红色边框和提示文字,失误次数减少 | 通过 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 箭头正常消失,无越界错误 | 上、下、左、右四种边缘方向的自动化子测试均通过 | 通过 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 清空列表后显示“恭喜通关”,点击“下一关”进入下一关 | 通过 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 失误数降为 0 后显示失败界面;“重新开始”恢复当前关卡 | 通过 |
| T06 | 游戏中重新开始 | 箭头布局和失误次数恢复 | 点击“重新开始”后重新读取当前关卡数据,失误次数恢复为 3 | 通过 |
六、PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 0.5 | 0.5 | 0 |
| Python 与 Tkinter 学习 | 1.0 | 1.5 | +0.5 |
| 游戏界面实现 | 1.5 | 2.0 | +0.5 |
| 路径与碰撞逻辑实现 | 1.0 | 1.0 | 0 |
| 关卡设计 | 0.5 | 0.5 | 0 |
| AIGC 辅助开发 | 0.5 | 1.0 | +0.5 |
| 测试与修改 | 0.5 | 1.0 | +0.5 |
| README 与博客撰写 | 0.5 | 1.0 | +0.5 |
| 合计 | 6.0 | 8.5 | +2.5 |
七、心得体会
这次作业让我第一次较完整地把一个小游戏从规则、界面、逻辑到测试做完。AI 的帮助主要是快速整理任务和给出实现方向,减少了我查资料和搭框架的时间;但它不能代替运行和验证。实际运行时,Canvas 的 spacing 参数报错,说明即使代码看起来合理,也必须真正启动程序。
在实现核心逻辑时,我对“行、列”和“方向变化量”的关系更清楚了。以前容易把横向、纵向变化写反;现在通过从“下一格”开始循环检查,可以用同一段代码处理四个方向。自动化测试也让我意识到,边缘越界这种看似小的问题,应该在写代码时就设计测试,而不是等程序出错后再修。
整体而言,我认为 AIGC 是很有用的学习助手:它能加快起步速度,但自己仍要能解释每个变量、每个判断和测试结果。
浙公网安备 33010602011771号