软件工程第二次作业

软件工程第二次个人作业:用 Python 与 Codex 完成“一箭又一箭”

项目 内容
这个作业属于哪个课程 202601 软件工程
这个作业要求在哪里 软件工程课程第二次个人作业
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
姓名、学号 杜玉鹤,162404109
GitHub 仓库 myp208116/arrow-game

一、项目展示

游戏采用浅色背景和深绿色状态面板。首页可开始第一关,也可直接选择三个关卡。游戏界面中,棋盘与状态信息分开放置,剩余箭头、机会和计时始终可见。

开始界面

01-start

游戏过程与碰撞

02-game
03-collision

发生碰撞时,被点击的箭头变红并晃动,阻挡它的格子显示淡红色背景,底部显示提示。动画结束后扣除一次机会,两个箭头都保留在棋盘上。

通关与失败

05-win
09-fail

演示 GIF

demo

以上截图与 GIF 由自动化脚本向实际游戏事件处理函数传入鼠标事件,经过同一套更新和绘制流程生成。演示展示开始、碰撞、提示、第一关通关、进入下一关、失败和重新开始。它属于自动化演示,本人试玩情况另行记录。

二、项目介绍

1. 游戏规则

每个箭头占一格,朝向上、下、左、右之一。点击后检查它到棋盘边界之间的所有前方格子:

  • 没有其他箭头:沿指定方向飞出,然后从棋盘删除。
  • 存在其他箭头:播放碰撞反馈,保留箭头,扣 1 次机会。
  • 每关初始有 3 次机会,机会耗尽后失败,可重新开始。
  • 清空本关后显示结果,再由玩家点击进入下一关。
  • 空白格、棋盘外和右键点击均不扣次数。

2. 关卡设计

关卡 棋盘大小 箭头数量 设计重点
初见 5 × 5 12 理解前方阻挡与边界
交错 6 × 6 24 观察行列之间的消除顺序
回响 7 × 7 38 处理更密集的阻挡关系

三关均包含四个方向,关卡数据固定保存在 JSON 文件中。重新开始恢复同一布局,便于复盘。可解构造和求解器均已验证三关存在完整通关顺序。

3. 附加功能

实现了首页选关、合法箭头提示、计时、星级、本次运行内的完成标记、切换窗口后自动暂停,以及 Windows 独立程序打包。

提示会高亮一枚当前可以移除的箭头,不扣机会,但会影响星级。通关星级为 max(1, 3 - 失误次数 - 提示次数)。星级不依赖操作速度,计时只用于展示。

三、实现思路

1. 模块划分

core.py 实现箭头、棋盘、路径判断和游戏状态;levels.py 负责生成与加载关卡;app.py 负责界面、鼠标事件、动画和场景切换。这样的划分允许先测试规则,再测试界面流程。

2. 箭头和方向表示

每个箭头包含行号、列号、方向三个字段。棋盘使用字典保存占用关系:键是 (row, col),值是箭头对象。

方向 行变化 dr 列变化 dc
-1 0
1 0
0 -1
0 1

内部统一使用行列坐标,绘制时才转换为屏幕的 x、y。先统一约定可以避免把“向上”错误写成“向左”。

3. 路径检测

核心扫描逻辑如下,对应 Board.path()

dr, dc = arrow.direction.value
row, col = arrow.row + dr, arrow.col + dc
cells = []
while self.inside(row, col):
    cells.append((row, col))
    row, col = row + dr, col + dc

随后 blocker() 在这些格子中寻找第一个被占用的位置;若没有阻挡物,can_exit() 返回真。

从下一格开始是为了排除箭头自己。每次先判断行列是否在棋盘内,再访问占用信息,所以向上、向左不会出现负下标误判。只检查当前方向,位于后方或其他行列的箭头不会阻挡它。

一次检测最多扫描一整行或一整列,时间复杂度为 O(max(行数, 列数))。本项目最多 7 × 7 格,无需引入复杂的空间索引。

