AIGC标识 软件工程第二次个人作业——《元素之箭 · 一箭又一箭》

《元素之箭 · 一箭又一箭》—— AIGC 完成箭头解谜小游戏

项目 内容
这个作业属于哪个课程 软件工程与软件工程实践(福州大学)
这个作业要求在哪里 作业链接
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102402138
GitHub 仓库 https://github.com/Xun1342/Software-Engineering-Assignment-2-elemental-arrows

一、项目展示

GIF展示
QQ20260922-205502

开始界面:七元素彩带云海背景、玩法说明、入口按钮,右上角是原创精灵向导「灵灵」。

image

游戏过程:竖版 540×860,网格点阵棋盘,七元素配色的宝石箭头,HUD 实时显示时间 / 步数 / 剩余 / 失误心形;点“提示”后当前可飞出的箭头会带金色脉动描边。

image

通关 / 失败界面:通关时精灵庆祝、彩屑飘落,三颗星依次弹出并按失误次数评星;失败时精灵安慰并允许重开。

image

选关与随机关卡:六个手工关卡卡片(星级、最佳成绩、锁定状态),另有“随机试炼”每次生成全新可通关棋盘。

image


二、项目介绍

这是一个用 Python + pygame-ce 实现的点击解谜小游戏:观察每支箭头的方向,按正确顺序点击,让所有箭头依次飞出棋盘。全部素材均为原创生成,未使用任何商业游戏的代码、美术、音效或关卡。

规则:

  • 点击一支箭头,程序沿它的朝向扫描,检查同一行(左右)或同一列(上下)上、箭头到棋盘边界之间是否还有其他箭头;
  • 前方没有箭头 → 加速飞出棋盘并消除,播放星光爆发与音效;
  • 前方有箭头 → 原地晃动警示、红屏闪烁、扣一次失误;
  • 清空全部箭头通关,按失误次数评星;失误耗尽则失败。

主要功能与特色:

  1. 六个手工设计关卡(5×5 ~ 8×8,6~22 支箭头),难度递进;
  2. 提示按钮:金色脉动高亮当前所有可飞出的箭头(快捷键 H);
  3. 计时、步数统计、撤销(Z)、重开(R);
  4. 选关界面 + 三星评价 + 本地存档(save.json 记录星级、最佳成绩、解锁进度);
  5. 随机关卡:逆向摆放算法即时生成 7×7、15 箭、保证可通关的新棋盘;
  6. 自动演示:DFS 求解器求出通关顺序,由精灵逐支自动飞出,可随时停止;
  7. 奇幻表现:原创白色精灵向导「灵灵」(圆身体、小翅膀、四角星天线,有开心/惊讶/沮丧/庆祝表情和对话气泡)、七色环境光点、飞出星光、碰撞火星、通关彩屑。

三、实现思路

3.1 数据表示

棋盘用二维网格,每支箭头就是一个 (行, 列, 方向) 三元组,方向是 U/D/L/R 四个字母之一;元素色按七元素循环编号。关卡就是一个字典,直接写在 game/levels.py 里,以后扩关只需追加一个字典:

{
    "name": "风起 · 试炼",
    "rows": 5, "cols": 5,
    "mistakes": 3,          # 允许失误次数
    "accent": 2,           # 本关主色(七元素之一)
    "arrows": [(0, 1, "L"), (0, 3, "R"), (2, 0, "U"),
               (2, 2, "U"), (2, 4, "D"), (4, 2, "U")],
}

3.2 核心:路径检测

这是整个游戏最关键的一段。方向先换算成行列增量 (dr, dc),然后从箭头的相邻格开始一步一步走向边界;一路上只要碰到任何还没飞出的箭头,就说明“被挡住”,返回不可飞;走到边界都没碰到,就是可以飞出。

def is_clear_to_edge(self, arrow):
    """判断沿箭头朝向到边界之间是否还有其他箭头。"""
    dc, dr = S.DIRS[arrow.direction]     # 方向 -> (列增量, 行增量)
    r, c = arrow.row + dr, arrow.col + dc
    while 0 <= r < self.rows and 0 <= c < self.cols:
        other = self.arrows.get((r, c))
        if other is not None and other.state != "gone":
            return False                # 被挡住
        r += dr
        c += dc
    return True                         # 一路畅通,可以飞出

“提示”和“自动演示”都复用它:把所有箭头过一遍筛出 idle 且 is_clear_to_edge() 的集合即可。

3.3 撤销:快照/恢复

撤销没有去做复杂的命令栈,而是在每次成功飞出之前,把当前所有待机箭头的 (行, 列, 方向, 元素色) 存进一个栈;撤销时出栈一份重建棋盘,同时恢复当时的失误数和步数:

def snapshot(self):
    return [(a.row, a.col, a.direction, a.element_idx)
            for a in self.arrows.values() if a.state == "idle"]

def restore(self, data):
    self.arrows = {(r, c): Arrow(r, c, d, e) for r, c, d, e in data}

3.4 随机关卡为什么“保证有解”

