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

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

这个作业属于哪个课程 福州大学2026年软件工程
这个作业要求在哪里 福州大学2026 秋软件工程个人作业(第二次)
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401228
GitHub 仓库 点击此处传送

一、项目展示

这里我录制了B站视频,我的声音有点小,音效有点大声,请大家见谅。

可运行的程序,我放在Github上的Release上了.

下面是采用图表介绍的形式。

开始界面 关卡选择
01_start 08_level_select
游戏界面 箭头飞出
02_playing 03_flying
6x6 铺满(第 3 关) 8x8 铺满(第 4 关)
10_level3_full 11_level4_full
碰撞弹回 本关通过
05_bounce 07_all_clear
本关失败(失误耗尽,含彩蛋动图) 暂停菜单
06_game_over 13_pause
返回首页确认 AI 求解后的结算(彩蛋)
14_pause_confirm 15_ai_result

二、项目介绍

2.1 游戏规则

棋盘中分布着朝上、下、左、右四个方向的单格箭头。玩家点击某个箭头后,程序检查它前进方向到棋盘边界之间是否有其他箭头:

  • 路径畅通:箭头飞出棋盘并消失;
  • 路径被阻挡:箭头冲向阻挡者、撞上后弹回原位并变红,同时消耗一次失误;被堵过的箭头会一直保持红色,直到它成功飞出;
  • 失误次数耗尽,或倒计时归零,本关失败;
  • 清空本关全部箭头即可通关。

2.2 界面设计

  • 共 6 个关卡:第 1 关 5x5 入门,第 2 关 6x6,第 3 关 6x6 铺满,第 4~6 关 8x8 铺满;
  • 开始界面:渐变背景 + 漂浮装饰箭头 + 自动播放的迷你棋盘(循环演示箭头飞出);
  • 游戏界面:左侧显示关卡名、剩余箭头、剩余失误、剩余时间;右侧为暂停 / 重新开始 / AI 求解 / 回到主页 按钮;格子大小随棋盘自适应(8x8 时自动缩小);
  • 通关结算:按本关失误数评定 3 颗星(0 失误 3 金星、1 失误 2 金星、2 失误 1 金星),全部通关显示总评星级。

2.3 主要功能

  1. 图形化界面(pygame-ce),开始 / 游戏 / 通关 / 失败四类界面;
  2. 四方向箭头、鼠标点击、路径检测、飞出与碰撞反馈;
  3. 失误次数、限时(箭头数 × 0.75 秒)、重新开始;
  4. 6 个可通关关卡(导入时自动校验无死局);
  5. 暂停菜单(继续 / 重新开始 / 回到首页,返回前有"记录不保存"确认);
  6. 音效 8 种(点击、飞出、碰撞、通关、失败、倒计时滴答、按钮悬停、邪恶大笑),全部由代码合成;
  7. 星级结算、关卡选择(含缩略图与历史最佳星级)。

2.4 特色 / 附加功能

  • AIGC 辅助生成的关卡:铺满棋盘的关卡用"逆向构造法"生成,天然保证可通关;
  • AI 自动求解彩蛋:一键自动通关,但会触发"你试图使用不属于你的力量"的结算界面;
  • 原创音效合成:不依赖任何第三方音频素材,无版权问题;
  • 全程标红选错的箭头:当箭头被堵住不能正常通过时,该箭头会全程标红。

2.5 关卡介绍

关卡 棋盘大小 箭头数 设计重点
1 5×5 8 边缘飞出与简单阻挡
2 6×6 16 前后同向、隔格阻挡
3 6×6 36 铺满棋盘,横向纵向依赖交错
4 8×8 64 高密度下的连续解除
5 8×8 64 高密度下的连续解除
6 8×8 64 高密度下的连续解除

难度介绍: 第1,2,3关 层层递进; 第4,5,6关难度相同,都是铺满整个(8x8)格子。


三、实现思路

3.1 箭头、方向与关卡的表示

方向用字符串 up/down/left/right 表示,对应行列增量:

DIRS = {"up": (-1, 0), "down": (1, 0), "left": (0, -1), "right": (0, 1)}

箭头用 (row, col, direction) 表示(本次基础版全部为单格箭头)。关卡是字典:

{"name": "第 1 关", "rows": 5, "cols": 5, "mistakes": 3,
 "arrows": [(0, 1, "right"), (4, 1, "up"), ...]}

3.2 路径检测(重点)

从箭头所在格出发,沿方向逐格前进,越界即可飞出,遇到其他箭头即被阻挡:

def is_blocked(arrows, arrow, rows, cols):
    dr, dc = arrow.delta
    occupied = set()
    for a in arrows:
        if a is not arrow:
            occupied.update(a.path)
    for (r, c) in arrow.path:          # 单格箭头 path 只有一个格子
        rr, cc = r + dr, c + dc
        while 0 <= rr < rows and 0 <= cc < cols:
            if (rr, cc) in occupied:
                return True
            rr += dr
            cc += dc
    return False

3.3 关卡可通关性校验与生成

关键性质:消除箭头只会减少障碍,不会让原本可飞出的箭头变得被阻挡。因此可以反复贪心移除"当前可飞出"的箭头,若能把棋盘清空,则一定存在通关顺序:

def solve_order(arrows, rows, cols):
    remaining = list(arrows)
    order = []
    progress = True
    while progress and remaining:
        progress = False
        for a in list(remaining):
            if not is_blocked(remaining, a, rows, cols):
                order.append(a); remaining.remove(a); progress = True
    return order if not remaining else None
  • levels.py 在导入时对所有关卡调用 solvable(),一旦有死局直接报错;
  • "铺满棋盘"的关卡使用逆向构造法tools/build_levels.py):从内向外依次放置箭头,每放一个都要求它飞出方向上不会撞到已放置的箭头。这样后放的箭头一定先被移除,天然保证可通关。

