chen673
欢迎来到🍊的博客世界ㅇㅅㅇ
项目 内容
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice?page=4
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/homework/16718
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401303
GitHub 仓库 https://github.com/cheng0673/arrow-game-cz

一、项目展示(ง •̀_•́)ง:

开始界面

初始页面展示1

游戏过程

游戏过程

通关界面

通关

失败界面(有个小彩蛋在此!)

没通关

二、项目介绍=ᗜωᗜ=:

2.1游戏规则
我将用最直白、最不绕弯子、最一针见血的告诉你:点箭头,让它飞出去,飞出去就消失,全部消失就赢!

2.2界面设计小巧思💡:
整体风格走的是童趣+糖果色 + 圆角 + 果冻质感 路线,每个箭头上面还有可爱的小表情,而且箭头碰撞会变成哭哭(╥_╥)/的表情哦(就是上面说的小彩蛋,全是细节吧!)。同时背景设计了一个10s为一个循环的日夜更替,保证页面动态,点击开始游戏后会有主题风格选择,同时每个关卡还有不同难度等级设计,各位玩家还可以根据实际情况选择是否挑战“限时模式”,考验手速的时候到了!迎难而上!挑战自己吧!
image

image

2.3功能与特色
1.有许多通关玩法,你可以选择正常闯关、限时挑战、随机关卡,同时设计了异形关卡,可以多换换口味,比如下面这个苹果、葡萄关卡
imageimage

2.同时增加了连击加分机制,让玩家在游戏中挑战更高分,如果不小心走错了也没关系,可以撤销上一步,世上可能没有后悔药,但在我这里有嘿嘿嘿,详细呈现大家可以看下方演示
撤回和提示3

3.为了满足我个人的换装喜好,我还设计了一个对四方向箭头颜色以及表情的游戏设计界,快来设计属于你的专属闯关页面吧啊哈哈哈,总有一款表情和颜色属于你,如果没有那我再加、、同时在这个界面也可以通过滑动条调整游戏音量~ദ്ദിˊᗜˋ)
image

4.那就有人问了,玩到一半不小心关闭了怎么办?不用担心!为此我特意设计了游戏进度保存功能,关卡会保留在你上次运行的进度,再也不用担心一朝回到解放前,从新手村重新开始惹₍^ >ヮ<^₎ .ᐟ.ᐟ
image
image

三、实现思路:

3.1箭头和方向表示

3.1.1方向——Direction 枚举
model.py#L18-L33 中定义了四个方向,每个方向用(dr, dc)`位移量表示:

方向 枚举值 dr(行位移) dc(列位移) 字符
Direction.UP -1 0
Direction.DOWN +1 0
Direction.LEFT 0 -1
Direction.RIGHT 0 +1

3.1.2箭头——ArrowSpec三元组
一支箭头就是(r, c, d) 三个值——它在第 r 行第 c 列,朝 d 方向射。
ArrowSpec = tuple[int, int, Direction] # (行号 r, 列号 c, 方向 d)

3.2关卡——dict字典

3.2.1像素画棋盘
levels.py#L405-L420 定义了 14 色调色板,用字符代表颜色,例如苹果图案的顶部几行:

.....bbb.......
....bgggb......
....ggg#.......
....####.......

其中b是棕色果柄、g是绿叶、#是红色果身(主体格,可放箭头)。_parse_mask()函数把这种字符图案解析成两个集合:cells(所有格子及其颜色,供渲染用)和playable。

3.2.2关卡生成——逆向构造
正向思维 :摆好箭头 → 检查能不能解 → 不能就重摆(暴力枚举,几乎不可能找到可解的密集关卡)。
**逆向思维 **:从空棋盘开始, 倒着放箭头 ——先放最后一个被消除的,再放倒数第二个……每放一个,只要保证它前方射线上没有已摆放的箭头,那么按放置的逆序点击就一定能通关!

