# 2026 秋软件工程个人作业(二)—— 一箭又一箭
2026 秋软件工程个人作业(二)——一箭又一箭
0. 作业信息
2026 秋软件工程个人作业(二)——一箭又一箭
作业信息
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 2026-01 软件工程与软件工程实践 |
| 这个作业要求在哪里 | 个人作业(二):一箭又一箭 |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏,完成游戏设计、编码、测试、AIGC 使用记录以及 Git/GitHub 版本管理 |
| 学号 | 102401216 |
| GitHub 仓库 | baomihua1234/ArrowGame |
1. 项目成果展示
本次作业的目标是利用 AIGC 辅助完成“一箭又一箭”小游戏,同时记录 AIGC 在需求分析、程序设计、调试、测试以及项目管理过程中的使用情况。
1. 项目成果展示
1.1 游戏主菜单
游戏启动后首先进入主菜单,显示游戏规则以及“开始游戏”按钮。

1.2 游戏界面
进入关卡后,界面会显示:
- 当前关卡;
- 剩余失误机会;
- 剩余箭头数量;
- 游戏棋盘;
- 当前操作提示;
- 返回菜单按钮;
- 重新开始按钮。

1.3 点击正确箭头
当箭头前方一直到棋盘边缘都不存在其他箭头时,该箭头可以飞出棋盘。
界面会提示:
成功!箭头已飞出
同时剩余箭头数量减少。

1.4 点击错误箭头
如果箭头前方存在其他箭头,则该箭头无法飞出。
玩家会损失一次失误机会,例如:
前方有障碍!剩余 2 次机会

1.5 游戏失败
每个关卡初始拥有 3 次失误机会。
当失误机会耗尽后,游戏进入失败状态:
挑战失败
失误机会已经用完
玩家可以选择重新挑战当前关卡。

1.6 关卡通过
当棋盘中的全部箭头被清除后,当前关卡完成。
本关通过!
继续挑战下一关

1.7 全部通关
本项目目前包含三个关卡。
完成第三关后显示:
全部通关!
恭喜完成全部三个关卡

