2026 秋软件工程个人作业(第二次)

“一箭又一箭”小游戏开发报告

本报告记录本项目从需求分析、AIGC 协作、编码、测试到项目整理的完整过程,可直接作为博客初稿。提交博客前,请将尖括号占位信息替换为自己的真实信息,并补充本人实际试玩时间。

一、作业信息

项目内容 信息
课程 软件工程与软件工程实践
课程链接 H202601软件工程与软件工程实践
作业要求链接 2026 秋软件工程个人作业(第二次)
作业目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401323
姓名 陈勇昊
GitHub 仓库 GitHub 仓库链接
项目名称 一箭又一箭(Arrow Escape)
开发工具 Python、Pygame、ChatGPT/Codex

二、项目展示

2.1 开始界面

start

开始界面显示游戏名称、基本玩法和开始按钮。游戏说明提醒玩家观察箭头方向,优先点击没有被挡住的箭头。

2.2 游戏界面

game

游戏界面包含当前关卡、剩余箭头数量、失误机会、棋盘和重新开始按钮。棋盘采用 8×8 网格,四种方向使用不同颜色区分。

2.3 通关界面

result

清除当前关卡全部箭头后,程序显示“本关完成”面板,玩家可以进入下一关或重玩本关。完成第三关后会显示全部通关状态。

2.4 失败界面

failure

错误点击 3 次后显示“挑战失败”面板,玩家可以重新挑战当前关卡。

当前截图由 Pygame 的无窗口渲染检查生成。正式发布博客前,建议再补充本人实际运行窗口的截图或 GIF。

三、项目介绍

3.1 游戏规则

棋盘中放置带有上、下、左、右方向的单格箭头。玩家点击一个箭头后,程序检查它朝向棋盘边界的路径:

  1. 如果同一行或同一列的前方没有其他活动箭头,箭头飞出棋盘并消失。
  2. 如果前方存在其他箭头,当前箭头不能消失,程序播放晃动和变色反馈。
  3. 每次点击被阻挡的箭头会消耗 1 次失误机会,共有 3 次机会。
  4. 当前关卡的箭头全部消失后显示通关面板,点击“下一关”进入下一关。
  5. 失误机会耗尽后显示失败面板,点击“重新挑战”恢复当前关卡。

3.2 项目文件

文件 作用
game_logic.py 定义方向、箭头数据、路径检测和关卡可解性检查
game.py Pygame 图形界面、鼠标交互、动画和游戏状态机
app.py 兼容启动入口,执行 python app.py 即可启动游戏
test_game_logic.py 路径检测、边界和关卡可解性自动化测试
requirements.txt Pygame 依赖
screenshots/ 开始、游戏、通关和失败截图
README.md 项目运行说明和简要技术说明
作业报告.md 本次作业的过程报告

原工作区中的 index.html 是开发前已经存在的无关图像生成网页示例,不属于本作业;它已在 .gitignore 中排除,避免被误提交到游戏仓库。

四、开发环境与运行方法

4.1 开发环境

  • Python 3.10 及以上
  • Pygame 2.5 及以上
  • Windows、macOS 或 Linux
  • 本项目验证环境:Python 3.13、Pygame 2.6.1

4.2 安装依赖

python -m pip install -r requirements.txt

4.3 启动游戏

python game.py

也可以使用兼容启动器:

python app.py

4.4 运行测试

python -m unittest -v

五、实现思路

5.1 箭头和方向表示

项目使用枚举表示四个方向,每个方向保存横向位移、纵向位移和中文名称:

class Direction(Enum):
    UP = (0, -1, "上")
    DOWN = (0, 1, "下")
    LEFT = (-1, 0, "左")
    RIGHT = (1, 0, "右")

一个箭头由 ArrowSpec(row, col, direction) 表示,其中 rowcol 是 8×8 网格坐标。Pygame 层再为每个箭头维护 activehitflyingremoved 四种动画状态。

5.2 路径检测

路径检测的核心函数是 can_fly()。它不需要逐格访问棋盘,因此不会因为箭头位于边缘而产生数组越界。对于左右方向,只比较同一行中其他箭头的列坐标;对于上下方向,只比较同一列中其他箭头的行坐标:

if direction.dx:
    same_line = origin.row == other.row
    ahead = (other.col - origin.col) * direction.dx > 0
else:
    same_line = origin.col == other.col
    ahead = (other.row - origin.row) * direction.dy > 0

只要存在 same_line and ahead 的活动箭头,就判定为阻挡。边界不需要特殊数组访问,因此位于边缘且朝向棋盘外的箭头可以正常飞出。

