软件工程第二次作业

软件工程第二次作业

项目 内容
这个作业属于哪个课程 H202601软件工程与软件工程实践
这个作业属于哪个课程 2026 秋软件工程个人作业(第二次)
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102402145
GitHub 仓库 zsp-c/one_arrow_after_another: 一箭又一箭项目

一、项目展示

1.游戏开始界面

image
游戏开始界面,包含游戏玩法说明,及自选关卡。

2.游戏中画面

image
画面包含生命值,剩余箭头数等等,鼠标放在箭头上会有高亮和箭头路径提示,箭头撞到其他箭头时会有红色高亮,和文字提示。

3.通过画面

image

4.失败画面

image

二、项目介绍

这是一个参考微信小游戏《一箭又一箭》核心玩法实现的小游戏作业。棋盘上摆着若干带方向
的箭头(上、下、左、右四种),玩家点击箭头,程序检查它前进方向上有没有别的箭头挡路:

  • 前方畅通 → 箭头飞出棋盘并被消除;
  • 前方有箭头挡路 → 箭头飞不出去,会被弹回来并消耗一次失误机会。

把一关的箭头全部清空即可通关进入下一关;失误次数耗尽则本关失败。

主要特性

  • 上、下、左、右四种方向的箭头,鼠标点击操作,点击判定严格按“同一行 / 同一列、
    箭头与边界之间是否还有其他箭头”执行;
  • 飞出、碰撞都有动画反馈:飞出带残影拖尾与火花,碰撞会顶出去再弹回、闪红,
    并把挡路的那支箭头用金色方框闪两下;
  • 悬停任意箭头即可预览它的前进路线(绿点畅通 / 金点可走 / 红点被挡);
  • 自动提示:每关 2 次,点了直接帮你飞掉一支能走的箭头,不消耗失误次数;
  • 4 个可通关关卡,难度从 5 支箭头递增到 12 支;
  • 开始界面、游戏界面、通关 / 失败结算界面,支持重新开始本关。

三、实现思路

1.方向表示

四个方向就是四个字符串常量,加一张「方向 → 行列增量」的对照表:

UP = "up"
DOWN = "down"
LEFT = "left"
RIGHT = "right"

# 方向 -> (行增量, 列增量)。屏幕坐标里行号向下增大。
DELTA = {
    UP: (-1, 0),
    DOWN: (1, 0),
    LEFT: (0, -1),
    RIGHT: (0, 1),
}

DELTA 是整套实现的关键。屏幕坐标里行号向下增大,所以「上」是行号 -1、「下」是 +1、
「左」是列号 -1、「右」是 +1。

把方向统一成 (行增量, 列增量) 之后,上下左右四种情况就能用同一段代码处理,
不需要写四个 if 分支——后面路径检测就是靠这一点压成一次循环的。

2.箭头表示

一个格子里最多一支箭头,整张棋盘表示成字典 {(r, c): 方向}

{(0, 3): "up", (1, 1): "left", (3, 3): "down"}

用字典进行表示。

3.关卡表示

levels.py 里用字符画描述棋盘,^ v < > 是箭头,. 是空格:

    {
        "name": "初识箭头",
        "tip": "箭头前方没有别的箭头,才能飞出棋盘",
        "mistakes": 3,
        "map": [
            "....^",
            ".<...",
            ".....",
            ".>.v.",
            "...v.",
        ],
    },

4.路径检测

  • 先求出前进路线
def path_cells(rows, cols, pos, direction):
    """箭头前进方向上、棋盘以内的所有格子(不含自己),按由近到远排列。"""
    dr, dc = DELTA[direction]
    r, c = pos[0] + dr, pos[1] + dc
    cells = []
    while 0 <= r < rows and 0 <= c < cols:
        cells.append((r, c))
        r += dr
        c += dc
    return cells
  • 在判断路径上是否存在障碍
def find_blocker(arrows, rows, cols, pos, direction):
    """返回挡在这个箭头前方的第一个箭头坐标;前方畅通则返回 None。"""
    for cell in path_cells(rows, cols, pos, direction):
        if cell in arrows:
            return cell
    return None
  • 关卡合理性判断,通过DFS找到最优解
def find_solution(index):
    """深度优先搜索一条零失误的通关顺序。

    返回 [(r, c), ...](按点击先后排列);无解返回 None。
    箭头数量很少(<= 12),直接穷举即可。
    """
    rows, cols, arrows = parse_level(LEVELS[index])

    order = []
    failed_states = set()

    def search(state):
        if not state:
            return True
        key = frozenset(state)
        if key in failed_states:          # 该局面已证明走不通,剪枝
            return False
        for pos in sorted(state):
            if find_blocker(state, rows, cols, pos, state[pos]) is None:
                direction = state.pop(pos)
                order.append(pos)
                if search(state):
                    return True
                order.pop()
                state[pos] = direction
        failed_states.add(key)
        return False

    return order if search(dict(arrows)) else None

四、AIGC使用过程

子任务 借助何种AIGC技术 AI实现或提供了什么 效果如何 人工修改
提示功能的添加 deepseek 添加提示功能代码 功能完善 由单纯高亮提示改为直接点击箭头
画面清晰图优化 deepseek 优化画面清晰度 画面明显变清晰 进行验证
重开功能实现 deepseek 功能代码 无法使用 进行断点调试,修改

1.提示功能优化

image

2.画面清晰度优化

image

3.重开功能实现

image
人工修改:
通过断点调试确定按下r键的事件并没有被捕获,通过判断确定是中文输入法的原因,导致r键无法被捕获,这里设置进入游戏
后强制变更为英文输入,且禁用中文输入,原本的逻辑代码没有问题。修改后,功能正常。

五、自动化测试

通过代码进行自动化测试
核心代码:
image
这段代码会根据 find_solution(通过DFS找到最佳步骤)给出的方案,进行一次测试,确保关卡的可行性。
部分检测报告:
image

六、psp表格

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

七、心得体会

-AI 带来的帮助

  1. 搭起项目骨架。把逻辑和渲染拆开:game_logic.py 不导入 pygame,规则判定可以脱离
    图形界面单独运行和测试。这个结构是后面所有自动化验证的前提。
  2. 自动化验证脚本check_levels.py 校验规则,main.py --auto 直接驱动真实界面代码
    把 4 关自动打通一遍,还覆盖了碰撞扣失误、重开复原、提示次数、判负等分支。
  3. 动画与视觉反馈。飞出拖尾、碰撞回弹闪红、路径预览、脉冲圆环这些效果直接可用。
  4. 定位画面模糊的真因。不是分辨率不够,而是 Windows 125% 缩放下进程不是 DPI 感知,
    窗口被系统位图拉伸。这个原因我自己不一定会想到。

二、出现的问题

  1. AI 设计的第 3 关是无解的。它把 r3c5(下) 和 r5c5(上) 摆成了互相阻挡,形成死局。
    这是求解器报出"无解"才发现的。
  2. AI 的代码问题。发现R键重置关卡的bug

三、自己的收获

  1. 关键结论必须自己验证。AI 说得越顺、越像那么回事,越要动手确认。输入法那次就是
    典型:推理链条听起来很合理,但前提是错的。
  2. 把"能自动检查的东西"交给程序。路径判定、关卡是否可解、重开是否复原,
    这些都不该靠人一遍遍手点,写成脚本一次跑完,改代码后几秒就能回归。
posted @ 2026-09-20 20:02  zsp-  阅读(14)  评论(0)    收藏  举报