for 每次尝试 (attempts=80):
    occupied = 空集
    placed = 空列表
    
    for 要放 count 支箭:
        1. 遍历所有 active 格子,找出"至少有一个方向射线畅通"的候选格
        2. 对候选格的每个畅通方向,记录 blocked_by 值(该格被多少支箭挡着)
        3. 「最深优先」策略:优先选被挡最多的格子(制造更紧密的依赖关系)
           - 密度≥80%时放宽偏好(否则贪心必失败)
        4. 随机选一个 (格子, 方向),放入 occupied 和 placed
        5. 更新该方向射线上所有格子的 blocked_by 计数
    
    如果放满 count 支 → 记录为候选解,保留 blocked_by 总分最高的
    
如果全部失败 → 启用保底构造

3.3路经检测方法

3.3.1核心函数_ray_clear

def _ray_clear(occ, rows, cols, r, c, d):
    """(r,c) 朝 d 方向的射线上(不含自身)没有已占据格子。"""
    nr, nc = r + d.dr, c + d.dc
    while 0 <= nr < rows and 0 <= nc < cols:
        if (nr, nc) in occ:
            return False       # 遇到阻挡,射不出去
        nr += d.dr
        nc += d.dc
    return True                # 一路走到棋盘边缘,畅通

执行过程 (以 → 方向为例):

棋盘:  →  ·  ·  ↓  ·  |
       (0,0)(0,1)(0,2)(0,3)(0,4) 边缘

点击 (0,0) 的 →:
  nr=0, nc=1 → 不在 occ 中,继续
  nr=0, nc=2 → 不在 occ 中,继续
  nr=0, nc=3 → (0,3) 在 occ 中(有↓箭头)→ return False ❌
-------------------------------------------------------
棋盘:  →  ·  ·  ·  ·  |
点击 (0,0) 的 →:
  nr=0, nc=1 → 空,继续
  nr=0, nc=2 → 空,继续
  nr=0, nc=3 → 空,继续
  nr=0, nc=4 → 空,继续
  nr=0, nc=5 → 越界(nc >= cols)→ return True ✅ 畅通!

四、AIGC 使用过程:

本项目全程借助 Trae AI 辅助开发,覆盖代码编写、关卡设计、Bug 排查、测试用例编写与美术方案等环节。总体使用情况如下表:

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
游戏核心框架 Trae AI 生成 Pygame 主循环、场景状态机、按钮组件骨架 框架可运行,但场景切换逻辑有冗余 精简场景管理结构,统一事件处理入口
路径检测 Trae AI 实现四方向射线扫描 _ray_clear,沿 dr/dc 步进查阻挡 基本可用,异形棋盘装饰格被误判为阻挡 改为 occupied 集合只存箭头坐标,装饰格射线天然可穿过
关卡逆向构造 Trae AI 实现 reverse_generate_masked 逆向摆放 + 贪心选位 矩形棋盘正常;高密度困难关卡频繁生成失败 密度≥80%自动放宽贪心偏好,并补写保底构造算法
像素画图案设计 Trae AI 用 14 色调色板字符绘制 6 水果 + 6 动物图案 首版形状偏方块、猫兔面部出现空洞裂缝 多轮目检后重画:苹果改正圆、葡萄改果粒串、五官全部填满
主题选择流程 Trae AI 生成主题选择页、选关页、难度弹窗及卡片组件 流程跑通,但三主题存档键和解锁逻辑混在一起 拆分独立存档键,水果动物全解锁、默认顺序解锁
界面美化 Trae AI 生成糖果色渐变背景、果冻质感格子、圆角按钮 卡片底色不统一、标题副标题间距太近 三卡片统一白底,描述文字改黑色,全局拉开间距
难度分级与限时挑战 Trae AI 实现三档箭头数量控制及倒计时模式 高难度参数与生成器不匹配导致坏档 重新校准三档密度比例与目标箭头数阶梯
加载性能优化 Trae AI 降低 attempts、新增磁盘缓存 首次 0.4-2.3 秒,二次启动毫秒级 发现缓存无版本号,补加图案内容 hash 版本校验
存档系统 Trae AI 实现 JSON 序列化、继续/重置弹窗、旧存档迁移 tuple 颜色键无法直接序列化 增加 cells/playable 字段转换,旧中途存档自动清理
测试与验证 Trae AI 编写 21 个单元测试及 36 关批量验证脚本 测试暴露出生成失败的隐藏 bug 修复生成器后,36/36 关全部精准命中目标