4. 如何保证关卡可解

如果完全随机设置位置和方向,可能出现两枚箭头相向而行、互相阻挡的死局。因此生成阶段先选定占用格,然后重复以下步骤:

  1. 在当前剩余占用格中,找出存在无遮挡出口的“位置、方向”组合。
  2. 随机选择一个组合,为这个格子确定方向。
  3. 从临时占用表中删除它,记录操作顺序。
  4. 所有格子都处理完成后,将箭头完整保存为关卡。

按记录顺序消除时,每一步前方都没有尚未消除的箭头,因此构造过程本身提供了一个解。程序还使用独立求解器逐轮移除合法箭头,复核正式关卡。

求解器可以使用贪心方法,因为移除箭头只会减少障碍,不会让其他箭头的路径变得更差。如果棋盘仍非空但没有任何合法箭头,才返回无解。

5. 动画和游戏状态

场景分为开始、游戏和结果三类。暂停是游戏场景的一个状态。点击箭头时建立动画对象,动画期间不接受新的箭头点击;动画结束后才更新逻辑棋盘、失误次数及胜负状态。

这个顺序避免重复点击造成重复扣次数,也让最后一枚箭头真正飞出之后再出现通关界面。玩家在动画中点击重新开始,会清除旧动画并重建游戏状态。

四、AIGC 使用过程

使用工具:Codex。本次开发在一次连续对话中按阶段推进,以下是实际发生的三个代表性协作环节,没有虚构额外的历史提问或本人手工改码经历。

子任务 我提出的要求或依据 AI 实现或提供了什么 实际效果 人工修改
规则与关卡 提供作业链接和完整正文,要求完成四方向判断、三关及失误机制 拆分 Board/Game;实现路径扫描、关卡构造、独立求解器和规则测试 首轮 14 项规则测试通过;三关全部可解;生成器验证 125 个布局 本人补充完整原题,确认需求;此阶段未手改代码
界面与动画 按原题要求制作开始、游戏、结果界面,加入飞出、碰撞和重新开始 实现 pygame 界面、动画锁定、碰撞后结算、鼠标操作和切关;添加提示、计时、星级 通过真实鼠标事件跑通三关,连点与动画中重开行为正常,生成截图和 GIF 本人确认“杜玉鹤 / 162404109”及目标仓库;实现由 AI 完成
测试、复核与交付 按原题 T01—T06、README、博客和真实 AI 记录要求整理交付 执行 23 项测试、检查实际截图、修正菜单文字间隔和计时截断问题、准备说明文档并打包 23 项测试通过;截图覆盖开始、碰撞、通关与失败;独立程序启动检查结果见仓库记录 本人完成实际试玩,并根据真实投入补充 PSP 与学习心得。

开发过程中保留了逐阶段更新的 docs/development.md 和 Git 提交。具体出现并修正的问题包括:

  • 开始界面的说明文字离装饰箭头过近。检查实际截图后,将文字下移,保留间隔。
  • 首版游戏循环将帧间隔限制为 0.05 秒,遇到低帧率会少计时。代码复核后改为使用实际帧间隔,暂停时仍停止累计。
  • 发布初期,GitHub 连接账号与目标仓库不一致,没有写权限;重新连接本人账号后已完成上传。本机 Git 直连失败,因此通过 GitHub 接口按真实开发阶段导入,各阶段代码树与本地完全一致。原始编号、开发时间及线上提交对应关系保存在 docs/publication.md,原始本地历史也保留在交付包中。

五、测试结果

测试环境为 Windows、Python 3.14.5、pygame-ce 2.5.8。共 23 项自动化测试通过,失败 0 项,错误 0 项。测试采用 unittest,界面测试使用 pygame 的离屏显示模式和真实事件处理函数。