2. 游戏需求分析
2.1 基本游戏规则
游戏棋盘由若干格子组成,每一个格子可能为空,也可能存在一个箭头。
箭头共有四个方向:
↑ ↓ ← →
游戏规则如下:
- 玩家点击一个箭头;
- 程序从该箭头前方的第一个格子开始,沿箭头方向一直检查到棋盘边缘;
- 如果路径中不存在其他箭头,则当前箭头可以飞出棋盘并被消除;
- 如果路径中存在其他箭头,则当前箭头被阻挡;
- 点击被阻挡的箭头会损失一次失误机会;
- 每关初始拥有 3 次失误机会;
- 清空当前棋盘即可进入下一关;
- 失误机会耗尽则本次挑战失败。
例如:
→ . . ↑
虽然 → 右侧相邻的两个位置为空,但是更远处仍然存在 ↑,因此这个 → 不能飞出。
而:
→ . . .
右侧一直到棋盘边缘都不存在其他箭头,因此该箭头可以飞出。
3. 开发环境与技术选型
本项目使用以下开发环境:
| 项目 | 环境 |
|---|---|
| 操作系统 | Windows |
| IDE | Visual Studio 2022 |
| Python | 3.13.7 |
| 图形库 | pygame-ce 2.5.8 |
| 测试框架 | pytest 9.1.1 |
| 版本管理 | Git |
| 代码托管 | GitHub |
选择 Python + pygame-ce 的主要原因如下:
- Python 代码结构相对简单,适合快速实现游戏逻辑;
- pygame 能够方便地处理窗口、鼠标事件和图形绘制;
- pytest 可以对与图形界面无关的核心规则进行自动化测试;
- Git 和 GitHub 可以记录代码开发过程并进行版本管理。
4. 项目结构
项目最终结构如下:
ArrowGame/
│
├── ArrowGame.py
│ └── 游戏主程序、pygame 界面以及状态管理
│
├── game_logic.py
│ └── 游戏核心逻辑
│ ├── can_exit()
│ ├── is_level_clear()
│ ├── count_arrows()
│ └── is_solvable()
│
├── test_game_logic.py
│ └── pytest 自动化测试
│
├── requirements.txt
│ └── Python 项目依赖
│
├── README.md
│ └── 项目使用说明
│
├── aigc_log.md
│ └── AIGC 使用过程记录
│
├── psp.md
│ └── PSP 时间记录
│
├── .gitignore
│ └── Git 忽略规则
│
├── ArrowGame.pyproj
└── ArrowGame.sln
最初游戏逻辑和 pygame 界面代码都位于同一个文件中。
在进行自动化测试时,我将核心游戏规则拆分到:
game_logic.py
从而实现了游戏逻辑与图形界面的分离。
5. 数据结构设计
5.1 棋盘表示
游戏使用 Python 二维列表保存棋盘状态。
例如:
board = [
[".", ".", "D", "."],
["R", ".", ".", "L"],
[".", "U", ".", "."],
["R", ".", ".", "U"]
]
其中规定:
U = Up = ↑
D = Down = ↓
L = Left = ←
R = Right = →
. = 空格
因此程序在进行游戏逻辑判断时,只需要处理:
U D L R .
pygame 绘制界面时,再将这些字符转换成真正的箭头符号。
5.2 方向表示
箭头方向通过字典保存:
DIRECTIONS = {
"U": (-1, 0),
"D": (1, 0),
"L": (0, -1),
"R": (0, 1)
}
其中:
| 方向 | 坐标变化 |
|---|---|
U |
行号 -1 |
D |
行号 +1 |
L |
列号 -1 |
R |
列号 +1 |
这种表示方式可以使用统一的代码处理四种方向,而不需要为上下左右分别编写四套判断逻辑。
6. 核心算法实现
6.1 can_exit() 算法
本游戏最重要的函数是:
can_exit(board, row, col)
该函数负责判断指定位置的箭头能否飞出棋盘。
核心流程如下:
获取箭头方向
↓
根据 DIRECTIONS 得到 dr、dc
↓
从箭头前方第一个格子开始
↓
沿箭头方向逐格扫描
↓
当前坐标是否仍在棋盘内部?
↓
是
↓
当前位置是否存在其他箭头?
↙ ↘
是 否
↓ ↓
False 继续扫描
↓
最终离开棋盘
↓
True
核心代码:
def can_exit(board, row, col):
rows = len(board)
cols = len(board[0])
if not (
0 <= row < rows
and
0 <= col < cols
):
return False
direction = board[row][col]
if direction not in DIRECTIONS:
return False
dr, dc = DIRECTIONS[direction]
r = row + dr
c = col + dc
while (
0 <= r < rows
and
0 <= c < cols
):
if board[r][c] != ".":
return False
r += dr
c += dc
return True
这里不能只判断箭头相邻的一个格子。
例如:
→ . . ↑
必须继续检查到最右侧,才能发现真正的阻挡。
7. 鼠标点击与坐标转换
pygame 获取鼠标点击位置:
mouse_x, mouse_y = event.pos
但程序真正需要知道的是:玩家点击的是棋盘中的哪一行、哪一列。
因此需要进行坐标转换:
col = (mouse_x - board_x) // cell_size
row = (mouse_y - board_y) // cell_size
之后还需要判断:
0 <= row < rows
0 <= col < cols
从而防止玩家点击棋盘外部导致数组越界。
完成坐标转换后,再调用:
can_exit(board, row, col)
进行游戏规则判断。
8. 游戏状态设计
为了管理不同页面,我使用了多个游戏状态:
STATE_MENU = "menu"
STATE_PLAYING = "playing"
STATE_CLEAR = "clear"
STATE_GAME_OVER = "game_over"
STATE_ALL_CLEAR = "all_clear"
对应关系如下:
| 状态 | 含义 |
|---|---|
menu |
主菜单 |
playing |
正常游戏 |
clear |
当前关卡完成 |
game_over |
游戏失败 |
all_clear |
全部关卡完成 |
程序根据当前 game_state 决定:
- 显示哪个页面;
- 哪些按钮有效;
- 鼠标点击应该执行什么操作。
9. 多关卡设计
本项目目前实现了三个关卡:
| 关卡 | 棋盘大小 |
|---|---|
| 第 1 关 | 4 × 4 |
| 第 2 关 | 5 × 5 |
| 第 3 关 | 6 × 6 |
随着关卡增加:
- 棋盘逐渐扩大;
- 箭头数量增加;
- 判断顺序更加复杂。
为了避免人工设计出无法完成的关卡,我增加了:
is_solvable()
函数进行自动检查。
10. 关卡可解性验证
is_solvable() 会复制一份关卡数据,然后自动寻找当前可以飞出的箭头。
每找到一个可以飞出的箭头,就将其删除。
如果最终:
棋盘全部清空
则说明:
关卡可解
如果出现:
棋盘仍有箭头
+
已经不存在任何可以飞出的箭头
则说明:
关卡发生死锁
此时函数返回:
False
程序启动时会自动验证三个正式关卡,从而避免提交后才发现某个关卡实际上无法通过。
11. 自动化测试
本项目使用 pytest 对核心游戏逻辑进行自动化测试。
为了方便测试,我将核心规则从 pygame 主程序中独立到了:
game_logic.py
测试文件为:
test_game_logic.py
11.1 测试用例
| 编号 | 测试内容 | 预期结果 |
|---|---|---|
| T01 | 箭头前方无遮挡 | can_exit() 返回 True |
| T02 | 箭头前方存在其他箭头 | 返回 False |
| T03 | 边界位置箭头朝棋盘外 | 返回 True |
| T04 | 点击空格 | 返回 False |
| T05 | 棋盘全部为空 | 判定关卡完成 |
| T06 | 棋盘仍存在箭头 | 判定关卡未完成 |
| T07 | 统计剩余箭头数量 | 返回正确数量 |
| T08 | 检查简单可解关卡 | is_solvable() 返回 True |
运行命令:
python -m pytest -v
测试结果:
8 passed