下面选取 3 次最有代表性的 AIGC 使用过程详细展开。


代表性过程一:路径检测——游戏的「心脏」

我提出的要求:实现箭头点击后的路径判定——箭头朝上下左右四个方向射出,射线路径上没有其他箭头就能飞出棋盘消除,有阻挡则消除失败。

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
路径检测 Trae AI 生成四方向射线扫描函数,沿 dr/dc 位移逐格检查,并处理棋盘边界 矩形棋盘一切正常;但加入异形棋盘后,苹果叶子、兔子五官等装饰格被误判为阻挡,旁边的箭头飞不出去 让 AI 把判定依据改为「当前箭头坐标集合 occupied」——装饰格不放置箭头、不在集合中,射线天然可穿过;同一函数对矩形和异形棋盘通用

代表性过程二:像素画图案——AI 画的苹果,是一块方宝石

我提出的要求:水果按现实配色和形状画——以苹果为例,中间红色、上面棕色的杆和绿色的叶子,形状要圆;动物要更形象,兔子拉长耳朵、加上眼睛鼻子嘴巴,像像素画一样。

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
像素画图案设计 Trae AI 设计 14 色字符调色板(g 绿叶、b 棕柄、k 黑五官、p 粉内耳等)和图案解析器,并画出 12 个图案的第一版 框架思路清晰,但实机效果不理想:苹果是方的像红宝石、葡萄像洋葱、猫兔脸中间空了一条缝(胡须和嘴巴一行只画 3 格),一点不可爱 让 AI 把图案放大逐格截图给我看,逐一下令修改:苹果按真像素圆宽度规律重画;葡萄推翻重画三版定为「绿叶梗在上、3-2-1 层果粒垂挂」;猫兔五官全部替换满行格子保证面部实心

代表性过程三:36 关批量验证——测试抓出了「看不见的坏档」

我提出的要求:编写脚本一次性生成全部 36 个异形关卡(12 图案 × 3 难度),验证每关都能生成成功,且箭头数量符合难度预期。

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
测试与验证 Trae AI 编写批量生成与校验脚本,输出每关的目标箭头数与实际生成数 直接抓出大问题:草莓困难、西瓜困难两关全部生成失败,箭头数从 87/81 的目标回退到 49/46,比简单档还少;这种坏档靠手工试玩几乎不可能发现 与 AI 一起定位根因(贪心「最深优先」偏好在高密度棋盘钻牛角尖),确定方案:密度≥80% 自动放宽偏好,仍失败则启用保底构造算法;修复后重测 36/36 关全部精准命中目标箭头数

五、测试结果:

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失,剩余箭头数减 1 箭头沿方向飞出棋盘边缘并播放消除动画,剩余箭头数正确减 1 ✅ 通过
T02 点击前方有其他箭头阻挡的箭头 箭头不消失,失误次数减 1,播放碰撞反馈 箭头原地不动,失误次数减 1 并显示晃动碰撞效果 ✅ 通过
T03 点击位于棋盘边缘且朝向棋盘外的箭头 箭头正常消失,不发生数组越界错误 边缘箭头直接消除,无越界报错(边界条件已正确处理) ✅ 通过
T04 消除本关全部箭头 显示通关结算页,按步数与失误数给出 1-3 星评价 清空最后一支箭头后弹出结算页,星级按表现正确计算 ✅ 通过
T05 失误次数耗尽 / 倒计时归零 均正确判定失败,允许重新开始本关 失误 3 次、超时两种情况均弹出失败页,可点击重新开始 ✅ 通过
T06 点击异形棋盘装饰格(苹果叶子、兔子五官等) 装饰格不放箭、不可点击,箭头射线可正常穿过装饰区域 装饰格无点击响应,射线穿叶/五官区域检测结果正确 ✅ 通过
T07 三主题解锁逻辑验证 默认主题顺序解锁(未通关灰显带锁),水果/动物 12 关全部解锁可自由选择 默认第 2 关起灰显带锁;水果/动物 6 关全彩色可点 ✅ 通过
T08 简单/中等/困难三档箭头数量验证 三档箭头密度依次递增(约 50%/70%/88%),且每档布局 100% 保证可解 三档箭头数实测递增,solve() 验证全部存在通关顺序 ✅ 通过
T09 36 个异形关卡批量生成验证 全部关卡精准命中目标箭头数、无一失败 修复前:草莓/西瓜困难档生成失败回退(49/46 支);修复后(高密度放宽贪心 + 保底构造):36/36 关全部精准命中 ✅ 通过(修复后)
T10 关卡加载速度测试 首次生成 < 3 秒,二次启动毫秒级 优化前:10-20 秒/关;优化后(attempts 降至 80 + 磁盘缓存 + hash 版本校验):首次 0.4-2.3 秒,二次启动 < 5ms ✅ 通过(优化后)

