软件工程第二次作业:利用AIGC进行游戏开发
| 这个作业属于哪个课程 | H202601软件工程与软件工程实践 |
|---|---|
| 这个作业要求在哪里 | 2026秋软件工程个人作业(第二次) |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏 |
| 学号 | 102401607 |
| GitHub仓库 | “一箭又一箭小游戏” |
一、项目展示
演示视频
提取码: xedu
二、项目介绍
1.游戏规则
- 棋盘是若干行 × 若干列的网格,部分格子中有一个单格箭头,方向为上 / 下 / 左 / 右。
- 点击某个箭头后,程序沿其箭头方向检查到棋盘边界的路径(只判断同一行或同一列):
- 路径上没有其他箭头:该箭头飞出棋盘并被消除;
- 路径上存在其他箭头:该箭头无法消除,通过"晃动 + 变红 + 文字提示"反馈碰撞, 并消耗 1 次失误机会(阻挡它的箭头会高亮显示)。
- 清除本关全部箭头即可进入下一关;失误机会用完则本关失败,可重新开始本关。
2.界面设计
游戏主界面及游戏界面如下图所示
主界面

游戏界面

整体风格偏向像素风,不同方向的箭头颜色不同,有利于快速识别及辨认。主要游戏信息、主要功能和简要提示均在游戏界面中进行了展示,简洁大方。
3.主要功能
- 核心消除玩法:点击箭头,沿指向方向飞出消除;撞箭会扣除失误机会,清完全部箭头即通关。
- 双游戏模式:含固定关卡(星级评分、解锁下一关)和无尽模式,本地保存星级与最高分。
- 多界面交互:主菜单选关、查看进度;对局页展示计时、得分、失误数,支持重开本局。
4.游戏特色
- 辅助功能:提供提示、撤销、AI 自动求解,降低游戏难度。
- 程序渲染与音效提供即时反馈:代码绘制霓虹矢量图形,实时合成音效,自带粒子特效,无需外部素材。每一步操作都配有粒子特效、合成音效与动画,操作反馈直观,提升游玩沉浸感。
- 容错设计:设置有限失误红心,误点不会直接游戏结束,给玩家试错空间,降低上手门槛。
三、实现思路
1.方向表示
DIR_VECTORS = {"up": (0, -1), "down": (0, 1), "left": (-1, 0), "right": (1, 0)}
DIR_NAMES = {"up": "上", "down": "下", "left": "左", "right": "右"}
DIR_ORDER = ["up", "down", "left", "right"]
用字典映射方向名到行列偏移向量:(列偏移dc, 行偏移dr)
up:行号 - 1(向上);down:行号 + 1(向下);left:列号 - 1;right:列号 + 1
2.箭头表示
class Arrow:
"""网格中的一个单格箭头"""
def __init__(self, row, col, direction):
self.row = row
self.col = col
self.direction = direction
每个箭头是Arrow实例,保存所在格子row行、col列和方向字符串"up"/"down"/"left"/"right"
游戏内用字典self.arrows = {(r,c): Arrow对象}存储所有箭头,键为格子坐标,方便快速查找
3.关卡配置
LEVELS = [
(4, 5, 5, 0.10),
(4, 8, 4, 0.20),
(5, 10, 4, 0.35),
(5, 13, 3, 0.50),
(6, 16, 3, 0.65),
(6, 20, 2, 0.80),
]
对于6个有限可选关卡,每个关卡元组:(网格边长, 箭头数量, 失误机会, 缠绕程度0~1)
网格边长:N×N 棋盘
箭头数量:本关生成多少箭头
失误机会:最多允许多少次碰撞失误
缠绕程度:越高,箭头之间互相阻挡越多,解谜难度越高
对于无尽模式中的关卡,则有
def load_endless(self, index):
"""无尽模式:难度随层数持续递增,上限封顶后保持不变(保证可生成)"""
self.mode = "endless"
self.level = index
grid = min(4 + (index - 1) // 3, 6)
count = min({4: 8, 5: 13, 6: 20}[grid], 4 + 2 * index)
mistakes = max(2, 5 - (index - 1) // 3)
bias = min(0.8, 0.05 + 0.1 * index)
self.grid = grid
layout = None
while layout is None:
for _ in range(100):
layout = generate_arrows(grid, count, bias)
if layout is not None:
break
if layout is None:
count -= 1
self.layout = layout
self.mistakes_total = mistakes
self._reset_level()
根据关卡数灵活增加难度,缠绕程度封顶为0.8,网格随之逐渐增大,最大同有限模式一样为6×6。
4.路径检测方法
核心代码段
def first_arrow_on_path(row, col, direction, arrows, grid):
"""返回 (row, col) 沿 direction 到棋盘边界路径上的第一个箭头,没有则返回 None。
[fix] 修复向上检测时的数组越界:循环条件统一用 0 <= r < grid 且 0 <= c < grid
限定索引范围,向上越过第 0 行(r 变为 -1)时安全退出循环,不会访问负数下标。
"""
dc, dr = DIR_VECTORS[direction]
r, c = row + dr, col + dc
while 0 <= r < grid and 0 <= c < grid:
if (r, c) in arrows:
return arrows[(r, c)]
r += dr
c += dc
return None
作用:从当前箭头位置,沿着箭头指向方向,向棋盘边界做射线扫描,找到路径上遇到的第一个箭头。
- dc, dr:取出当前方向的行列偏移。
- r, c = row + dr, col + dc:从箭头下一格开始扫描(不包含箭头自身格子)。
- while 0 <= r < grid and 0 <= c < grid:边界判断,保证坐标不会越出棋盘,防止数组越界报错。
- 循环内判断:如果当前坐标(r,c)存在箭头(在arrows字典里),立刻返回这个箭头(就是阻挡物)。
- 如果循环走到棋盘边界还没碰到箭头 → 返回None,代表路径畅通,可以消除。
在游戏中的调用逻辑(点击箭头时)
blocker = first_arrow_on_path(arrow.row, arrow.col, arrow.direction,
self.arrows, self.grid)
if blocker is not None:
# 路径存在阻挡箭头,无法消除,消耗失误机会,触发晃动动画
else:
# 路径无阻挡,箭头飞出消除,播放飞出动画
返回值blocker != None:路径被挡住,不能消除,扣失误红心
返回None:整条射线无遮挡,箭头飞出棋盘消除
四、AIGC使用过程
1. 第一次调用

2. 第二次调用

3. 第三次调用:增加扩展功能
三次主要调用整理表格如下
| 子任务 | 借助何种AIGC技术 | AI实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| 基础玩法 | Claude Code | 简易的完整小游戏界面 | 整体基础游戏效果及框架较为完整,但由于电脑字体缺失问题失误机会处看不到具体次数 | 微调界面布局,对齐文字显示区域,优化文字显示效果。 |
| 修正显示错误 | Deepseek | 修改优化后的部分代码 | 修正了失误机会处的显示问题,改用pygame 矢量绘制心形,不依赖字体;在游戏界面加上显示了当前棋盘上剩余箭头数目 | 调整矢量心形绘制参数,优化 UI 布局,测试验证界面在不同关卡下显示正常,微调文字位置。 |
| 增加扩展功能及美化界面 | Claude Code | 增加了撤销上一步、保存游戏进度、提示等功能 | 游戏界面增加了AI求解和撤销、提示等功能;游戏风格整体更偏向于赛博朋克风格,同时关卡评价采用星级表示;游戏随机性更强 | 校验各扩展功能逻辑,修复边界 bug;调整按钮 UI 布局,优化星级评分计算,测试多场景下功能稳定性。 |
五、测试结果
| 编号 | 测试内容 | 预期结果 | 最终结果 |
|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 箭头正常飞出消失 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数减 1 | 箭头原地晃动并弹出文本提示,失误次数正常减1 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 箭头正常消失,不发生越界错误 | 箭头正常飞出消失 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 正常展示通关界面并进入下一关 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 正常展示失败界面并重新开始 |
| T06 | 游戏进行中重新开始 | 箭头布局和失误次数恢复 | 箭头布局恢复且失误次数恢复 |
| T07 | 点击AI求解按钮 | 显示通关并进入下一关 | AI求解过程中不可打断且顺利通关 |
| T08 | 点击撤销按钮 | 上一步消失的箭头回到原位且剩余箭头数加1 | 箭头正常恢复且剩余箭头数目加1 |
| T09 | 保存游戏进度 | 在下一次进游戏后可见上次游戏进度 | 正常显示上次游戏进度 |
| T10 | 点击提示按钮 | 自动高亮当前可直接消除的箭头所在方框边缘,不改变游戏状态 | 成功高亮可点击箭头,棋盘、失误次数保持不变 |
| T11 | 关卡通关后,根据用时、失误次数计算星级与得分 | 根据游戏表现自动计算得分,给出 1~3 星的关卡评价 | 正常统计用时与失误,正确计算得分并展示对应星级 |
| T12 | 随机生成关卡 | 生成的棋盘存在可通关的箭头消除顺序,不会生成无解布局 | 成功生成可通关随机关卡,存在合法消除路径 |
六、PSP表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 2 | 2 | 0 |
| Python 与图形库学习 | 3 | 4 | +1 |
| 游戏界面实现 | 3 | 3.5 | +0.5 |
| 路径与碰撞逻辑实现 | 4 | 5 | +1 |
| 关卡设计 | 2 | 2 | 0 |
| AIGC 辅助开发 | 2 | 1.5 | -0.5 |
| 测试与修改 | 3 | 4 | +1 |
| README 与博客撰写 | 2 | 4 | +2 |
| 合计 | 21 | 26 | +5 |
整体实际总耗时比预估多出5小时。
主要原因如下
- 游戏路径碰撞逻辑调试、各类功能 bug 修复花费时间超出预期
- README 文档、技术博客撰写需要整理开发过程、测试用例与 Git 提交记录,耗时远超预估
- 借助 AIGC 生成代码,节省了部分编码时间,但仍需要人工校验、修改代码。
七、心得体会
1.AIGC 适合快速搭建基础代码框架,但不能替代逻辑设计
借助 AIGC 可以快速生成 Pygame 基础界面、棋盘渲染等样板代码,节省重复编码的时间。但游戏核心的箭头路径判断、碰撞阻挡逻辑,AI 写出的代码经常存在边界漏洞,需要自己理解算法原理,人工校验、调试,不能直接照搬。
2.开发过程中,人与 AI 是协作关系而非完全依赖
在需求梳理、功能构思阶段,AIGC 可以提供多种实现思路;代码编写时用来辅助生成模块;遇到报错时帮助定位问题。但功能取舍、代码规范、项目 Git 提交管理,都需要开发者自主把控,要学会甄别 AI 输出内容里的错误。
3.软件测试是验证 AI 生成代码可靠性的关键环节
AI 生成的代码容易忽略异常场景,比如棋盘越界、功能并发冲突。本次项目通过设计多组测试用例,对提示、撤销、存档、AI 求解等功能逐一测试,及时发现并修复隐藏 bug,验证程序稳定性,弥补 AI 代码考虑不周的短板。
4.模块化开发配合 AIGC,便于增量开发与版本管理
将游戏拆分为界面、核心逻辑、附加功能等独立模块,每次只让 AI 实现一个功能,配合 Git 分批提交代码。这样可以避免一次性生成大量代码难以排查问题,新增撤销、星级评价、随机关卡等扩展功能时,也能降低代码冲突风险。
5.文档撰写是完整软件开发流程不可缺少的一环
开发不只是写代码,README、技术博客需要梳理项目需求、实现思路、测试结果。在整理文档的过程中,可以复盘整个项目的优缺点,把零散的开发经验系统化,同时也能清晰记录 AIGC 在项目各个环节起到的作用与局限。

浙公网安备 33010602011771号