通过自动化测试,可以减少修改代码后引入新错误的风险。
12. AIGC 使用过程
本次作业主要使用 ChatGPT 辅助完成开发。
由于这是我第一次完成此类型的软件工程作业,因此 AIGC 不仅用于代码生成,也用于:
- 环境配置;
- 算法设计;
- 错误分析;
- 自动化测试;
- Git / GitHub 使用;
- 开发流程学习和问题排查。
12.1 AIGC 使用总表
| 子任务 | 借助何种 AIGC 技术 | AI 实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| Python 与 pygame 环境配置 | ChatGPT | 根据 Visual Studio 2022 环境指导检查 Python Development 组件、Python 版本,创建 .venv 并安装 pygame-ce |
成功完成 Python 3.13.7、pygame-ce 2.5.8 的开发环境配置 | 实际运行时发现 VS 使用了全局 Python,根据报错手动将解释器切换到 .venv\Scripts\python.exe |
核心路径检测 can_exit() |
ChatGPT | 提出使用 DIRECTIONS 字典表示四个方向,并从箭头前方逐格扫描到棋盘边界的算法 |
能正确判断无遮挡、远距离阻挡、边界箭头等情况 | 根据实际测试补充坐标边界检查,避免 Python 负索引影响边界判断,并通过人工棋盘示例验证 |
| 完整游戏功能设计 | ChatGPT | 提供 pygame 游戏状态设计以及主菜单、失误次数、通关、失败、重新开始、多关卡等功能实现思路 | 游戏能够完成从主菜单到三关通关的完整流程 | 对生成代码进行实际运行检查;曾出现括号未闭合问题,人工检查后重新测试,同时使用可解性检查验证关卡 |
| pytest 自动化测试 | ChatGPT | 建议将核心算法拆分到 game_logic.py,并设计 can_exit()、通关判断、箭头计数、关卡可解性等测试用例 |
最终共完成 8 个自动化测试,运行结果为 8 passed |
根据项目实际函数名称调整测试代码,并实际运行 pytest 验证所有测试通过 |
| Git 与 GitHub 项目管理 | ChatGPT | 指导创建 .gitignore、初始化 Git、提交代码、配置用户信息、建立 GitHub 仓库并完成 push |
成功将项目上传到 GitHub,并形成多次 Git 提交记录 | 初次 .gitignore 未正确排除 .vs/ 和 __pycache__/,根据 git status 结果手动修改,同时处理 Git 用户身份配置问题 |
12.2 代表性案例一:环境配置
我首先向 AIGC 说明:
这是我第一次做该类型作业,我的电脑已经安装 Visual Studio 2022,没有 VS Code,希望一步步完成该作业。
AIGC 建议继续使用 Visual Studio 2022,并指导检查:
Python Development
组件。
随后使用:
py --version
python --version
检查 Python。
结果为:
Python 3.13.7
之后建立:
.venv
并安装:
pygame-ce
pytest

12.3 代表性案例二:编码问题排查
第一次运行包含中文的 Python 程序时出现:
SyntaxError: Non-UTF-8 code
经过 AIGC 分析,发现 Python 文件使用的编码不是 UTF-8。
在 Visual Studio 中将文件重新使用 UTF-8 保存后,问题得到解决。