六、PSP 表格:

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

差异说明(实际比预估多 12 小时,主要超支点):

  • 关卡设计(+4h):12 个异形图案并非一次画成——苹果从「方块宝石」改到真像素圆、葡萄重画 3 版才定稿成串状果粒、猫兔面部空洞问题排查,逆向构造的保底算法也花了额外时间。
  • 测试与修改(+3h):36 关批量验证暴露了草莓/西瓜困难档坏档问题,修复生成器后又做了全量回归;加载性能优化(磁盘缓存 + hash 版本号)也是计划外的工作量。
  • 游戏界面实现(+2h):主题卡片白底统一、标题副标题间距、音量键位置反复调整了多轮,属于「看着不满意就得改」的视觉打磨。
    节省的部分:Python/Pygame 基础语法比预想熟悉,且 AIGC 在样板代码(按钮组件、渲染循环)上提速明显,学习阶段少花了 1 小时。

七、心得体会:

AI 到底帮了我什么?

这次开发我全程都在跟 AI 结对编程,最大的感受是:它真的像一个傻但不知疲惫的搭档
那些机械重复的活儿,它干得又快又好——按钮组件、场景切换、渲染循环,我描述清楚需求,它几秒钟就给我一版能跑的骨架。特别是写像素画棋盘的时候,我要的是 14 种颜色的字符系统,它不仅帮我把调色板和解析器写出来了,还顺带给每个水果、动物都画了第一版草图,让我在这个基础上改,比对着空白文件发呆强太多了。
当然,它也没少让我生气,它的第一版方案经常“看起来像那么回事,细一看全是问题”。
就说那个苹果,我明明想要圆滚滚的,它给我画了个方块宝石;葡萄更绝,第一版像个洋葱,第二版像个灯泡,(`Д´)我硬生生让它重画了三版才变成现在这串正经的葡萄。
所以说,AI 给的是起点,不是终点。

我自己的收获

这趟下来,收获远不止一个能跑的游戏:
技术上,我第一次完整走通了「需求 → 设计 → 实现 → 测试 → 迭代」的流程。逆向构造算法的思维方式让我特别受启发——正着解不了的难题,倒过来想居然豁然开朗。还有单元测试,以前总觉得写测试是负担,这次真的是测试帮我抓出了大 bug,从此对「21 个测试全绿」有了执念哈哈哈。

方法上,我学会了怎么跟 AI 高效合作:需求要描述得具体;它给的代码一定要跑、要看、要质疑;大改动之前先commit一次做个记录,防止后面跑歪了还能即使回退。最后我明白了,AI 时代最值钱的能力,是提问和判断,而不是打字

最后

从一个方格子小游戏,到现在这个有三种主题、24 个关卡、还能看像素画的「糖果世界」,我玩着自己写的游戏通关的时候,是真的开心,而且这种cos产品经理压力ai的感觉好爽啊哈哈哈哈哈哈哈哈哈哈哈!(≖ᴗ≖✿)

谢谢 AI 这个嘴快但靠谱的搭档,也谢谢那个没有在它连苹果长啥样都不知道时选择「凑合交了」的自己。✧。٩(ˊᗜˋ)و✧*。
下一个项目,继续加油!

posted on 2026-09-22 20:05  chen673  阅读(9)  评论(0)    收藏  举报