如果随机乱摆箭头,很容易生成无解死局。这里用逆向摆放:从空棋盘开始,每次随机放一支箭头,只放在“沿它的方向到边界之间还没有任何已放箭头”的位置。这样放完之后,按摆放顺序倒过来点,就一定能通关。生成后再用一个独立的 DFS 求解器验证一遍,双重保险:

def solve(arrows, rows, cols):
    """DFS 求一个通关顺序;无解返回 None。"""
    state = {(r, c): d for r, c, d in arrows}
    def dfs(st, path):
        if not st:
            return path
        for (r, c), d in list(st.items()):
            if clear(st, r, c, d, rows, cols):   # 该箭头当前无阻挡
                nxt = dict(st); nxt.pop((r, c))
                found = dfs(nxt, path + [(r, c, d)])
                if found is not None:
                    return found
        return None
    return dfs(state, [])

四、AIGC 使用过程

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
路径检测与游戏骨架 豆包2.1Pro 生成四方向行列扫描、飞出/碰撞动画、主循环与界面切换初版和其他游戏主体框架 不能跑 查找报错,是本地编译器问题,切换编译器和下载相关软件,成功运行
自动化测试 豆包2.1Pro 按 T01–T06 写 unittest 验收用例,并补了 T07–T13 13 个用例一次基本通过 无
美术背景与音效 豆包2.1Pro 文生图生成七元素云海背景;用标准库波形合成 5 个音效 无版权风险、体积小 无
使用记录如下:
生成整体游戏框架
f08b6a16-bafb-4d3d-91ba-8256ab1b7290
09b6b375-b6b1-46dd-8b47-6230c06c65fb
处理报错
cc3e4bf2-0585-4446-abdd-882c655ceee5
增加功能
image

五、测试结果

自动化测试
image
image

用例文件 tests/test_acceptance.py,在无头环境(SDL_VIDEODRIVER=dummy)下驱动真实游戏帧循环运行,共 13 个用例,全部通过:

$env:SDL_VIDEODRIVER="dummy"; $env:SDL_AUDIODRIVER="dummy"
python -m unittest tests.test_acceptance -v
# Ran 13 tests in 0.7s  —— OK

对应作业要求的 T01–T06:

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 进入 flying,动画结束后移除,剩余 6→5,失误不变 通过
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1 箭头晃动后仍在原地,失误 3→2,红闪提示 通过
T03 点击边缘、朝向棋盘外的箭头 正常消失,不越界 六关逐帧校验待机箭头坐标均在棋盘内,飞出无索引错误 通过
T04 消除本关全部箭头 显示通关并进入下一关 弹出结算面板,点“下一关”后装载第二关 通过
T05 失误次数耗尽 显示失败并允许重开 连续 3 次被挡后进入失败界面,重开后布局/失误复位 通过
T06 游戏进行中重新开始 箭头布局与失误数恢复 飞出+失误后重开,布局与初始完全一致,失误恢复 3 通过

扩展功能用例 T07–T13:提示高亮集合与可飞箭头一致、撤销可恢复、计时只在游戏中累计、随机关卡必有解、自动演示可清空棋盘、零失误记三星并持久化、未解锁关卡点击无效——全部通过。早期逻辑测试 tests/test_levels.py(路径检测、六关可通关交叉验证)也保持通过,无回归。

测试中发现并修复的问题:提示描边初版不醒目(改双层金色脉动)、结算按钮压住弹窗边框(重新排布)、选关锁定图标与文字重叠(调整卡片布局),均已复测通过。


六、PSP 表格

任务 预估耗时(小时) 实际耗时(小时) 差异(小时)
需求分析与游戏设计 1 1 0
Python 与图形库学习 1 0.1 0.9
游戏界面实现 0.5 0.5 0
路径与碰撞逻辑实现 0.5 0.5 0
关卡设计 0.2 0.1 0.1
AIGC 辅助开发 3 2.5 0.5
测试与修改 3 1 2
README 与博客撰写 3 1 2
合计 *12.2 6.7 5.5

七、心得体会

这次作业最大的体会是:AIGC 很适合“把骨架快速搭起来”,但“对不对、好不好玩”还得靠自己把关。路径检测初版能跑,可一旦没把“飞行中的箭头”从遮挡判定里排除,整个游戏规则就错了;随机关卡算法虽然巧妙,但如果不做求解器二次验证,很可能把无解死局交给玩家。这些坑 AI 不会主动告诉你,都是在写测试、实际试玩时才暴露出来的。

另一方面,小步提交 + 自动化测试帮了大忙:每加一个功能就跑一遍 T01–T13,哪里改坏了一眼就能定位;撤销、星级存档这些容易出回归的功能,也是靠无头测试把边界场景都覆盖到。再就是学会了重视版权意识——背景用文生图、音效用程序合成、精灵和界面全用代码画,全程没有抄任何商业素材,交作业心里踏实。

最后,“灵灵”这个原创小精灵和粒子特效虽然不影响玩法,但让游戏一下子有了灵气。以后再做类似项目,我会更早地把测试用例和存档结构设计好,少做返工。


仓库地址:https://github.com/Xun1342/Software-Engineering-Assignment-2-elemental-arrows

posted @ 2026-09-22 21:13  迅1342  阅读(15)  评论(0)    收藏  举报