编号 测试内容 预期结果 实际结果 是否通过
T01 前方无阻挡 飞出并消失,不扣次数 四方向均可消除,动画后只删除一次 通过
T02 前方有阻挡 不消失,机会减 1 四方向阻挡识别正确,红色晃动后扣 1 次 通过
T03 边缘且向外 正常消失,无越界 四条边分别验证通过 通过
T04 清空本关 显示通关并进入下一关 三关依次清空,前两关能切关,最后一关能返回或重玩 通过
T05 失误耗尽 显示失败并允许重开 第三次碰撞结束后失败,重开恢复 3 次机会 通过
T06 中途重新开始 布局和次数恢复 恢复初始布局、机会、计时和提示;取消旧动画 通过

额外验证了空白点击、鼠标右键、后方箭头不阻挡、最近阻挡物、求解器识别死局、20 次连续点击仅处理一次、失焦暂停和提示正确性。

测试报告保存在 docs/test-report.jsondocs/test-output.txt

本人试玩记录

在完成自动化测试后,我又对三个正式关卡进行了实际试玩,确认游戏流程、碰撞反馈、重新开始和通关功能均能正常使用。

关卡 本人试玩 结果
初见 已完成 可正常通关
交错 已完成 可正常通关
回响 已完成 可正常通关

六、PSP 表格

预估值在实现开始前记录,表示 AI 建议的学生实施预算。实际值由本人根据真实投入填写;差异 = 实际 - 预估。AIGC 辅助开发一行只统计独立阅读、交互及检查 AI 输出的时间,避免与编程、测试等阶段重复计算。

任务 预估耗时(小时) 实际耗时(小时) 差异(小时)
需求分析与游戏设计 0.5 1.0 +0.5
Python 与图形库学习 0.5 1.0 +0.5
游戏界面实现 1.5 1.5 0.0
路径与碰撞逻辑实现 1.0 1.5 +0.5
关卡设计 0.5 1.0 +0.5
AIGC 辅助开发 0.5 1.0 +0.5
测试与修改 1.0 0.5 -0.5
README 与博客撰写 1.0 0.5 -0.5
合计 6.5 8.0 +1.5

七、开发总结与心得

本次协作中,AI 的直接帮助是把完整作业拆成规则、关卡、界面、测试和交付几个部分,并快速形成可以运行和验证的实现。规则被独立出来后,不需要每次打开窗口就能检查四个方向和边界条件;界面完成后,再使用鼠标事件验证动画和切关流程。

这次实际复核也说明,“代码能运行”仍不足以保证体验完整。菜单说明文字与装饰图案的间隔需要看真实截图;计时是否准确需要检查帧间隔处理;上传到 GitHub 还取决于账号权限与网络。这些问题必须结合实际结果判断,不能仅根据 AI 对自己的说明下结论。

理解本项目的关键是三个约定:坐标统一使用行列、路径只扫描前方、删除箭头不会增加阻挡。在此基础上,碰撞检测、可解关卡构造和贪心求解都可以解释清楚。Git 中分阶段保存规则、界面、修复和文档,也便于回看每一步做了什么。

实际试玩时,我曾因为没有看清箭头前方是否存在阻挡而误点。后来我发现,通关时可以优先消除当前能够直接飞出棋盘的箭头,再根据棋盘变化逐步判断后续顺序。阅读代码后,我也理解了 Board.path() 的基本作用,即沿箭头方向逐格检查路径,判断前方是否存在其他箭头,从而确定该箭头能否移除。

八、运行方法与资料

安装运行依赖后执行 python main.py,或使用本地交付的 ArrowGame.exe。详细步骤、操作说明和资源位置见仓库 README。

参考资料:

所有箭头、按钮和关卡由本项目代码创建,未使用商业原游戏或他人的完整项目及素材。程序调用系统中文字体,不分发字体文件。

posted @ 2026-09-17 15:50  等一会  阅读(7)  评论(0)    收藏  举报