[P] 结对项目:花见小路
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 首页 - 2026年春季软件工程 - 北京航空航天大学 - 班级博客 - 博客园 |
| 这个作业的要求在哪里 | [P] 结对项目:花见小路 - 作业 - 2026年春季软件工程 - 班级博客 - 博客园 |
| 我在这个课程的目标是 | 提升系统化工程能力与团队协作水平,探索 AI 辅助开发新模式 |
| 这个作业在哪个具体方面帮助我实现目标 | 实践了两人结对协作与代码审查,将复杂的博弈算法在严格限时下工程化 |
→ 📖 Q0.0(P) 如果你的代码仓库包含 AIGC 的部分,列举使用的工具、模型和使用范围。若未使用则填写:本组提交的全部代码不包含AI补全或生成的部分。
本项目完整采用了 AI 辅助编程(Vibe Coding)范式。使用的主要工具为 anti-gravity,底层频繁切换调用的模型为 Claude Opus 4.6 以及 Gemini 3.1 Pro。使用范围涵盖了 T1、T2、T3 的基础逻辑代码生成、Rust 语法及所有权报错的快速修复、以及辅助构建海量的边缘测试用例脚本。不过,核心的博弈算法设计(PIMC+Alpha-Beta剪枝)与底层的系统状态机架构,是我们两人线下结对讨论推演出来的,随后才将其转化为 Prompt 引导大模型去生成具体代码。
Chapter.0 wasm从安装到入门
→ 📖 Q0.1(P) 请记录下目前的时间。
2026年3月29日 10:00
→ 📖 Q0.2(I) 作为本项目的调查:
对 Wasm 的熟悉程度:II,仅限于听说过相关名词。
对桌游花见小路的熟悉程度:I. 不了解玩法和规则。
→ 📖 Q0.3(P) 请记录下目前的时间。
2026年3月29日 10:45
Chapter.1 七色之缨
→ 📖 Q1.1(P) 请记录下目前的时间。
2026年3月29日 12:30
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | 110 | 115 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 15 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 20 | 25 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 10 | 10 |
| - Coding | - 具体编码 | 30 | 30 |
| - Code Review | - 代码复审 | 10 | 10 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景) | 10 | 15 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 10 |
| REPORTING | 报告 | 15 | 15 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 130 | 135 |
查阅资料:学习 wasm-bindgen 数组传参规范(最终采用 &[i8]),并明确花见小路的胜负及第三回合复杂的连环决胜规则。
逻辑设计:摒弃复杂数据结构,将一维数组直接降维映射为 4 个核心状态量(双方的分数与标记物)。按“绝对胜利 -> 回合流转 -> 终局决胜”的优先级顺序,设计防御性判定分支。
测试设计:借助大模型生成辅助测试脚本,重点覆盖“高分与多标记物同时触发”的优先级冲突,以及第三回合多区域同分的极限平局场景。
问题与解决:第一个是Wasm/Rust 类型报错,我们对所有权和内存映射不熟。将报错交由 AI 分析,改为基础切片传参,第二个是决胜逻辑冗余,多区域判定嵌套过深,我们提取局部布尔变量合并条件,简化了代码。
→ 📖 Q1.3(P) 请说明你们为这个判定模块设计了哪些中间量或辅助函数;如果没有额外设计,也请说明为什么认为直接实现已经足够清晰。
在 hanamikoji_judge 函数中,我们没有拆分额外的辅助函数,而是通过设计几个关键的中间量来实现逻辑:
scores数组 ([2, 2, 2, 3, 3, 4, 5]):将 7 个地标的权重进行了硬编码映射,避免了冗长的switch/match分支。- 状态统计变量 (
my_score,opp_score,my_tokens,opp_tokens):通过一次对board的 O(N) 遍历,将当前盘面抽象为分数和标记物数量这四个核心维度。
没有额外设计辅助函数的原因:
判定逻辑虽然涉及多重条件(常规获胜、回合流转、第三回合平局判定),但其本质是一个纯粹的数据流判断,不包含复杂的嵌套循环或状态突变。整体代码行数控制在 60 行左右,线性向下执行的逻辑(计算特征 -> 判定绝对获胜 -> 判定非末回合 -> 判定第三回合 Tie-breakers)非常契合阅读直觉。强行抽离成多个辅助函数反而会导致上下文的频繁传递,增加阅读负担。
→ 📖 Q1.4(I) 请说明在这样一个规则判定类模块中,如何避免“漏判”“错判”或分支顺序错误等问题。
在规则判定类模块中,控制流的顺序即是游戏规则的优先级。为避免错漏,需要采取以下策略:
- 防御性分支排序:必须严格按照“优先级从高到低”的顺序编写判定。例如,首先判定绝对胜利条件(分数达标或标记物达标),因为这在任何回合都会立即结束游戏;其次判定未到最终回合的继续条件;最后才处理最复杂的最终回合平局决胜。
- 状态穷举与真值表推演:利用类似决策树或真值表的方法。例如,对于第三回合的判定,明确决胜顺位(总分 -> G点 -> F点 -> D/E点 -> A/B/C点)。代码中使用
if/else if/else结构严格阻断了低优先级条件在高优先级条件满足时被执行的可能。 - AI 辅助生成边缘测试用例:依靠大模型根据规则描述反向生成海量的边界情况脚本,通过自动化测试来验证代码的健壮性。
→ 📖 Q1.5(P) 请说明你们设计了哪些测试用例,这些测试分别覆盖了哪一类规则或边界情况。
我们设计的测试用例主要覆盖了以下几类核心规则与边界情况:
- 分数获胜测试:测试玩家或对手单方面
score >= 11的情况(无论回合数)。 - 标记物获胜测试:测试玩家或对手获得 4 个标记物(
tokens >= 4)且对方分数不足 11 分的情况。 - 回合流转测试:模拟第 1、2 回合结束时,双方均未达到获胜条件,验证系统正确返回
0(游戏继续)。 - 第三回合连环 Tie-breaker 测试:
- 覆盖常规平局:双方分数、标记物均不达标,但一方分数较高。
- 覆盖 G (index 6) / F (index 5) 决胜点:构造分数和标记完全相同的盘面,仅改变 6 号位或 5 号位的归属。
- 覆盖多位点决胜(D/E 与 A/B/C):验证
me_de && opp_de同时存在时返回2(彻底平局),以及单一归属时正确返回1或-1。
- 互斥胜利边界测试:例如一方标记物大于 4,但另一方分数大于 11,测试系统是否按照规则优先判定分数高者/或同时满足时的特殊处理。
→ 📖 Q1.6(I) 请说明你对“先写测试再实现”与“先实现再补测试”两种方式的理解。
- 先写测试再实现:这种方式强迫开发者在写下第一行逻辑代码前,先彻底理解“需求是什么”和“边界在哪里”。在花见小路这类规则极其明确且状态有限的桌游判定模块中非常适用。它能有效防止开发者在编写过程中陷入逻辑自嗨或过度工程,测试用例就是代码的“行为契约”。
- 先实现再补测试:这更符合人类在面对未知技术栈时的探索直觉。先通过快速编码让程序“跑起来”,验证技术可行性,随后再通过补全测试来兜底逻辑漏洞。缺点是容易产生“确认偏误”——即写出的测试往往是为了证明已写代码的正确性,而不是为了挑战代码的脆弱点。本项目中我们结合了 AI 辅助,一定程度上弥补了后补测试容易漏掉边界情况的缺陷。
→ 📖 Q1.7(P) 请记录下目前的时间,并根据实际情况填写附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026年3月29日 14:45
→ 📖 Q1.8(I) 请写下本部分的心得体会。
本次任务最大的体会是 “Vibe Coding与人类逻辑抽象的结合点”。在面对一个并不熟悉的语言和一个未曾玩过的桌游(花见小路)时,直接手写代码的门槛极高。但通过梳理状态机模型和将大问题拆解为小提示词,我们发现:大模型非常擅长处理枯燥的语法转换和解决严格的编译报错,而人类开发者的核心价值则转移到了规则架构的推演上。此外,利用 AI 批量生成测试用例,极大地减轻了繁琐的验证工作。在这个过程中,技术不再是阻碍实现想法的黑盒,而是一个可以被自然语言调用的高效接口。
Chapter.2 不祥之影
→ 📖 Q2.1(P) 请记录下目前的时间。
2026年3月29日 14:50
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | 45 | 35 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 5 |
| - Coding Standard | - 代码规范 | 5 | 2 |
| - Design | - 具体设计(确定怎么实现) | 10 | 8 |
| - Coding | - 具体编码 | 10 | 10 |
| - Code Review | - 代码复审 | 5 | 2 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 3 | 2 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 2 | 1 |
| REPORTING | 报告 | 10 | 10 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 3 | 3 |
| - Size Measurement | - 计算工作量 | 2 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 60 | 50 |
技术准备:为避免 JSON 序列化开销,决定引入 js_sys::Int32Array,将双方手牌与盘面状态“拍平”为长度 21 的一维数组返回 JS。
逻辑设计:按回合解析 history,模拟四种动作(1记录、2舍弃、3/4处理复杂的选牌分配),结算时比较卡牌数,相等则继承原 board 归属。
测试设计:覆盖了单动作验证、8 动作全流程连贯推演,以及特定的“平局状态继承”边界测试。
遇阻与解决:Rust 的字符解析与索引转换易引发越界,且 Action 4 的选牌剔除较繁琐,我们枯燥的解析交由大模型,利用其生成的安全迭代器和布尔数组(used_in_chosen)完美规避了 Panic 和匹配错漏。
→ 📖 Q2.3(P) 请说明针对该任务,你们对 T1 中已实现的代码进行了哪些复用和修改。
在这个模块中,我们主要复用了 T1 中关于状态抽象的设计思想:即将花见小路复杂的盘面降维成数组索引(0-6 对应 A-G)。代码层面,我们复用了 T1 中对于 board: &[i8] 的 Wasm 传参模式。同时,T1 中“比较数值大小判定地标归属(1 为我方,-1 为对手)”的核心规则被复用到 new_board 的生成逻辑中:如果 p1_cards[i] > p2_cards[i] 则置 1,反之置 -1,相等则回退使用旧的 board[i]。区别在于,T1 是基于已知结果进行最终裁判,而 T2 是通过历史记录去推演并生成这个结果。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
- 数据结构的降维与扁平化:如代码中将三个
[i32; 7]数组拍平为一个Int32Array(21)。这种设计避免了强类型结构体的硬绑定,未来如果增加新状态(比如卡牌弃牌堆情况),只需扩展一维数组的长度并在前端对应切割即可,无需修改 Wasm 接口的签名。 - 无状态的纯函数:
calc_current_state不依赖任何外部全局变量。历史记录history和当前盘面board作为仅有的输入决定唯一的输出。这种设计让模块极易被各种测试框架和上层 AI 树搜索调用。 - 防御性字符解析:在解析
history时,通过if chars.is_empty() { continue; }和对字符范围的校验(c >= 'A' && c <= 'G')提供了容错。即使外部传入了畸形的无效操作记录,也不会导致底层 Rust 代码的崩溃(Panic)。
→ 📖 Q2.5(P) 头脑风暴环节:我们终于快要开始让程序玩游戏了!请尝试分析:T2 中不带 X 的操作记录比起实际对局多出了多少信息?如果加上 X,也就是失去了这部分信息的话,如何处理对小轮结束后状态的估计?
T2 的 history 是一份“上帝视角”的完美信息记录。在实际的桌游对局中,玩家的 Action 1(密印/Secret)和 Action 2(弃牌/Discard)都是背面朝下的暗牌。此时的系统通过历史记录如 1C 或 2DE 确切知道了这两张牌是什么,这比起实际对局多出了对手隐藏手牌库与弃牌堆的绝对信息。一旦隐藏动作变为 1X 或 2XX,游戏就从“完美信息博弈”变成了“非完美信息博弈”,对于此问题,处理方法如下:
- 剩余卡牌池:由于每种卡牌的总量是固定的(2,2,2,3,3,4,5),我们可以用总卡牌减去“自己手中的牌”和“场上已明示的牌”,得出当前所有未知卡牌的集合。
- 概率分布估计:对手的
X必然从未知卡牌集合中产生。我们可以通过计算每种卡牌在未知集合中的比例,将其转化为一个概率矩阵,估计对手某张暗牌是 A-G 的概率。
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录 A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026年3月29日 15:40
→ 📖 Q2.7(I) 请写下本部分的心得体会。
在实现 T2 模块时,AI 辅助编程(Vibe Coding)的优势得到了极大的体现。在 Rust 这种对内存和类型有着极其严苛要求的语言中,手写各种生命周期处理和繁琐的字符串切片非常消耗心智。我们将“历史记录字符串的格式规则”用大白话喂给大模型后,它不仅帮我们生成了清晰的 split 逻辑,还在跨语言的数据交互上给出了 Int32Array 这种非常实用的降维解法,避免了我们陷入底层 C-ABI 层面的序列化泥潭。这让我们能够将主要精力集中在推演花见小路规则中棘手的“多牌分配与抵消”的逻辑正确性上,进一步验证了“AI 写代码,人类定框架”的开发模式的极高效率。
Chapter.3 道途之荆
→ 📖 Q3.1(P) 请记录下目前的时间。
2026年4月3日 13:00
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 20 | 15 |
| - Estimate | - 估计这个任务需要多少时间 | 20 | 15 |
| DEVELOPMENT | 开发 | 240 | 280 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 40 | 50 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 20 | 30 |
| - Coding Standard | - 代码规范 | 10 | 10 |
| - Design | - 具体设计(确定怎么实现) | 40 | 45 |
| - Coding | - 具体编码 | 80 | 90 |
| - Code Review | - 代码复审 | 20 | 25 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景) | 20 | 15 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 15 |
| REPORTING | 报告 | 40 | 50 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 15 | 20 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 25 |
| TOTAL | 合计 | 300 | 345 |
完成编程任务期间的过程记录:
技术准备:引入 js_sys::Date::now 满足 2 秒限时,并手写轻量级 Xorshift64 伪随机算法以严格控制 Wasm 产物大小。
逻辑设计:构建基于 PIMC 的采样架构,结合 Alpha-Beta 剪枝树,以及综合“地标控制权、分数、卡牌期望值”的启发式评估函数,实现核心决策逻辑。
测试设计:通过本地自我博弈,验证AI第一步的直觉合理性,并针对 Action 4 构造极限分支压测,通过同学之间互相博弈,在实战中对程序进行测试。
遇阻与解决:Action 4 合法分牌组合爆炸易引发超时,借助 AI 生成了栈内存级别的极速去重分牌函数,并辅以“1500ms 时限硬中断 + 动态搜索深度(3至5层)”的双重保险,彻底攻克性能瓶颈。
→ 📖 Q3.3(P) 头脑风暴环节:假设提供更充裕的时间和资源,这个游戏中你能找到的最优策略有可能是什么形式的?
花见小路是一个典型的非完美信息、零和、双人博弈。我们目前采用的 PIMC完美信息蒙特卡洛存在理论缺陷,即“策略融合”与“非局部性”问题,它假设对手在每个采样世界中都能看到我们的暗牌并做出针对性最优解,这会导致 AI 过于保守。
如果时间和算力极其充裕,最优策略的形态应该是:
- 反事实遗憾最小化:这是目前解决非完美信息博弈的数学最优解形态。通过不断自我博弈迭代,最终收敛到一个纳什均衡策略。形式上,它会表现为一个庞大的查找表或神经网络,对于任何一个信息集,直接输出各种合法动作的概率分布,而不是像现在这样每次都在线搜索。
- Deep Reinforcement Learning:训练一个价值网络和策略网络,结合隐藏状态的信念追踪,将历史记录编码为隐状态向量输入给模型。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么选择行动类型?选牌如何更优?如何编程实现。
针对苛刻的 2 秒时间限制和复杂的博弈树,我们在编程实现时采取了以下针对性优化策略:
- 时限硬中断与动态深度:
设定time_budget = 1500.0毫秒,预留 500ms 的通信与序列化缓冲区。在最外层的loop中,如果当前耗时超过预算,立即中断 PIMC 采样并返回当前最优解。同时,根据当前可选动作的数量动态调整 Alpha-Beta 搜索树的深度,分支少则搜 5 层,分支多如刚开局时只搜 3 层,确保单次采样的耗时可控。 - 动作排序优化:
为了让 Alpha-Beta 剪枝尽早发生,我们在alphabeta函数中实现了动作排序。在浅层搜索时,利用类别直接排序,Action 1 > Action 4 > Action 3 > Action 2,因为隐藏/保留高价值牌通常是好动作;在顶层或深层搜索时,先用启发式函数对第一层子节点进行一次廉价评估并降序排列,这提升了剪枝效率。 - 启发式评估:
在选牌优化上,我们没有单纯计算胜负,而是在evaluate_heuristic中引入了期望值计算。程序会判断某张牌的数量是否过半,如果处于拉锯状态,则计算双方手中与牌库中该花色卡牌的期望差值(diff = e1 - e2)。这种平滑的打分机制让 AI 倾向于抢夺权重高(如 5分、4分)且当前处于优势的位点。
→ 📖 Q3.5(P) 请说明针对该任务,你们对 T2 中已实现的代码进行了哪些复用和修改。
T3 的核心解析逻辑完全脱胎于 T2。
- 复用:我们复用了 T2 中逐个按
split('-')和字符遍历解析history字符串的基础骨架。判定当前操作者(i % 2 == 0)以及识别动作类型('1'到'4')的思路被完整继承。 - 修改与升级:在 T2 中,我们的目标仅仅是还原“公开的完美盘面”,因此对 'X' 直接采取了丢弃/忽略处理。而在 T3 中,为了支持后续的搜索算法,我们将解析函数升级为了
parse_history,其最大的修改是加入了隐蔽信息追踪:遍历卡牌和历史记录时,维护了一个hidden_pool。凡是遇到已知的卡牌,就从hidden_pool中剔除,从而精准计算出当前未知的卡牌集合,为 PIMC 的determinize(采样确定化)提供了数据基础。此外,我们将松散的数组封装成了严密的GameNode状态机。
→ 📖 Q3.6(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
- 配置数据分离:将地标的分值和总卡牌数提取为全局常量
SCORE_BY_ID和COUNT_BY_ID。如果规则发生变更,例如扩展包引入了 6 分的艺伎或改变了牌数,我们无需修改底层判定逻辑,只需更改这几行常量即可。 - 纯函数式的状态转移:
GameNode::apply_move被设计为一个自包含的纯状态转移函数。它不依赖外部上下文,接受一个Move枚举,完成状态突变。这种解耦不仅方便了并发搜索,也为日后可能加入的“悔棋”或“蒙特卡洛树搜索(MCTS)”提供了无缝接入的基础。 - 时间控制冗余:没有硬编码死循环次数,而是基于时钟流逝(
js_sys::Date::now)和迭代次数双重防线来控制退出。即使底层硬件执行速度剧烈波动,程序也能自适应保证不死锁并按时返回决策。
→ 📖 Q3.7(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块决策能力很强?”,尝试提出一些可能的定量分析方式或测试方式。:

如图所示,我们通过与其他的组的同学进行对局对抗进行测试,实战是最有说服力的指标,如果我们的 AI 能在与他人的程序对局下保持高胜率,且未发生崩溃、超时或输出非法动作,即可证明其有效性。
可能的定量分析方式:
- ELO 等级分系统:编写一个本地的测试脚本,让 T3 的当前版本与旧版本,或纯随机/贪心的简单策略,进行数千局的自动对局。计算其 ELO 积分,通过积分的稳步上升来定量证明算法优化的有效性。
- 残局解题率测试:在花见小路社区收集特定的“一招制敌”或“绝境逢生”的残局历史字符串。将这些固定局面喂给 AI,统计它能在多少毫秒内找到理论最优解的命中率。
→ 📖 Q3.8(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026年4月3日 18:45
→ 📖 Q3.9(I) 请写下本部分的心得体会。
完成 T3 是一次将“高层博弈理论”与“底层工程优化”结合的极致体验,也是 AI 辅助编程(Vibe Coding)大放异彩的阶段。在设计阶段,我们人类的大脑负责推演 PIMC 和 Alpha-Beta 的架构图,并设计了启发式函数的权重(比如抢夺 5 分地标的收益系数应该比 2 分大多少)。但当我们落笔写 Rust 代码时,无论是实现复杂的 Action 4 不重复组合的生成算法,还是手动编写极速的伪随机数生成器(xorshift64),亦或是处理借用检查器在复杂树搜索中的报错,都极度消耗心智。将这部分繁琐的实现抛给大模型后,我们获得了难以置信的效率提升。AI 填补了我们从“懂理论”到“写出高性能底层代码”之间的鸿沟,它提供的栈内数组分配方案极大地降低了内存开销,确保了我们的 AI 能够在严苛的 2 秒内跑完上千次局面采样。这让我们深刻意识到,未来的软件开发,核心壁垒不再是熟练掌握某种语言的语法细节,而是能否准确构建系统模型、提出正确的算法思路,并精准地将其描述给 AI 去执行。
结对项目总结
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
在本次引入了 AI 辅助编程(Vibe Coding)的结对过程中,我们发现传统的结对模式发生了变化,也暴露出了一些需要改进的点:
- AI 提示词的协同构建:初期我们常常是一个人构思好逻辑直接去问 AI,另一个人只能看着,后来我们意识到在 Vibe Coding 中,结对的重心应前移。两人应该先在白板或草稿纸上结对画出状态机和数据流,共同拟定好 Prompt 的约束条件,然后再交由一人去“驾驶”大模型生成代码。
- 对 AI 生成代码的审查盲区:因为大模型生成代码速度极快,有时我们会产生惰性,直接 Copy-Paste 运行,导致一些隐蔽的边界 Bug(如越界或生命周期问题)在测试阶段才暴露,对于结对编程,其中一人应当严格落实“导航者”的职责——一人负责引导大模型生成并集成代码,另一人必须逐行审查大模型产出的核心逻辑,充当“人类编译器”和“逻辑审阅者”。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
本次结对项目中,具体的底层代码落地和生成工具的对接主要是由我的搭档来主力完成的。
优点:
- 执行力与工程底蕴:在确立了 PIMC 和 Alpha-Beta 的算法框架后,他能极其迅速地构建 Prompt 并通过大模型将我们的构想转化为实际的 Rust 代码,推动项目进度。
- 逻辑思维敏捷:在设计 T3 的状态树和启发式评估函数时,他对零和博弈中“收益差值”的直觉非常敏锐,提出了用期望差值平滑代替绝对胜负判定的好点子。
- 情绪稳定且耐心:在面对 Rust 严格的所有权报错以及测试用例跑不通的挫败时刻,他总能保持冷静,有条不紊地将报错信息提炼后交给 AI 修复,沟通起来非常顺畅。
缺点:
- 有时过于依赖 AI:在拿到大模型给出的第一版代码时,有时为了赶进度会急于运行看结果,而忽略了对代码中可能存在的隐蔽边缘情况进行人工仔细推敲,偶尔会导致后续需要返工调试。
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:
- 实时代码审查与容错:两双眼睛盯着同一套逻辑,能瞬间捕捉到低级拼写错误或逻辑漏洞,极大减少了后期的 Debug 成本。
- 思维碰撞:在遇到架构设计瓶颈,例如如何处理 Action 4 庞大的分牌组合时,两个人讨论往往能迅速跳出思维定势,找到像“栈内数组去重”这样的巧妙解法。
缺点:
- 极度消耗精力:结对编程要求两人在长达数小时的时间里保持高度集中的注意力和高频的语言交流,比单人写代码容易疲劳。
- 时间协调成本高:需要两人抽出大块的共同空闲时间,这在满课的日程安排中往往比较困难。
在传统语境下,结对编程是“一人敲键盘,一人看思路”。但在 AI 辅助编程时代,敲键盘和纠正语法的脏活累活已经被大模型接管了。现在的结对编程,本质上变成了“两个架构师的结对”。我们的核心任务不再是盯着屏幕检查分号有没有漏,而是共同讨论系统边界、推演博弈树的深度、设计测试覆盖的盲区,以及审查 AI 生成产物的安全性。结对编程的价值没有被 AI 削弱,反而被拔高到了“纯粹逻辑与架构设计”的层面。
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
https://github.com/paidaxingKing/BUAASE2026-PairProgramming.git

浙公网安备 33010602011771号