2026秋软件工程个人作业(第二次):一箭又一箭

2026秋软件工程个人作业(第二次):一箭又一箭

项目 内容
这个作业属于哪个课程 202601 软件工程班级博客
这个作业要求在哪里 第二次个人作业要求
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401128
GitHub 仓库 https://github.com/kasinglee/ArrowAfterArrow

项目展示

本项目使用 Pygame 绘制 810 × 1440 的手机竖屏逻辑画布,窗口缩放时保持比例。基础玩法是本作业的主体;开始页还提供进阶玩法入口和中英文切换,进阶玩法及后文所述附加功能均建立在完成基础要求之后。

开始界面基础玩法:单格箭头
碰撞反馈通关结果
失败结果进阶玩法(附加功能)

以上截图与 GIF 均来自本人于 2026 年 9 月 14 日的实际运行记录,分别展示开始、基础关卡、碰撞、通关、失败和附加玩法的界面效果。

项目介绍

“一箭又一箭”是一个通过观察方向与遮挡关系决定点击顺序的点击式解谜游戏。点击一支箭头后,程序检查它朝向棋盘边界的直线路径:没有任何箭头占用时,箭头飞出棋盘;路径被占用时,箭头撞击后变红、返回原位并扣除一次机会。每局有 3 次机会,清除全部箭头即可通关,机会耗尽则失败并可重新开始。

在完成作业规定的基础玩法后,本项目再提供一个附加模式:

  • 基础玩法(作业主体):每支箭头只占一个网格,方向为上、下、左、右,完全按作业题目的统一判定实现。
  • 进阶玩法(附加功能):每支箭头是一条尾部到头部的正交折线路径,形状类似贪吃蛇。只有头部最后一段朝向的射线用于判定;射线命中其他箭头或自身较早的轨迹都会碰撞。

两种模式均包含 5 个固定关卡和随机关卡;还实现了关卡选择、计时、得分、星级、提示、撤销、进度保存、重置存档、内置自动求解、程序生成音效与 Windows EXE 打包脚本。项目已使用 PyInstaller 打包为 Windows .exe 可执行文件,便于在未配置 Python 环境的电脑上直接运行。基础模式始终保持单格箭头,便于直接展示题目要求的路径检测;进阶模式的长轨道箭头则作为额外尝试。

界面采用手机竖屏布局:顶部集中显示关卡、剩余箭头和失误次数,中部为棋盘,底部放置重来、提示、撤销和自动求解等操作。开始、游戏、通关和失败页面均有明确的状态提示,保证玩家能理解当前操作与结果。

我的参与

本项目由我独立完成需求分析、功能取舍、代码整合、运行调试和最终测试。AIGC 主要帮助我学习 Python/Pygame、提供代码结构和排查思路;我没有直接照搬生成结果,而是逐段阅读关键代码、运行程序、比较实际效果,并根据作业要求和试玩体验进行修改。特别是基础玩法是否符合题目、进阶箭头是否应沿轨迹移动、关卡是否真的可通关,都是我在实际检查后做出的决定。

实现思路

数据表示与路径检测

Direction 枚举保存四个方向及其行列增量。Arrow 使用有序的 cells 保存占用格:基础箭头只有一个格并显式保存方向;进阶箭头包含两个或更多连续格,方向由最后一段路径自动推导。Board 维护“网格坐标 → 箭头”的占用表,因此点击网格即可找到对象。

核心检测从箭头头部的下一格开始,按方向循环到棋盘边界:

cell = head + direction.delta
while cell 在棋盘内:
    如果 cell 被占用:返回阻挡物
    cell += direction.delta
返回无阻挡

基础模式中 head 就是单格箭头自身的位置;进阶模式中 head 是轨迹最后一个格。进阶模式统一查占用表,因此头部射线命中自身较早的轨迹也会正确判定为碰撞,不会产生“看似可飞出、实际会撞到自己”的错误。

在实现和学习过程中,我重点理解了 Direction.delta 如何把方向转换为行列增量,Board.first_collision 如何沿射线逐格查找,以及 GameSession.click_arrow 如何根据检测结果更新机会、历史和关卡状态。最初试玩时我发现把整支折线整体平移会产生不符合玩法的效果,因此主动要求改为头部前进、尾部沿旧轨迹跟随,并通过动画测试确认转弯处仍保持直角。

可解关卡生成与验证

