软件工程第二次个人作业——一箭又一箭
项目 内容 这个作业属于哪个课程 H202601软件工程与软件工程实践 这个作业要求在哪里 2026 秋软件工程个人作业(第二次) 这个作业的目标 使用 Python 和 AIGC 完成 “一箭又一箭” 小游戏,实现箭头解谜、关卡切换、失误计数等全部基础功能,学习借助 AI 辅助开发并学会甄别、修改 AI 生成代码 学号 102402103 GitHub 仓库 Arrow-Game
1. 项目展示
视频:通过网盘分享的文件:一箭又一箭.mp4
链接: https://pan.baidu.com/s/1VUHNcTvD0_m3mOyYNuxtiw?pwd=uq65
本次开发的是一箭又一箭点击解谜小游戏,采用 Python+Pygame 实现。
游戏一共 3 个可通关关卡,完整包含:开始页面、游戏棋盘页、通关弹窗、失败弹窗。
核心玩法:点击箭头,沿着箭头方向直线检查路径,路上没有别的箭头就直接飞出棋盘消失;如果半路撞上别的箭头,会触发晃动反馈,扣除一次失误机会。失误耗尽直接失败,清空棋盘全部箭头即可通关,自动进入下一关。
- 开始界面:
![开始]()
- 游戏界面:
![游戏]()
- 通关界面:
![结算]()
- 失败界面:
![失败]()
2. 项目介绍
游戏规则
棋盘上分布上、下、左、右4 种方向箭头。玩家使用鼠标左键点击箭头:
- 程序沿着箭头指向的直线扫描路径;
- 路径上没有其他箭头:箭头飞出棋盘并消失,剩余箭头数量 - 1;
- 路径上存在其他箭头:箭头不动,触发晃动动画反馈,剩余失误次数 - 1;
- 每关最多 4 次失误机会,用完本关直接失败;
- 本关所有箭头全部消除,通关,自动进入下一关;
- 随时可以点击【重新开始】按钮,重置当前关卡棋盘与失误次数。
功能特色
✅ 完整状态机:首页 → 游戏中 → 通关 → 失败
✅ 4 方向箭头渲染、鼠标点击格子判定
✅ 路径检测算法,判断箭头是否可以飞出
✅ 碰撞视觉反馈(箭头晃动动画)
✅ 3 个人工试玩验证、存在合法通关顺序的关卡
✅ 剩余箭头、失误次数实时 UI 显示
✅ 关卡自动切换、关卡重置功能
3. 实现思路
整体代码结构
yi-jian-you-jian/
├─ main.py # 游戏入口,主循环,状态管理(首页/游戏/通关/失败)
├─ game_logic.py # 核心逻辑:路径检测、箭头能否飞出的判断
├─ game_board.py # 棋盘绘制、箭头渲染、动画、UI文字绘制
├─ levels.py # 3个关卡数据,二维数组存储每个格子箭头方向,None代表空格
└─ README.md # GitHub项目说明文档
关卡数据使用二维列表存储:
None为空格子,"up"/"down"/"left"/"right"代表 4 个方向箭头。
核心算法:路径检测(重点!面试助教大概率问)
给定箭头坐标(r,c)与方向,沿着方向一步一步遍历格子:
- 根据方向确定步长
dr,dc; - 不断更新下一个格子坐标
nr = r+dr, nc = c+dc; - 循环判断坐标是否还在棋盘范围内:
- 如果在棋盘内,并且该格子存在箭头 → 被阻挡,不能飞出
- 如果走到棋盘边界之外 → 一路畅通,可以飞出
# 核心逻辑代码片段
def can_fly(board, r, c):
dir = board[r][c]
dr, dc = 0, 0
if dir == "up": dr = -1
elif dir == "down": dr = 1
elif dir == "left": dc = -1
elif dir == "right": dc = 1
nr, nc = r + dr, c + dc
rows = len(board)
cols = len(board[0])
while 0 <= nr < rows and 0 <= nc < cols:
if board[nr][nc] is not None:
# 路上碰到别的箭头,阻挡
return False
nr += dr
nc += dc
# 成功走到棋盘外面,可以飞出
return True
坑点说明:AI 最初生成代码有数组越界 bug,向上检测时 r 不断减 1,没有提前做边界判断,我手动修复了循环条件。
游戏状态流转
STATE_HOME(首页)→点击开始→STATE_PLAY(游戏对局)
- 游戏对局:点箭头,调用
can_fly();- 成功飞出:删除当前箭头,剩余箭头计数 - 1;如果剩余箭头 = 0,切换到
STATE_WIN通关状态; - 碰撞阻挡:播放晃动动画,失误次数 - 1;失误次数 = 0,切换
STATE_LOSE失败状态;
- 成功飞出:删除当前箭头,剩余箭头计数 - 1;如果剩余箭头 = 0,切换到
- 通关弹窗:确认后加载下一关;
- 失败弹窗:确认后重置当前关卡;
- 任意游戏状态,点击重新开始按钮,重置当前关卡棋盘、失误次数。
4.AIGC 使用过程
表格
| 子任务 | 借助何种 AIGC 技术 | AI 实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| 整体代码架构与 Arrow 数据类定义 | Deepseek | 生成游戏分层架构,定义 Arrow 类,设计网格游戏基础数据结构 | 结构合理,基础属性齐全 | 补充枚举方向定义,完善类成员注释 |
| 路径检测函数 check_path | Deepseek | 生成沿箭头方向同行 / 同列的路径检测代码,判断是否存在阻挡箭头 | 基础逻辑正确,边界遍历逻辑存在疏漏 | 修正网格边界判断,只检测存活箭头 |
| 飞出 + 碰撞晃动动画实现 | Deepseek | 扩展 Arrow 类增加动画属性,编写动画状态更新、箭头绘制函数 | 晃动与飞行动画逻辑可行,正弦抖动效果可用 | 调整晃动时长 0.3s,微调飞出移动速度 |