12.4 代表性案例三:Python 环境问题
随后又出现:
ModuleNotFoundError: No module named 'pygame'
实际原因并不是 pygame 没有安装,而是:
pygame 安装在 .venv
但 Visual Studio 当时使用的是:
全局 Python
将 Visual Studio 的 Python 环境切换为:
.venv\Scripts\python.exe
后问题得到解决。
12.5 代表性案例四:核心算法设计
对于游戏核心规则,我向 AIGC 描述:
需要判断一个箭头从当前位置沿方向一直到棋盘边缘之间是否存在其他箭头。
AIGC 建议使用:
DIRECTIONS
统一保存四种移动方向,并通过 while 循环一直扫描到棋盘边界。
在理解算法后,我又通过实际棋盘进行人工验证。
例如:
→ . . ↑
不能飞出。
而:
→ . . .
可以飞出。
同时在实际代码中加入:
0 <= r < rows
0 <= c < cols
保证不会因为 Python 的负索引机制产生错误的边界判断。
【这里插入 can_exit() 相关 AIGC 对话截图】
12.6 代表性案例五:自动化测试
完成游戏以后,我继续询问如何进行软件工程测试。
AIGC 建议:
- 将核心游戏规则从 pygame 主程序中分离;
- 创建
game_logic.py; - 创建
test_game_logic.py; - 使用 pytest 测试核心逻辑和边界条件。
最终:
8 passed
这说明当前设计的 8 个核心自动化测试均成功通过。
12.7 代表性案例六:Git 与 GitHub
由于此前没有完整使用过 Git 和 GitHub,因此 AIGC 还指导我完成了:
.gitignore
git init
git status
git add
git commit
git remote
git branch
git push
同时解决了:
Author identity unknown
问题。
最终将项目成功上传至:
https://github.com/baomihua1234/ArrowGame

13. AIGC 输出的验证与人工修改
在开发过程中,我没有直接认为 AIGC 输出一定正确,而是采用以下方法进行验证:
- 每增加一个功能后实际运行程序;
- 手动点击箭头验证游戏规则;
- 使用 pytest 验证核心算法;
- 使用
is_solvable()检查正式关卡; - 使用 Git 保存项目的重要阶段;
- 出现错误时根据实际错误信息继续分析,而不是反复复制代码。
开发过程中也出现过 AIGC 给出的完整代码在复制后存在括号未闭合的问题。
Visual Studio 提示:
"(" was not closed
之后重新检查并替换为经过验证的版本才解决。
这让我认识到:
AIGC 可以提高开发效率,但是生成结果仍然需要人工检查、实际运行和测试。
14. Git 与 GitHub 版本管理
项目使用 Git 进行版本管理。
第一次提交:
feat: complete initial arrow game
之后添加项目文档:
docs: add project README
以及:
docs: add AIGC log and PSP record
GitHub 仓库:
https://github.com/baomihua1234/ArrowGame