基础随机关卡采用“反向剥离”构造:先随机选择若干占用格,再反复寻找当前沿某个方向可以直达边界的格子,记录该格的移除顺序与方向。反向得到初始棋盘后,这个记录顺序就是零失误通关证书。生成时会优先让箭头朝向已移除的区域,使布局存在合理依赖而不是全部箭头同时可消除。

进阶满盘生成器先生成经过所有格的 Hamilton 路径,再使用 backbite(端点回咬)变换打乱路径拓扑;该变换保持“连续、无重复、覆盖全部格”三个性质。之后将整条路径随机切成长度和转弯数不同的箭头,并从满盘状态向外剥离:只有头部射线不碰到任意轨迹(包括自身)的片段才可被选中。程序记录每次成功剥离的箭头 ID,并调用验证器逐步复放,确保每张固定关和随机关都有零失误解。

存档与自动求解器

存档保存在 JSON 文件。源码运行时文件是项目根目录的 savegame.json;打包版使用 %LOCALAPPDATA%\ArrowAfterArrow\savegame.json。文件包含进阶/基础玩法各自的解锁进度、最高分、最高星级与语言设置。读取时对值做范围限制;写入失败不会影响游戏运行。重置存档需要二次确认,只清除解锁与成绩记录,保留当前语言。

内置自动求解器不调用外部在线模型,而是使用与验证器相同的确定性规则:复制当前未消除箭头组成快照,不断扫描可飞出的箭头,选取第一支并从快照移除;若某一步没有候选箭头就返回无解。已生成关卡带有构造证书并会在生成后验证,因此求解器可以找到完整顺序。界面再按该顺序模拟点击并播放动画;为了区分玩家自己完成与演示,使用自动求解的本局最多获得 1 星。

AIGC 使用过程

下面选择几次代表性协作过程。每次协作中,我负责提出具体问题、运行和比较结果,并决定是否采用 AI 的建议:

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 实际效果如何 人工修改
基础玩法恢复与测试 OpenAI Codex 在进阶玩法旁加入单格箭头模式、独立进度、固定/随机关及测试 我运行开始页、关卡页和基础关卡,确认单格箭头符合题目规则 我保留基础模式作为作业主体,检查四方向、边界和阻挡扣机会,并补充 T07、T08、E22
进阶轨道玩法建模 OpenAI Codex 提供多格正交轨迹、头部射线判定与贪吃蛇式动画结构 我试玩后发现整体平移不符合参考玩法 我明确要求只检查头部射线、尾部沿旧轨迹跟随,并要求自身轨迹也能阻挡
可解关卡生成 OpenAI Codex 提供反向剥离证书、满盘 Hamilton 路径与 backbite 拓扑随机化方案 我查看生成布局并按顺序试玩,固定关和随机局均可通关 我调整棋盘密度、形状多样性、U 形比例和自身碰撞筛选
Python/Pygame 学习 OpenAI Codex 解释事件循环、Surface、Rect 点击判断和逻辑坐标缩放 我能读懂界面更新、鼠标点击和页面切换的主要流程 我根据实际窗口效果调整竖屏比例、棋盘位置、字体和按钮布局

测试结果

运行 python scripts/run_tests.py 会生成自动化测试的 Markdown 和 PNG 证据。测试首先覆盖作业要求的单格箭头、四方向、边界、阻挡扣机会、通关、失败和重开;长轨道箭头、提示、撤销、保存、随机生成、自动求解器、动画和界面流程则作为扩展测试。

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的基础单格箭头 飞出并消失 箭头被移除,余量减少 通过
T02 点击前方有阻挡的基础单格箭头 不消失,机会减 1 箭头保留,机会减 1 通过
T03 位于边缘且朝向棋盘外的单格箭头 正常飞出且不越界 通过边界测试 通过
T04 清除基础关卡全部箭头 显示通关并进入下一关 最后一支箭头后进入通关状态 通过
T05 基础玩法连续三次碰撞 显示失败并允许重新开始 第三次碰撞后进入失败状态 通过
T06 基础玩法进行中重新开始 布局和机会恢复 棋盘、生命、历史恢复初值 通过
T07 基础单格箭头四方向路径检测 同行/列阻挡扣机会,清空后可飞出 显式方向与边界判定正确 通过
T08 基础固定/随机关 均存在零失误解 5 个固定关与多种子证书通过验证 通过
E19 进阶箭头头部撞自身轨迹 视为阻挡 扣命且箭头保留 通过
E22 基础模式界面流程 可进入、显示单格箭头、自动求解器可完成 开始页和关卡页流程通过 通过

