[P] 结对项目:花见小路
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 2026年春季软件工程 |
| 这个作业的要求在哪里 | [P] 结对项目:花见小路 |
| 我在这个课程的目标是 | 提高软件开发能力,用现代软件工程的常见开发方式去完成一个程序 |
| 这个作业在哪个具体方面帮助我实现目标 | 熟悉结对编程的实践方式,感受利弊 |
结对项目:博客问题清单
请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。
→ 📖 Q0.0(P) 【你可以在结对结束后补充】如果你的代码仓库包含 AIGC 的部分,列举使用的工具、模型和使用范围。若未使用则填写:本组提交的全部代码不包含AI补全或生成的部分。
工具:github copilot
模型:gpt-5.3-codex
使用范围:让 agent 写 gitignore,在 T3 迭代的时候让 agent 跑当前和上代版本的对打测试,在 T3 迭代的时候试着让他增加详细的打分逻辑。
Chapter.0 wasm从安装到入门
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2026-04-01 14:45
调查
→ 📖 Q0.2(I) 【你可以在结对结束后另行补充。】作为本项目的调查:
请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
I. 没有听说过;
请如实标注在开始项目之前对桌游花见小路的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)
I. 不了解玩法和规则;
II. 听说过,且有一定了解;
I. 不了解玩法和规则;
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2026-04-01 15:10
Chapter.1 七色之缨
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2026-04-01 15:10
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
-
预计60min。
-
如下:
- 先通读了
README.md中 Chapter.1 的说明,仿照 G 的做法构建了环境 。 - 把规则拆成几个部分:分值统计、标记数量统计、第三轮总分比较、第三轮同分时的最高档位比较。
- 在
assembly/index.ts中实现核心函数hanamikoji_judge(board, round),并补充了几个辅助函数。 - 在
test/index.js中设计了 6 类测试,分别对应题目要求的 6 类典型情况。 - 运行
npm run asbuild。 - 先在
t1-as目录下运行npm test检查自定义测试是否通过,再回到/src/T1目录运行npm run submit-test。
中间遇到的主要问题:
- 一开始对于构建出来的项目结构还不太熟悉,看他们花了点时间。不过这个不怎么影响完成作业。
- 先通读了
设计
→ 📖 Q1.3(P) 请说明你们为这个判定模块设计了哪些中间量或辅助函数;如果没有额外设计,也请说明为什么认为直接实现已经足够清晰。
markerWeight(index):根据 A-G 的下标返回对应分值。countMarkers(board, owner):统计某一方当前获得了多少枚倾心标记。scoreMarkers(board, owner):统计某一方当前倾心标记的总分。resolveTier(board, start, end):用于判断某个分值档位上,是否只有一方拥有标记。judgeByHighestTier(board):在第三轮总分相同的情况下,比较最高非空档位。
→ 📖 Q1.4(I) 请说明在这样一个规则判定类模块中,如何避免“漏判”“错判”或分支顺序错误等问题。
1.严格根据题目条件来设置规则判定,先想清楚再编码。
2.设置覆盖全面的测试。
测试
→ 📖 Q1.5(P) 请说明你们设计了哪些测试用例,这些测试分别覆盖了哪一类规则或边界情况。
完全是按照题目要求的来的:
- 一方分值达到
11分而获胜; - 一方获得至少
4枚倾心标记而获胜; - 前两小轮结束时尚未满足胜利条件,应返回
0; - 第三小轮结束时,总分不同,由总分高者获胜;
- 第三小轮结束时,总分相同,由最高档位倾心标记判定胜负;
- 第三小轮结束时平局,应返回
2。
→ 📖 Q1.6(I) 请说明你对“先写测试再实现”与“先实现再补测试”两种方式的理解。
我认为这两种方式各有适用场景。
“先写测试再实现”的优点是,开发者需要先把需求边界想清楚。这样可以减少漏判和分支顺序错误。但它的前提是:需求本身已经足够明确。如果需求还在变化,或者对于编码具体方案还不熟,不适合这样做。
“先实现再补测试”的优点是推进速度快。但这样人会有惰性,写测试的时候容易敷衍了事,比如写测试时可能只写自己在编码时已经想到过并做了处理的样例。
总结
→ 📖 Q1.7(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026-04-01 15:55
Chapter.1 PSP 表格(15:10-15:55)
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 4 | 3 |
| - Estimate | - 估计这个任务需要多少时间 | 4 | 3 |
| DEVELOPMENT | 开发 | 50 | 36 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 7 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 6 | 4 |
| - Coding Standard | - 代码规范 | 2 | 1 |
| - Design | - 具体设计(确定怎么实现) | 10 | 6 |
| - Coding | - 具体编码 | 16 | 12 |
| - Code Review | - 代码复审 | 4 | 3 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 3 | 3 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 2 | 2 |
| REPORTING | 报告 | 6 | 6 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 2 | 2 |
| - Size Measurement | - 计算工作量 | 2 | 1 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 2 | 3 |
| TOTAL | 合计 | 60 | 45 |
→ 📖 Q1.8(I) 请写下本部分的心得体会。
这一部分难度较小,更多是熟悉一下语法。
Chapter.2 不祥之影
准备
→ 📖 Q2.1(P) 请记录下目前的时间。
2026-04-01 15:55
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
-
预计70min。
-
我们本章任务的大致完成过程如下:
- 先通读 T2 的题目说明。
- 正常流程建立工程。
- 在
assembly/index.ts中实现calc_current_state(history, board),并设计了一些辅助函数来拆分字符串解析、卡牌统计和结算更新逻辑。 - 写测试。
- 运行
npm run asbuild生成产物后,先在t2-as目录下运行npm test,再回到/src/T2目录运行npm run submit-test,确认课程组测试通过。
没有遇到什么问题。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
没有直接复制,因为这次的输出只是得分标记,没有判断输赢。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
主要是拆分和封装,把具体的功能封装起来,便于修改。冗余方面我个人觉得主要是结构上的冗余,就是能用一个函数或者一个长表达式写完的逻辑可以拆开,长期来看更容易维护。
头脑风暴环节
→ 📖 Q2.5(P) 头脑风暴环节:
我们终于快要开始让程序玩游戏了!请尝试分析:T2 中不带 X 的操作记录比起实际对局多出了多少信息?如果加上 X,也就是失去了这部分信息的话,如何处理对小轮结束后状态的估计?
多出的信息:原本在对局过程中对对手不可见的牌,也在回合结束后被完整公开了。如密约取舍。
如果加上 X,也就是失去这部分信息后,问题就会从“恢复唯一状态”变成“在不完全信息下估计可能状态集合”。此时我们认为可以这样:
-
维护所有可能状态
把未知牌视为多个可能分支,枚举所有与当前公开信息一致的状态,并维护一个候选集合。根据牌堆总量、双方已公开出的牌、已知动作消耗的牌,缩小可能集合。
-
做概率估计
计算。
-
做保守估计或乐观估计
也可以不追求完整概率模型,而是根据策略需要,构造“最坏情况”“最好情况”或“最可能情况”下的估计,用来辅助出牌。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录 A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026-04-01 16:41
Chapter.2 PSP 表格(15:55-16:41)
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 4 | 3 |
| - Estimate | - 估计这个任务需要多少时间 | 4 | 3 |
| DEVELOPMENT | 开发 | 59 | 37 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 8 | 6 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 9 | 5 |
| - Coding Standard | - 代码规范 | 3 | 2 |
| - Design | - 具体设计(确定怎么实现) | 10 | 6 |
| - Coding | - 具体编码 | 18 | 10 |
| - Code Review | - 代码复审 | 5 | 3 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 3 | 2 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 3 | 3 |
| REPORTING | 报告 | 7 | 6 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 3 | 2 |
| - Size Measurement | - 计算工作量 | 2 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 2 | 2 |
| TOTAL | 合计 | 70 | 46 |
→ 📖 Q2.7(I) 请写下本部分的心得体会。
和 T1 相比,这一部分复杂很多。我意识到,处理字符串记录时,先把规则抽象清楚很重要,边看边写容易把自己绕晕。
另外,测试在这一题里的价值比 T1 更大,因为情况更复杂,错误藏的更深。
Chapter.3 道途之荆
准备
→ 📖 Q3.1(P) 请记录下目前的时间。
2026-04-01 16:41
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
-
150min
-
我的依次做了如下行动:
-
我们先阅读 T3 题目,明确了函数需要在每一步返回一个合法行动,并且要能够处理
X带来的信息缺失。随后继续使用 AssemblyScript,初始化工程后先完成了一个能稳定输出合法行动的朴素版本。 -
在此基础上,我们在 ai 辅助下先做启发式策略迭代。最初版本主要依赖静态牌值,例如高分牌更重要、赠予和竞争优先保住高价值牌。之后逐步加入了对历史记录的解析、对当前公开局势的估计、对不同动作类型的评分,以及不同行动阶段的偏好调整。
-
中途我们也查阅了一些社区讨论和论文资料(没错,有一篇论文是研究花见小路的,叫Monte Carlo methods and algorithms for the card game Hanamikoji),发现《花见小路》的公开资料中并没有公认的完美策略,更多的是一些启发式的经验心得。
-
开发过程中遇到的主要问题有两个:一是 T3 的
history带有视角差异,需要考虑双方各自已有的信息;二是策略题不像 T1/T2 那样有唯一标准答案,因此不能只靠固定样例判断优劣,我们让迭代的先后版本互相对打,比较是否明显改善。
头脑风暴环节
→ 📖 Q3.3(P) 头脑风暴环节:
假设提供更充裕的时间和资源,这个游戏中你能找到的最优策略有可能是什么形式的?进行调研并总结分析。你还可以在任务结束后试着实现(不计分)。
我们调研了不少玩家经验,比较稳定的共识包括:
- 不应只盯着 5 分和 4 分艺伎,而应考虑以尽量小的代价拿下关键艺伎并守住已有优势;
- 赠予和竞争的关键要让对手没有舒服的选择,即制造“怎么选都不赚”的局面;
- 行动顺序可能存在通常的更好策略,但很难算出严格最优。
如果给出更充裕的时间和资源,我认为更接近最优策略的形式,应该需要依赖博弈论知识,进行尽可能全面的信息搜集和分析,又或是可以尝试靠机器学习来拟合出来。
需求建模和算法设计
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么选择行动类型?选牌如何更优?如何编程实现。
我们当前版本的核心思路是先从历史记录中得到尽可能多的公开信息,再对所有合法行动做评分,最后选择得分最高的动作。
具体来说,策略主要分为四层:
-
解析历史并估计当前局势
程序先根据
history判断自己在当前小轮中是否先手,并分析哪些动作已经使用过。随后根据公开的赠予、竞争、密约等信息,估计双方目前在 A-G 七类艺伎上的已知牌数,形成selfKnown和oppKnown两个数组。 -
给单牌计算优先级
对每张牌,我们综合考虑艺伎本身分值高低,当前
board上该艺伎偏向自己、对手还是中立,本轮公开信息下自己和对手在该艺伎上的差距,当前手里是否持有同类重复牌。鼓励争夺容易抢过来的较高分艺伎 -
对不同动作枚举候选并评分
对于
1/2/3/4四种动作,程序都会生成候选方案并评分:1密约:从手牌中选最值得隐藏的一张;2取舍:从手牌中选最不值得保留的两张;3赠予:枚举所有三张组合,并按“对手拿走最好一张后还剩多少收益”的思路打分;4竞争:枚举所有四张组合和三种分组方式,优先选择能让对手陷入两难、即无论选哪一组都不舒服的方案。
-
加入阶段偏置
我们考虑到
3/4会给对手更多信息,因此在评分里额外加入了动作时机偏置:- 前期适当提高
1/2的得分; - 中后期适当提高
3/4的得分。
这样可以让策略更符合“先藏信息、后公开博弈”的安全顺序。
- 前期适当提高
代码可复用性与需求变更
→ 📖 Q3.5(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
T3 没有直接复用 T2 的主函数,因为两者目标不同:T2 关注的是根据完整历史恢复一轮结束后的状态,而 T3 要根据当前信息实时决策。
不过,T2 中的一些函数和语句对 T3 仍然有直接帮助,主要体现在:
- 继续使用长度为 7 的数组表示 A-G 七类艺伎的状态;
- 继续使用对行动记录进行拆分和解析的方式理解
1/2/3/4四种动作; - 沿用赠予和竞争中对牌组、选择结果的一些处理逻辑;
T3 复用的主要是一些数据表示,绝大多数代码都是新增的决策逻辑。
→ 📖 Q3.6(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
我认为像 T3 这种策略程序,依然要尽量拆分逻辑,比如:
- 历史和视角相关函数;
- 局势估计相关函数;
- 单牌优先级计算函数;
- 各类动作的候选生成函数;
- 各类动作的评分函数。
好处和 T2 中说的类似。
软件度量
→ 📖 Q3.7(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块决策能力很强?”,尝试提出一些可能的定量分析方式或测试方式。
有效性首先是正确性,输入输出首先要合法。
而对于决策能力强弱,最直观的应该是找人对打,不过我们做的比较早,写这个文档的时候还没人提交,所以我们主要是自己测。
我们设想了一些定量分析的方式:
- 让当前版本和旧版本互相对打,并交换先后手;
- 使用固定牌堆或固定随机种子,减少偶然性;
- 多轮重复对战,统计净胜场、胜率和平局率;
- 与多个不同风格的策略程序进行双循环赛;
- 观察最终
board分数、拿到的标记数量、关键高分艺伎控制率等中间指标。
总结
→ 📖 Q3.8(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026-04-01 18:28
Chapter.3 PSP 表格(16:41-18:28)
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 6 | 4 |
| - Estimate | - 估计这个任务需要多少时间 | 6 | 4 |
| DEVELOPMENT | 开发 | 128 | 90 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 18 | 12 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 18 | 12 |
| - Coding Standard | - 代码规范 | 4 | 3 |
| - Design | - 具体设计(确定怎么实现) | 20 | 14 |
| - Coding | - 具体编码 | 45 | 32 |
| - Code Review | - 代码复审 | 10 | 7 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 6 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 7 | 5 |
| REPORTING | 报告 | 16 | 13 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 6 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 4 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 4 |
| TOTAL | 合计 | 150 | 107 |
→ 📖 Q3.9(I) 请写下本部分的心得体会。
和前两题相比,T3 给我的最大感受是:决策问题非常复杂,T3 需要在不完全信息下做一个尽量好的选择,这意味着需要在不同版本之间不断试错、比较和迭代。
另外,测试过程让我意识到,对打的单局结果偶然性很大,所以更合理的方式是做多次对局、交换先后手、比较不同版本之间的净胜场。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
总体挺愉快的,交流比较顺畅。分工比较明确,一个人更多地读题,验证规则,搜集网络信息,提出idea,另一个更多负责编码,测试。
- 因为之前不认识,所以话不是很多。
- T3 的有些迭代做出来发现没有很确定性的提升(和前版本打胜负受先后手影响比较大),不过出于感觉,我们直接沿用了。如果以后还碰到类似任务,我们应该定好更合适的测试方法。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
- 性格好,协作起来很舒服。
- 能力强,能提出很多有用的建议。
- 思维缜密,编码时能快速指出写出来的一些bug。
缺点:
- 一开始的时候话不多。
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
我觉得结对编程的最大优点是:很多问题在和搭档说出来的过程中就已经被发现了。一个人做题时,很容易默认自己的理解是对的;但两个人一起做时可以互相验证、监督。除此之外,结对编程还能在一定程度上减少卡壳时间,一个人查资料、一个人实现或验证,通常会比单独推进更高效。
它的缺点也很明显。首先,沟通本身是有成本的,如果两个人对问题的抽象层次不一致,就会花不少时间在“到底在讨论什么”上。其次,如果分工不清晰,结对编程容易变成一个人做另一个人看着,那样反而 1+1=1 了。最后,两个人的节奏和风格不完全一样时,也可能出现推进速度不稳定的问题。
总体来说,我对结对编程的理解是:它是一种持续同步思路、互相校验理解的协作方式。其意义在于在任务推进过程中不断暴露问题、修正想法,并让结果比单独完成时更好。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
https://github.com/messmerr/BUAASE2026-PairProgramming-private
附录
附录 A:基于 PSP 2.1 修改的 PSP 表格
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 40 | |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | ||
| - Technical Background | - 了解技术背景(包括学习新技术) | ||
| - Coding Standard | - 代码规范 | ||
| - Design | - 具体设计(确定怎么实现) | ||
| - Coding | - 具体编码 | ||
| - Code Review | - 代码复审 | ||
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | ||
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | ||
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | ||
| - Size Measurement | - 计算工作量 | ||
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | ||
| TOTAL | 合计 |

浙公网安备 33010602011771号