通过 Git 可以:
- 保存项目历史版本;
- 查看代码变化;
- 防止修改失败后无法恢复;
- 将项目同步到 GitHub。
15. PSP
15.1 PSP 时间记录
| 阶段 | 预计时间(分钟) | 实际时间(分钟) |
|---|---|---|
| 需求理解与任务分析 | 30 | 20 |
| Python / Visual Studio 环境配置 | 30 | 35 |
| pygame 环境配置 | 20 | 25 |
| 游戏界面与棋盘设计 | 60 | 35 |
核心算法 can_exit() |
60 | 30 |
| 鼠标交互与游戏规则实现 | 60 | 30 |
| 多关卡与状态管理 | 60 | 25 |
| Bug 调试 | 60 | 25 |
| 自动化测试 | 45 | 25 |
| Git 与 GitHub 配置 | 60 | 40 |
| README 与项目文档 | 45 | 25 |
| AIGC 使用记录 | 30 | 20 |
| PSP 与博客整理 | 90 | 75 |
| 合计 | 650 | 410 |
实际时间根据开发过程记录,休息时间不计入开发时间。
15.2 时间差异分析
本次作业预计总耗时为:
650 分钟 ≈ 10 小时 50 分钟
实际耗时约为:
410 分钟 ≈ 6 小时 50 分钟
实际耗时低于最初预计时间,主要原因是使用 AIGC 后,可以将整个开发任务拆分为多个较小步骤,并在出现问题时快速定位原因,因此游戏界面、核心算法和自动化测试等部分完成得比最初预计更快。
不过在环境配置和 Git / GitHub 配置过程中,由于此前缺少相关经验,仍然产生了一些额外调试时间。
主要问题包括:
Non-UTF-8 code
ModuleNotFoundError
Author identity unknown
这些问题让我认识到:在估算开发时间时,不能只考虑编码本身,还需要给环境配置、问题排查、测试和文档整理预留时间。
16. 开发过程中遇到的问题
16.1 Python 文件编码错误
错误:
SyntaxError: Non-UTF-8 code
原因:
Python 文件不是 UTF-8 编码。
解决方法:
使用 Visual Studio 的“使用编码保存”功能,将 Python 文件重新保存为 UTF-8。
16.2 pygame 已安装但程序无法导入
错误:
ModuleNotFoundError: No module named 'pygame'
原因:
pygame 安装在项目虚拟环境 .venv 中,而 Visual Studio 使用的是全局 Python。
解决方法:
将 Visual Studio 当前 Python 环境切换到:
.venv\Scripts\python.exe
16.3 Python 负索引问题
在 Python 中:
board[-1]
不会直接报错,而是会访问列表中的最后一个元素。
因此 can_exit() 中必须先通过:
0 <= r < rows
0 <= c < cols
保证坐标仍然位于棋盘内部,然后才能读取:
board[r][c]
否则边界位置的箭头可能得到错误结果。
16.4 关卡死锁问题
人工设计箭头布局时可能产生:
箭头互相阻挡
最终没有任何箭头能够飞出。
因此加入:
is_solvable()
函数,在程序启动时自动验证所有正式关卡。
16.5 Git 忽略文件问题
第一次运行:
git status
时发现:
.vs/
__pycache__/
等本地缓存目录也准备被 Git 记录。
因此通过 .gitignore 排除:
.venv/
.vs/
__pycache__/
.pytest_cache/
*.pyc
*.pyo
Thumbs.db
.DS_Store
最终 GitHub 仓库只保留真正需要的项目文件。
17. 项目最终功能
目前项目已经完成:
- pygame 图形界面;
- 游戏主菜单;
- 游戏规则显示;
- 4×4、5×5、6×6 三个关卡;
- 四方向箭头;
- 鼠标点击;
- 箭头路径判断;
- 正确消除;
- 错误点击提示;
- 3 次失误机会;
- 游戏失败;
- 重新挑战;
- 返回菜单;
- 重新开始;
- 当前关卡完成;
- 下一关;
- 全部通关;
- 剩余箭头统计;
- 自动检查关卡可解性;
- pytest 自动化测试;
- Git 版本管理;
- GitHub 项目托管;
- README;
- AIGC 使用记录;
- PSP 开发时间记录。
18. 项目运行方法
GitHub 仓库:
https://github.com/baomihua1234/ArrowGame
18.1 克隆项目
git clone https://github.com/baomihua1234/ArrowGame.git
18.2 进入项目目录
cd ArrowGame
18.3 创建虚拟环境
python -m venv .venv
18.4 激活虚拟环境
Windows:
.venv\Scripts\activate
18.5 安装依赖
python -m pip install -r requirements.txt
18.6 运行游戏
python ArrowGame.py
18.7 运行自动化测试
python -m pytest -v
19. 作业心得
本次作业是我第一次从零开始完成一个相对完整的小游戏项目,同时也是第一次系统接触 pygame、pytest、Git 和 GitHub。
开始时,我对整个项目应该如何组织并不清楚。如果直接尝试一次完成所有功能,很容易因为环境、代码和项目管理问题同时出现,而不知道应该从哪里进行排查。
在 AIGC 的辅助下,我将整个任务拆分为:
环境配置
↓
Python 程序运行
↓
pygame 游戏窗口
↓
棋盘绘制
↓
箭头数据结构
↓
can_exit() 核心算法
↓
鼠标操作
↓
游戏状态
↓
多个关卡
↓
自动化测试
↓
Git
↓
GitHub
↓
项目文档
逐步完成之后,整个开发过程变得更加清晰。
本次作业也让我认识到,AIGC 并不是简单地“自动完成作业”。
在实际开发过程中仍然遇到了:
- 文件编码错误;
- Python 环境配置错误;
- 代码语法错误;
- Git 配置问题;
.gitignore配置问题。
这些问题都需要结合实际运行结果进行判断和处理。
因此,我认为 AIGC 更适合作为:
学习助手 + 开发助手 + 调试助手
而不是完全替代开发者。
此外,pytest 自动化测试让我第一次比较直观地理解了软件测试的作用。
过去运行程序时,主要依靠手动操作判断程序是否正确;而自动化测试可以在修改代码后快速验证核心功能是否仍然正常。
Git 和 GitHub 也让我第一次体验到了软件项目的版本管理流程。
通过本次作业,我不仅完成了“一箭又一箭”小游戏,也对一个软件项目从:
需求
↓
设计
↓
编码
↓
调试
↓
测试
↓
版本管理
↓
文档
↓
发布
这一完整过程有了更加具体的认识。
20. 项目链接
GitHub 仓库
https://github.com/baomihua1234/ArrowGame
项目主要文件
ArrowGame.py
game_logic.py
test_game_logic.py
README.md
aigc_log.md
psp.md
requirements.txt

浙公网安备 33010602011771号