除了自动化测试外,我还在 2026 年 9 月 14 日 21:00 左右进行了人工试玩。我亲自从头到尾测试了基础玩法和进阶玩法的 5 个固定关卡,观察每一步可点击的箭头并按合理顺序完成通关;另外测试了 2 局随机关卡,也都可以正常完成。试玩过程中我主动检查了箭头点击、阻挡扣除机会、碰撞反馈、通关结果、失败结果和重新开始功能,未发现无法通关或越界问题。

人工测试范围 我的操作 实际结果 是否通过
基础玩法固定关卡 1—5 逐关观察方向并按合理顺序点击 全部可以正常通关 通过
进阶玩法固定关卡 1—5 逐关沿箭头轨迹判断头部出口并点击 全部可以正常通关 通过
随机关卡 2 局 分别运行随机棋盘并尝试完整通关 两局均可以正常完成 通过
点击、阻挡、碰撞、失败、重开和通关流程 手动触发并观察界面反馈 操作和反馈均正常 通过

PSP 表格

任务 预估耗时(小时) 实际耗时(小时) 差异(小时)
需求分析与游戏设计 1.0 0.5 -0.5
Python 与图形库学习 1.5 2 0.5
游戏界面实现 1.0 0.5 -0.5
路径与碰撞逻辑实现 1.0 0.5 -0.5
关卡设计与生成器 1.0 0.25 -0.75
AIGC 辅助开发与人工修改 1.0 1.5 0.5
测试与修改 1.0 2 1.0
README 与博客撰写 1.5 1 -0.5
合计 9.0 8.25 -0.75

心得体会

本作业中,AIGC 对快速建立 Pygame 界面、拆分游戏逻辑与测试脚本非常有帮助,但不能替代对规则的理解。开发过程中最重要的修改来自实际试玩和对参考玩法的反复比对:先发现单格模型无法表达进阶轨道玩法,再发现整条箭头刚体平移不正确,最后补上头部射线撞自身轨迹的规则。每一次修改都同步增加了自动化回归测试,避免后续优化生成器或动画时重新引入错误。

另一个收获是“随机生成”不能只看画面随机。游戏生成器让游戏生成的多样化的同时,也要必须让游戏可解,否则很容易生成无解或体验不合理的棋盘。(虽然羊了个羊、一箭又一箭等游戏大概率可以避免游戏可解,以吸引更多人观看广告或充值)基础玩法和进阶玩法分别保留,使我既能展示题目规定的单格路径检测,也能展示在此之上扩展的轨道、满盘生成与自动求解功能。

通过这次作业,我实际掌握了用枚举表示方向、用数据类组织游戏对象、用集合维护棋盘占用关系,以及用 unittest 编写边界和状态测试。AI 可以帮助我快速获得可运行的起点,但最终哪些规则正确、哪些动画自然、哪些关卡真的能通关,仍然需要我自己运行、观察和判断。

最后对于 AIGC 和 Agent 有以下体会:在目前这个 Agent 发展的时代当你舍得烧 Token 的时候 Angent 可以通过大量的 COT、大量的大参数模型(比如GPT5.6 Sol、 GPT6 Astra)、1M 的 context 等等经过长时间的编码、编译、验证之后也是可以达到很好的效果,但是副作用就是会及其消耗 Token 以及上下文。但是如果引入一个所谓产品经理的人类,就算编码能力不需要很强,也能节省很多时间和 Token,可以在短时间内达到更好的效果。当然如果是一个完全不懂的人类,那你就是 codex 的阻碍还不如让他自己来,,,我曾经试过 prompt 里面让 llm 自己选 UI 的架构、或者不 prompt UI的风格,他的效果会比较参差,因此学习依旧是非常重要的。

这次经历也让我认识到,学习编程不能只关注代码能否运行,还要理解代码背后的规则和设计原因。通过自己提出需求、检查 AI 生成的结果并进行修改,我对 Python 和 Pygame 的使用更熟悉了,也积累了从需求分析到测试验证的完整开发经验。

posted @ 2026-09-15 10:55  Jasonxdd  阅读(44)  评论(0)    收藏  举报