| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 北航《软件工程》 |
| 这个作业的要求在哪里 | [P] 结对项目:花见小路 |
| 我在这个课程的目标是 | 完成一个团队开发项目并在实践中学习软件开发理论 |
| 这个作业在哪个具体方面帮助我实现目标 | 学习如何与他人进行紧密协作式的开发 |
Chapter.0 wasm 从安装到入门
→ Q0.0(P) 如果你的代码仓库包含 AIGC 的部分,列举使用的工具、模型和使用范围。若未使用则填写:本组提交的全部代码不包含 AI 补全或生成的部分。
包含少量 AIGC 内容,使用 Gemini 网页版对话,让 LLM 整理资料、生成测试样例(但是测试代码人工编写)、实现示例代码,最终的代码均经过人工矫正和修改。
→ Q0.1(P) 记录目前的时间。
2026-04-07 19:04
→ Q0.2(I) 分别说明两人对 Wasm 的熟悉程度(IIV)和对桌游花见小路的熟悉程度(III)。
Wasm:
cwz:III, 使用过 C 语言编写 WASM,并配置过相关工具链。
lyk: III, 尝试过将 WASM 反汇编至 C 语言。
花见小路:
cwz: I
lyk: I
→ Q0.3(P) 记录目前的时间(完成 Guide 后)。
2026-04-07 19:17
Chapter.1 七色之缨
→ Q1.1(P) 记录当前时间。
2026-04-07 19:17
→ Q1.2(P) 填写 PSP 表格预估耗时,并记录开发过程(查阅资料、设计逻辑、测试等)。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 6 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 12 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 4 |
| - Coding Standard | - 代码规范 | 5 | 3 |
| - Design | - 具体设计(确定怎么实现) | 5 | 5 |
| - Coding | - 具体编码 | 20 | 16 |
| - Code Review | - 代码复审 | 10 | 10 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 4 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 5 | 8 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 2 |
| - Size Measurement | - 计算工作量 | 5 | 3 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 3 |
| TOTAL | 合计 | 85 | 78 |
→ Q1.3(P) 说明设计了哪些中间量或辅助函数。
设计了 cnt1/cnt2(倾心标记数量)、score1/score2(总分)、mx1/mx2(最高分标记分值)作为中间量。
→ Q1.4(I) 说明如何避免漏判、错判或分支顺序错误。
严格按以下判定顺序编写 if-else 分支:
- 若一方总分 ≥11 → 该方获胜
- 否则若一方获得倾心标记数量 ≥4 且对方总分 <11 → 该方获胜
- 否则若
round < 3→ 返回 0 - 否则(
round == 3):- 总分高者获胜
- 总分相同则比较最高分倾心标记(优先级 G > F > D/E > A/B/C)
- 若仍无法区分 → 平局(返回 2)
→ Q1.5(P) 说明设计了哪些测试用例,覆盖什么规则。
设计了 9 个测试用例,覆盖:总分≥11 获胜、标记数量≥4 获胜、前两轮返回 0、第三轮总分高低、总分相同最高档位(G/F 优先)、平局返回 2,以及全中立边界情况。
→ Q1.6(I) 说明对“先写测试”与“先实现”两种方式的理解。
先写测试可明确需求并驱动设计,保证代码可测性;先实现可快速验证逻辑,但可能遗漏边界。本题采用先实现后补充测试,但先写测试更适合复杂逻辑。
→ Q1.7(P) 记录当前时间,填写实际耗时。
2026-04-07 20:21
→ Q1.8(I) 写下心得体会。
这一部分很简单,简单尝试了结对编程,同时加深了对 Rust/WASM 绑定代码编写与单元测试组织的理解。
Chapter.2 不祥之影
→ Q2.1(P) 记录当前时间。
2026-04-07 20:21
→ Q2.2(P) 填写 PSP 预估耗时,记录开发过程。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 3 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 12 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 0 |
| - Coding Standard | - 代码规范 | 2 | 2 |
| - Design | - 具体设计(确定怎么实现) | 10 | 20 |
| - Coding | - 具体编码 | 30 | 35 |
| - Code Review | - 代码复审 | 10 | 8 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 2 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 5 | 2 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 3 | 3 |
| - Size Measurement | - 计算工作量 | 3 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 3 | 4 |
| TOTAL | 合计 | 91 | 93 |
→ Q2.3(P) 说明对 T1 代码的复用和修改。
复用了 T1 中的得分标记更新逻辑(比较双方各牌张数),修改点:将 T1 的固定分值表替换为按牌类型统计张数,并在结算时用张数比较结果更新 board。
→ Q2.4(I) 说明编码时采用了哪些设计思想或冗余来提高代码适应需求变更的能力。
采用函数拆分(secret_action/gift_action/compete_action)封装不同行动规则,用 my_turn 动态交换双方结果数组指针,避免重复代码;未硬编码牌张位置,便于扩展新行动类型。
→ Q2.5(P) 头脑风暴:T2 中不带 X 的操作记录比实际对局多了多少信息?如果加上 X(未知信息),如何处理对状态的估计?
多了完整公开的牌面信息(无未知),实际对局中对方选择可能未知。若加上 X,需要及时过滤未知信息,只将自己所能知道的信息存到数据结构中。
→ Q2.6(P) 记录当前时间,填写实际耗时。
2026-04-07 21:55
→ Q2.7(I) 写下心得体会。
学会了拆分较为复杂的规则,得到确定性的状态更新函数,更好保证逻辑与真实对局一致。
Chapter.3 道途之荆
准备
→ Q3.1(P) 请记录下目前的时间。
2026-04-10 14:00
→ Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 20 | 25 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 0 |
| - Coding Standard | - 代码规范 | 2 | 2 |
| - Design | - 具体设计(确定怎么实现) | 10 | 30 |
| - Coding | - 具体编码 | 180 | 240 |
| - Code Review | - 代码复审 | 30 | 20 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 7 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 25 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 3 |
| - Size Measurement | - 计算工作量 | 3 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 305 | 364 |
→ Q3.3(P) 头脑风暴环节: 假设提供更充裕的时间和资源,这个游戏中你能找到的最优策略有可能是什么形式的?进行调研并总结分析。你还可以在任务结束后试着实现(不计分)。
可能会是使用最大最小算法,并按照条件概率去预测对手的手牌从而构建完整决策树(目前我们的决策树只有一层)
→ Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么选择行动类型?选牌如何更优?如何编程实现。
设计一个给局面评分的函数 rate,根据单次决策后 rate 的变化情况来决定选择哪种行动类型。具体而言,完全掌控的角色的分值越高,rate 越高;对于未完全掌控的角色,已放置的牌相比对手越多,rate 越高。
决定如何行动时,把所有可能的合法操作都列出来,分别计算它们的 rate,并根据行动类型进行一些修正(例如,我们发现将操作 3 与操作 4 的 rate 翻倍后,效果明显更优)最后选择 rate 最高的行动。
→ Q3.5(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
T2 实现了根据历史行动来分析目前每个角色都被双方各放置了多少牌。这个功能可以复用,不过需要稍加修改:对于 1X 和 2XX 这种不可见操作,需要跳过。
→ Q3.6(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
我采用的设计思想主要包括面向对象、接口设计,实现了策略模式与模块化分离。
通过 GiftStrategy、CompeteStrategy、MoveStrategy 三个 trait 将不同阶段的决策逻辑抽象为可插拔的接口,decide_action 泛型函数则根据实际需求组合不同的策略实现(如随机、最优、最近移动等)。这种设计使得新增或替换策略时完全无需修改核心状态计算与动作执行逻辑,大幅提升了代码对需求变更的适应能力:
decide_action::<OptimalAction3Strategy, OptimalAction4Strategy, BestMoveStrategy>(
history, cards, board,
)
decide_action::<RandomAction3Strategy, RandomAction4Strategy, RandomMoveStrategy>(
history, cards, board,
)
decide_action::<OptimalAction3Strategy, OptimalAction4Strategy, RandomMoveStrategy>(
history, cards, board,
)
通过以上代码可以方便地对策略排列组合,比较不同策略之间的优劣。
同时,我还以 ADT 方式设计 Action 枚举,精确建模游戏中的四种动作及其可选参数,配合 parse_history 的完整模式匹配,
#[derive(Debug, Clone, Copy)]
pub enum Action {
Secret(Card),
Discard([Card; 2]),
Gift([Card; 3], Option<Card>),
Compete([Card; 4], Option<CompeteSelectOption>),
}
软件度量
→ Q3.7(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块决策能力很强?”,尝试提出一些可能的定量分析方式或测试方式。
首先我们实现了一个纯随机的策略,它会在所有合法的操作中随机选择一个来行动。然后我们根据已有的代码(test.js, hanamikoji-engine.js)实现了测试代码。配置好所有想要测试的策略后,测试脚本可以自动让所有策略进行双循环比赛,每次比赛比 10000 局,最终输出对局结果。此后我们会将所有我们实现的优化策略都进行互相对弈,根据胜率的变化情况来决定此优化是否有效。
总结
→ Q3.8(P) 请记录下目前的时间,并根据实际情况填写。
2026-04-11 13:07
→ Q3.9(I) 请写下本部分的心得体会。
这类 AI 决策桌游编程项目,非常适合引入团队间的竞争机制。通过与其他团队反复切磋、迭代优化,我们的项目胜率也在不断攀升,带来了很强的成就感与驱动力。
结对项目总结
→ Q4.1(P) 提供两人在讨论的结对图像资料。

→ Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
此次结对作业开始的时间很晚,最后一周才开始,导致优化策略做的比较匆忙。此后可以尽早完成基础部分,给困难部分留足时间
→ Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
- 思路清晰,算法实现效率高
- 知识储备丰富,具备良好的专业素养
- 配合默契,辅助能力很强
缺点:
- 代码的抽象层次有待提升(可能由于对 Rust 语言还不够熟练)
→ Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
两人实时协作能显著减少低级错误、提升代码质量,同时促进知识传递与团队默契。缺点则包括可能因风格或沟通问题导致效率下降,以及对简单任务而言略显“资源浪费”。我认为结对编程并非简单的“一人写一人看”,而是一种动态的角色轮换与思维碰撞——只有当双方积极投入、频繁讨论时,才能真正实现“1+1>2”的效果。
→ Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
浙公网安备 33010602011771号