小吐槽:AI 真的很会写代码,但是经常 “想当然”,生成关卡的时候直接丢给我一个无解棋盘,差点白忙活。AI 写的代码只能当草稿,必须人工测试、修改,不能直接复制粘贴!
5. 测试结果
按照作业要求,完成 6 项测试,全部手工测试验证:
表格
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 箭头正常消失,剩余箭头数量减 1 | ✅通过 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数 - 1 | 箭头触发晃动动画,失误计数正常减少 | ✅通过 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 箭头正常消失,不发生越界错误 | 边缘箭头直接飞出,无报错崩溃 | ✅通过 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 全部箭头消除后弹出通关提示,点击确认加载下一关 | ✅通过 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 失误清零弹出失败弹窗,可重置关卡重玩 | ✅通过 |
| T06 | 游戏进行中点击重新开始 | 箭头布局和失误次数恢复初始状态 | 棋盘恢复初始布局,失误重置为 4 次 | ✅通过 |
6.PSP 表格
表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1 | 0.5 | -0.5 |
| Python 与图形库学习 | 2 | 2.5 | +0.5 |
| 游戏界面实现 | 2 | 2 | 0 |
| 路径与碰撞逻辑实现 | 1 | 1 | 0 |
| 关卡设计 | 1 | 0.5 | -0.5 |
| AIGC 辅助开发 | 1 | 1 | 0 |
| 测试与修改 | 1 | 2.5 | +1.5 |
| README 与博客撰写 | 2 | 2.5 | +0.5 |
| 合计 | 11 | 12.5 | +1.5 |
7. 心得体会
这次作业是第一次正式用 AIGC 辅助完整小型项目开发,体验非常奇妙。
一开始以为 AI 可以一键生成完美成品,上手之后才发现,AIGC 更像一个高级代码助手,不是直接交作业的工具。AI 能快速生成基础框架、写循环、写绘图代码,节省大量重复编码的时间;但是 AI 不懂作业要求细节,容易写出有 bug 的代码,还会生成无法通关的关卡,需要我自己阅读、调试、手工验证。
开发过程踩了不少坑:路径检测越界、动画效果太生硬、关卡布局无解,这些都要自己排查。在调试核心路径判断函数的时候,我才真正吃透了游戏的核心逻辑,不再是单纯复制代码。
同时我也体会到软件工程里测试的重要性,按照测试用例一条条手工测试,才能发现隐藏 bug。写博客整理整个开发流程,也让我把零散的开发思路梳理完整。
总的来说,AIGC 是强大的开发加速器,但最终的代码质量、项目正确性,责任完全在开发者本人。AI 负责 “快速写草稿”,我们负责 “审代码、改 bug、验证逻辑”。




浙公网安备 33010602011771号