3.4 动画与状态机

  • 游戏状态:start / level_select / playing / paused / level_clear / game_over / all_clear
  • 飞出:箭头逻辑上立即从棋盘移除(避免继续阻挡别人),同时播放位移动画,动画结束再判定胜负;
  • 碰撞:先冲出到阻挡箭头前,再平滑飞回原位(前 40% 冲出、后 60% 回位);
  • 计时与胜负都延迟到动画结束后结算,避免动画被打断。

3.5 AI 自动求解

载入关卡时用 solve_order() 预先算好该关的点击顺序;点击"AI 求解"后每 0.32 秒自动点掉一个箭头(计时暂停),清空后进入特殊结算界面。


四、AIGC 使用过程

以下均为开发过程中真实发生的协作记录。

记录 1:路径检测与箭头绘制

子任务 借助何种 AIGC AI 实现或提供了什么 效果如何 人工修改
箭头绘制 Claude / DeepSeek 给出用多边形绘制箭头的思路与顶点公式 方向写反、且退化成一条细线 把 x/y 的行列增量对调,并放大头部,恢复正常
碰撞反馈 ChatGPT / Claude 生成"原地左右晃动"的动画代码 太单薄,和题目想要的"撞上去再回来"不符 改为"冲出→弹回"两段式缓动,并让被堵箭头保持红色
关卡设计 Claude / DeepSeek 生成随机铺排 + 求解器校验的关卡生成脚本 6x6 可行,8x8 铺满时随机法成功率几乎为 0 改用"逆向构造法",从内向外放置,保证可通关
飞出音效 DeepSeek 用噪声/正弦合成的 whoosh 代码 呼啸感太强、太短、后半太重 反复调整频率、包络、时长,最终改为单声短促的"ju"

以下我给出两张我使用AI的图片,不全,只是为了稍微展示一下过程
image
image

说明:音效通过 tools/make_sounds.py 用代码合成,多次按"更尖/更轻/更短"的反馈迭代参数。

本来还想去网上寻找一些神秘音效的,但是怕什么版权问题,就不想去搞了。


五、测试结果

单元测试:python -m unittest discover -s tests -v(10 项全部通过)。

手工测试(题目要求的 T01~T06):

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 蓝色箭头飞出并消失 通过
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1 箭头变红弹回,失误 -1 通过
T03 点击位于边缘且朝向棋盘外的箭头 箭头正常消失,不发生越界错误 正常飞出,无越界报错 通过
T04 消除本关全部箭头 显示通关并进入下一关 显示星级结算,可进入下一关 通过
T05 失误次数耗尽 显示失败并允许重新开始 显示失败界面(含彩蛋动图),可重新开始 通过
T06 游戏进行中重新开始 箭头布局和失误次数恢复 布局、失误、计时全部恢复 通过

补充测试:

  • 暂停后计时停止、继续后恢复;
  • 时间归零显示"时间到!"失败;
  • AI 求解后计时暂停,清空后进入彩蛋结算,可进入下一关;
  • 8x8 关卡在窗口内完整显示,无越界。

六、PSP 表格

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

说明:实际耗时明显超出预估,主要集中在界面打磨、关卡生成算法(8x8 铺满)和音效反复调整上。


七、心得体会

AI就是新时代的“黑奴”,又便宜又好用。可以说,我这个项目离了AI,我完全复现不出来。对于代码的生成,修改都是我指导AI做的。你敢想嘛,就在9月18日下午四五点左右,有个骚年才知道“def”在python中是表示“函数”的意思,并且他在第二天借助就把所有的代码整完了,毫无疑问Deepseek得了MVP。只要沟通到位,这点难度的项目对于AI而言,简直太简单了。我发现对于我不擅长的东西,比如说音乐,在让AI帮我调整音效的时候,我一直都是不满意的,没有达到一直我想要的效果,我也不知道怎么沟通,只能说“声音太粗了/太细了”,这种比较范的语言来让AI自己感受,最终我也只是选了我不怎么抵触的音效来加入游戏中,并没有说改的多好。不过对于那种好沟通的,基本我说一声,它都能完成,并且仅生成一次就符合我的预期。也是在撰写心得的时候,我也才开始反思,对于像我这样技术不太过关的码农,要先提升的可能不是编码能力,而是我该如何把需求讲好,讲明白了。但这也不是说我以后就不用手敲了,我只是觉得在这个AI时代,AI写的代码会比我写的好,写的工整,在我还未真正成长之前,我只能先靠AI完成任务,并从中习得一些编码能力。


附:项目结构

arrow_game/
├── main.py             # 程序入口
├── board.py            # 箭头数据结构、路径检测与关卡求解器
├── levels.py           # 关卡数据(导入时自动校验可通关)
├── game.py             # pygame 界面、动画与游戏流程
├── audio.py            # 音效加载与播放(无音频设备时自动静音)
├── assets/             # 音效、GIF、图片等素材
├── tools/              # 音效合成、关卡生成、调难等脚本
├── screenshots/        # 游戏截图
├── tests/              # 单元测试
├── dist/ArrowOut.exe   # 打包后的可执行文件
├── requirements.txt
└── README.md
posted @ 2026-09-19 19:57  kk咸鱼  阅读(7)  评论(0)    收藏  举报