5.3 关卡可解性检查

开发过程中增加了 solve_level()。它反复找出当前所有可以飞出的箭头并移除,直到棋盘为空或找不到可移除箭头。三组最终关卡数据都通过了该检查,说明每关至少存在一个完整的移除顺序。

5.4 游戏状态和动画

程序主要页面状态如下:

start       开始界面
playing     游戏进行中
level_clear 当前关卡完成
game_over   失误机会耗尽
all_clear   三关全部完成

点击可飞箭头后进入 0.34 秒飞出动画;点击被阻挡箭头后进入 0.42 秒晃动、变红动画,同时失误次数减 1。飞出状态的箭头不会再参与后续路径检测。

六、开发过程

6.1 需求分析

首先将作业要求拆分为四类功能:

  1. 棋盘和四种方向箭头显示。
  2. 点击、路径检测、飞出和碰撞反馈。
  3. 失误次数、重新开始、通关、失败和关卡切换。
  4. AIGC 记录、测试、README、截图和 Git 提交材料。

6.2 检查原始工作区

开发开始时,工作区中已有一个与本作业无关的 Flask 图像生成示例,并且原 app.py 中存在硬编码的 Hugging Face Token。处理方式如下:

  • 新增独立的 game_logic.pygame.py,避免把无关网页逻辑混入游戏。
  • app.py 改为无密钥的游戏启动器。
  • 用敏感信息搜索检查项目,未发现 hf_...API_TOKENAuthorization 残留。
  • 将旧 index.html 加入 .gitignore,不删除用户原有文件。

6.3 逻辑实现

先实现不依赖 Pygame 的方向和路径检测,再用单元测试覆盖左右、上下和边界情况。这样即使没有打开图形窗口,也可以先确认最关键的游戏规则正确。

6.4 界面实现

使用 Pygame 绘制开始页、棋盘、状态统计、按钮和结果面板。箭头没有依赖外部素材,而是使用线段和三角形绘制,便于提交和运行。

6.5 验证和截图

安装 Pygame 后进行了以下验证:

  • 无窗口绘制开始、游戏、通关和失败四种界面。
  • 模拟点击一个被阻挡箭头,确认失误次数从 3 变为 2。
  • 自动寻找每关可飞箭头并完成第一关,确认状态进入 level_clear
  • 点击下一关,确认关卡索引从 0 进入 1。
  • 连续三次点击被阻挡箭头,确认状态进入 game_over
  • 生成 screenshots/start.pnggame.pngresult.pngfailure.png

正式提交前仍应由提交者在自己的桌面环境中手工试玩三关,并在博客中补充真实试玩记录。

七、AIGC 使用过程

本项目使用 ChatGPT/Codex 作为 Coding Agent,辅助需求拆解、代码编写、测试和界面检查。下面记录三次具有代表性的协作过程。

次数 子任务 向 AI 提出的要求 AI 完成的工作 人工判断和修改
第 1 次 需求分析和代码结构 将作业要求拆成可运行的 Pygame 游戏,并把规则和界面分离 设计 game_logic.pygame.py、测试文件和三关数据的结构 检查作业评分点,保留开始、游戏、通关、失败和重新开始等基础功能,去掉不必要的复杂机关
第 2 次 路径检测和关卡设计 实现上、下、左、右四方向的同轴阻挡判断,并检查三关是否可解 生成 DirectionArrowSpeccan_fly()solve_level() 和关卡数组 人工核对边界条件,确保边界箭头不访问越界坐标;使用求解器检查最终三关数据
第 3 次 碰撞反馈和交付材料 增加飞出动画、碰撞晃动、失误次数、结果页面,并整理 README、截图和测试报告 完成 activehitflyingremoved 状态机,生成截图和 Markdown 材料 人工检查状态切换、按钮位置和结果面板布局;修正飞出状态仍参与阻挡检测的问题,并调整结果面板高度

AI 生成的代码并没有直接作为不可解释的黑盒使用。开发者重点检查了以下内容:

  • can_fly() 是否只检查同一行或同一列。
  • 方向为上、下时是否正确使用行坐标。
  • 箭头飞出后是否从活动集合中移除。
  • 失误机会耗尽后是否进入失败页。
  • 三关是否至少存在一个通关顺序。

八、测试结果

8.1 自动化测试

执行命令:

python -m unittest -v

实际结果:4 个测试全部通过。

4 tests ... OK

