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

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

项目 内容
这个作业属于哪个课程 202601 软件工程(福州大学 计算机与大数据学院)
这个作业要求在哪里 作业链接
这个作业的目标 使用 Python 和 AIGC 完成"一箭又一箭"小游戏
学号 102401414
GitHub 仓库 https://github.com/shukai123123/arrow-game

一、项目展示

开始界面(标题 + 规则说明 + 开始按钮):

开始界面

游戏界面(顶栏显示当前关卡 / 剩余箭头 / 剩余失误,右上角重新开始按钮):

游戏界面

点击可飞箭头后(箭头飞出消失,剩余箭头数更新):

点击后

通关界面(半透明遮罩 + "本关通过" + 下一关按钮):

通关界面

失败界面(失误耗尽后红色提示 + 重新开始按钮):

失败界面

二、项目介绍

2.1 游戏规则

棋盘上有若干带方向的箭头(↑↓←→)。玩家点击某个箭头:

  1. 程序沿该箭头指向的方向,向棋盘边界扫描;
  2. 如果这条路径上、箭头与边界之间没有任何其他箭头,则箭头飞出棋盘并消失;
  3. 如果路径上存在其他箭头,箭头不能飞出,变红抖动并记一次失误;
  4. 清空本关全部箭头 → 进入下一关;失误次数(3 次)耗尽 → 本关失败,可重来。

2.2 界面设计

  • 三个界面状态:START(开始)、PLAYING(游戏中)、LEVEL_CLEAR / GAME_OVER / ALL_CLEAR(结果),由一个状态机驱动。
  • 游戏界面顶栏实时显示:当前关 / 总关数、剩余箭头数、剩余失误数(失误即将用完时变红)。
  • 右上角常驻"重新开始"按钮。
  • 视觉反馈:成功飞出时箭头沿方向飞出屏幕并渐隐;被阻挡时箭头变红、左右抖动。

2.3 主要功能与特色

  • 纯 Python + pygame-ce 实现,无外部素材,箭头用 Unicode 字符 ↑↓←→ 绘制。
  • 逻辑层与界面层分离core.py 只做纯数据判断,不 import pygame,因此可以在无图形环境下直接单元测试。
  • 内置 3 个手工设计、并经脚本验证可通关的关卡。

三、实现思路

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

棋盘用二维整数列表表示,每个格子的取值含义如下:

EMPTY = 0   # 空
UP = 1      # 上
DOWN = 2    # 下
LEFT = 3    # 左
RIGHT = 4   # 右

方向到坐标增量的映射:

DIRS = {
    UP: (-1, 0),    # 行号减小
    DOWN: (1, 0),   # 行号增大
    LEFT: (0, -1),  # 列号减小
    RIGHT: (0, 1),  # 列号增大
}

每个关卡就是一个二维列表,例如第 1 关:

→  ·  ↑
·  ·  ·
·  ·  ←

3.2 路径检测(核心算法)

can_fly(board, row, col) 是整个游戏最核心的函数。它从箭头所在格出发,沿方向一格一格走向边界,只要途中遇到任何非空格子(另一个箭头)就立刻判定为"被挡住";一路走到边界都为空则判定为"可飞出"。

def can_fly(board, row, col):
    direction = board[row][col]
    dr, dc = DIRS[direction]
    r, c = row + dr, col + dc          # 从相邻一格开始扫,不看自己
    while 0 <= r < rows(board) and 0 <= c < cols(board):
        if board[r][c] != EMPTY:       # 路上还有别的箭头 → 挡住
            return False
        r += dr
        c += dc
    return True                        # 一路走到边界都空 → 可飞

为什么这样写就能正确?因为题目约定"路径检测只需判断同一行或同一列、箭头与边界之间是否还有其他箭头",所以沿单一方向线性扫描即可,不需要 BFS/DFS。

关键边界处理:循环条件是 0 <= r < rows and 0 <= c < cols,天然处理了"箭头本来就在边界上、朝向棋盘外"的情况——此时相邻格就越界,循环不执行,直接返回 True,不会数组越界。

3.3 点击与状态流转

try_click(board, row, col) 封装了一次点击的结果,返回 {ok, flew, blocked} 三元组:

  • 点到空格 / 棋盘外 → ok=False,无任何变化;
  • 点到可飞箭头 → 把该格置空,并返回 flew=True,界面层播放飞出动画;
  • 点到被挡箭头 → 保持棋盘不变,返回 blocked=True,界面层记一次失误并播放抖动动画。

界面层(main.py)只负责画图和读鼠标,所有"能不能飞""清没清空"都交给 core.py 判断。