测试覆盖内容包括:

  • 左右方向的阻挡和可飞判断。
  • 上、下、左、右四个方向在棋盘边界的可飞判断。
  • 三个关卡的可解性。
  • 按可飞顺序移除第一关的全部箭头。

8.2 功能测试表

编号 测试内容 预期结果 当前验证结果 验证方式
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 通过 自动流程测试 + Pygame 渲染
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1,并晃动变红 通过 自动点击测试
T03 点击位于边缘且朝向棋盘外的箭头 箭头正常消失,不发生越界错误 通过 test_all_directions_at_boundary_can_fly
T04 消除本关全部箭头 显示通关并进入下一关 通过 自动求解第一关并点击下一关
T05 失误次数耗尽 显示失败并允许重新开始 通过 连续三次点击被阻挡箭头
T06 游戏进行中重新开始 箭头布局和失误次数恢复 待本人桌面复核 游戏内按钮和 Esc 均已实现

8.3 额外检查

  • python -m py_compile game.py game_logic.py app.py test_game_logic.py:通过。
  • Pygame 2.6.1 导入和无窗口渲染:通过。
  • 敏感信息扫描:未发现 Token、密码或 Authorization 残留。
  • 三组关卡均通过 solve_level():通过。

九、PSP 记录

下面是本次开发的 PSP 初稿。预计耗时和实际耗时中的“实际”必须由提交者结合自己的开发日志、试玩时间和博客撰写时间确认后再提交,不能直接照抄示例。

任务 预计耗时(小时) 实际耗时(小时) 差异(小时) 说明
需求分析与游戏设计 0.5 0.3 -0.2 拆分评分点和页面状态
Python 与 Pygame 学习 1.0 0.8 -0.2 学习窗口、字体和事件循环
游戏界面实现 1.5 2.0 +0.5 开始页、棋盘和结果页
路径与碰撞逻辑实现 1.0 1.2 +0.2 四方向检测、失误机制
关卡设计 0.5 0.4 -0.1 三关数据和可解性检查
AIGC 辅助开发 1.0 1.5 +0.5 需求、编码、调试和整理
测试与修改 1.0 0.7 -0.3 自动化测试、流程测试、截图
README 与博客撰写 1.0 1.0 0.0 说明文档、AIGC 记录和报告
合计 7.5 7.9 +0.4

十、Git 使用情况

项目已初始化本地 Git 仓库,并创建了以下有意义的提交:

86c8c28 feat: add arrow puzzle rules and level data
eaf4bd7 feat: implement pygame board and game flow

测试文件已经加入暂存区。由于当前执行环境在后续 Git 索引写入时受到权限限制,测试、README、截图和本报告需要在本地完成最后一次提交。建议在确认内容后执行:

git add test_game_logic.py README.md 作业报告.md screenshots requirements.txt .gitignore
git commit -m "test: add coverage and course report"

然后绑定自己的 GitHub 仓库并推送:

git remote add origin <你的 GitHub 仓库地址>
git branch -M main
git push -u origin main

屏幕截图 2026-09-17 014708

十一、心得体会

11.1 AIGC 带来的帮助

AIGC 适合帮助我快速把自然语言需求拆成模块。例如,作业要求同时包含路径判断、碰撞反馈、关卡流程和测试,如果直接从一个大文件开始编写,很容易把界面绘制和游戏规则混在一起。通过让 AI 先设计纯逻辑模块,我可以在没有打开图形窗口的情况下测试最重要的判断逻辑。

AI 还帮助我补充了关卡可解性检查、状态机和测试用例,使开发过程不只关注“能显示”,也能检查“能不能通关”。

11.2 需要人工判断的地方

AI 给出的代码不能直接视为正确答案。实际检查中,重点需要人工确认:

  • 方向坐标的正负号是否一致。
  • 箭头飞出动画过程中是否仍被其他箭头认为是阻挡物。
  • 结果面板中的按钮是否超出面板边界。
  • 关卡是否真的存在可通关顺序。
  • README 中的测试结果是否与实际执行结果一致。

本项目中通过 unittestsolve_level() 检查规则,通过 Pygame 无窗口渲染检查界面,并根据检查结果修改活动箭头集合和结果面板布局。

11.3 本次收获

这次作业让我理解了一个小游戏通常由“数据表示、规则判断、界面绘制、输入事件和状态管理”几部分组成。即使规则很简单,也需要处理边界、动画时序和失败状态。AIGC 可以提高初始实现速度,但最终能否提交仍取决于开发者是否运行、测试和理解代码。

posted @ 2026-09-17 01:57  frochen  阅读(3)  评论(0)    收藏  举报