3.4 关卡的可解性验证

设计完关卡后,我没有靠"觉得能通",而是在测试脚本里写了一个贪心校验:反复找任意一个当前可飞的箭头消除,直到清空或死局。结果三个关卡分别用 3、4、4 步清空,证明都存在合法通关顺序。

四、AIGC 使用过程

开发过程中使用了豆包等 AIGC 编程工具辅助,以下记录 3 次有代表性的协作。

协作 1:让 AI 帮我理清"路径检测"到底该扫什么

我最初的想法很模糊,只知道"箭头前面不能有别的箭"。我把游戏规则原样描述给 AI,问它"这个路径判断最核心的循环应该怎么写"。

AI 给出的关键点让我一下子明白了:要从箭头相邻的下一格开始扫,而不是从箭头自己开始,否则会把自己误判成阻挡。它还提醒我用 while 0<=r<rows and 0<=c<cols 这种写法天然处理边界。这正好对应上面的 can_fly

协作 2:让 AI 帮我把"逻辑"和"界面"拆开

我一开始把判断和画图全写在一个函数里,结果想测路径判断时一运行就弹出游戏窗口,很不方便。我把这个困扰告诉 AI,它建议:

  • 把方向常量、can_flycount_arrows、关卡数据抽到一个不 import pygame 的 core.py
  • main.py 只负责读鼠标、调 core、画图。

这样我就能用 python test_core.py 在命令行直接跑测试,不用开窗口。这是这次作业里对我启发最大的一步——原来"能测试"的代码结构和"能跑"的代码结构是两回事。

协作 3:让 AI 帮我排查"向上扫会越界"的 bug

自测时我发现:当箭头在第一行、方向朝上时,偶尔报 IndexError。我把报错堆栈和 can_fly 贴给 AI。AI 一眼指出:如果循环写成 while True: r += dr 而没有先判断范围,第一行的箭头 r-1 就会变 -1。它建议把"边界判断"写进 while 条件里。改完后 T03 测试(边缘箭头不越界)就稳定通过了。

说明:AI 给出的代码我都没有直接照抄,而是先读懂它在做什么,再自己敲进项目,并补了对应的测试。

五、测试结果

运行 python test_core.py,共 20 个断言全部通过。对应作业要求的 T01~T06:

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 箭头被置空,flew=True ✅ 通过
T02 点击前方有阻挡的箭头 箭头不消失,失误次数 -1 箭头保留,blocked=True ✅ 通过
T03 点击位于边缘且朝向棋盘外的箭头 正常飞出,不越界 上/下/右边界箭头均可飞,越界访问不抛异常 ✅ 通过
T04 消除本关全部箭头 显示通关并进入下一关 三关按验证顺序点完后 level_cleared=True ✅ 通过
T05 失误次数耗尽 显示失败并允许重新开始 连续 3 次被挡后累计失误 = MAX ✅ 通过
T06 游戏进行中重新开始 箭头布局和失误次数恢复 深拷贝恢复初始关卡,失误归零 ✅ 通过

附加校验:三个关卡分别用 3、4、4 步可解,无死局。

六、PSP 表格

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

实际耗时普遍高于预估,主要花在"pygame 在 Python 3.14 上装不上、换 pygame-ce"以及界面调优上。

七、心得体会

  1. AIGC 是"结对编程",不是"一键生成":AI 能很快给出一版能跑的代码,但如果直接照抄,遇到 bug 就会完全不知道从哪改。这次我坚持让 AI 解释每段代码在做什么,反而比直接要代码更快。
  2. "可测试的结构"比"能跑的代码"更重要:把逻辑层抽离出来后,我才能用 test_core.py 一键验证 T01~T06,而不是每次都开着窗口手点。这是这次作业最大的收获。
  3. 关卡设计要"自己解一遍":一开始我随手摆了几个箭头,写贪心校验才发现有死局。后来每个关卡都用脚本验证过通关步数,才敢交。
  4. 环境问题也是开发的一部分:Python 3.14 太新,原版 pygame 装不上,换 pygame-ce 才解决。这种问题 AI 帮我快速定位了原因,但最终换库决策和依赖记录是我自己做的。
  5. 不足与改进:目前动画还比较简单(飞出 + 抖动),没有音效;关卡也只有 3 个。如果时间允许,想加一个"提示当前哪个箭头能飞"的提示功能,以及一个能自动求解的 AI solver。

本项目代码与素材均为本人借助 AIGC 工具独立编写,未使用原商业游戏的代码、美术或关卡。

posted @ 2026-09-20 19:29  12546333  阅读(9)  评论(0)    收藏  举报