[P] 结对项目:花见小路
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 2026春季软件工程 |
| 这个作业的要求在哪里 | 结对项目:花见小路 |
| 我在这个课程的目标是 | 学习到软件工程中的各种最佳实践,然后实际运用到学习和未来的工作中 |
| 这个作业在哪个具体方面帮助我实现目标 | 学习结对编程相关知识并通过实践感受结对编程利弊 |
结对项目:博客问题清单
请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。
→ 📖 Q0.0(P) 【你可以在结对结束后补充】如果你的代码仓库包含 AIGC 的部分,列举使用的工具、模型和使用范围。若未使用则填写:本组提交的全部代码不包含AI补全或生成的部分。
Chapter.0 wasm从安装到入门
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2026.4.3 14:00
调查
→ 📖 Q0.2(I) 【你可以在结对结束后另行补充。】作为本项目的调查:
请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)
I. 没有听说过;✅️
请如实标注在开始项目之前对桌游花见小路的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)
I. 不了解玩法和规则;✅️
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2026.4.3 14:36
Chapter.1 七色之缨
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2026.4.3 14:38
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | |||
| - Estimate | - 估计这个任务需要多少时间 | 15 | 2 |
| DEVELOPMENT | |||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 60 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 60 | 4 |
| - Coding Standard | - 代码规范 | 15 | 1 |
| - Design | - 具体设计(确定怎么实现) | 90 | 6 |
| - Coding | - 具体编码 | 300 | 8 |
| - Code Review | - 代码复审 | 45 | 3 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 30 | 3 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 2 |
| REPORTING | |||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | 1 |
| - Size Measurement | - 计算工作量 | 15 | 0 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 25 | 0 |
| TOTAL | 705 | 35 |
- 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
先读题并整理胜负判定顺序,再把规则拆成计分、计数、档位比较几个部分实现。编码后先用题目样例测,再补边界测试。中间主要问题是第三轮平局细分容易写乱,最后靠拆辅助函数和补测试校正。
设计
→ 📖 Q1.3(P) 请说明你们为这个判定模块设计了哪些中间量或辅助函数;如果没有额外设计,也请说明为什么认为直接实现已经足够清晰。
我们设计了4个辅助函数:
| 函数 | 职责 | 设计理由 |
|---|---|---|
getOwnedScore |
计算指定方拥有的倾心标记总分 | 将"按角色分值累加"的逻辑独立封装,避免主函数中出现重复计算代码 |
getOwnedCount |
计算指定方拥有的倾心标记数量 | 独立封装计数逻辑,与计分逻辑解耦 |
cmpTier |
比较某一分数档位内双方的归属情况 | 处理第三小轮中同档位多角色(D/E、A/B/C)的平局细分逻辑 |
cmpHighestTier |
按优先级顺序比较最高档位 | 封装档位优先级顺序(G > F > D/E > A/B/C),主函数只需调用一次 |
这样的设计满足单一职责原则,即每个函数只做一件事儿;能够消除重复,计分/计数逻辑在"立即胜利条件"和"第三小轮判定"中都需要,提取后避免代码重复;规则映射直观,cmpHighestTier 中的 if 顺序直接对应题目优先级(G>F>D/E>A/B/C),可读性强;主函数流程清晰,hanamikoji_judge 按"立即胜利条件 → 轮次判断 → 第三小轮细分"的顺序展开,分支结构扁平。
→ 📖 Q1.4(I) 请说明在这样一个规则判定类模块中,如何避免“漏判”“错判”或分支顺序错误等问题。
我觉得关键是先把规则顺序写清楚,再按顺序实现。像这题就先判 >=11,再判 >=4枚,最后才处理第三轮细分,不能混着写。代码里把计分、计数、档位比较拆开,也更不容易漏情况。最后再用边界测试兜住。
测试
→ 📖 Q1.5(P) 请说明你们设计了哪些测试用例,这些测试分别覆盖了哪一类规则或边界情况。
我们一共设计了6个测试样例:
| 用例 | 名称 | 覆盖规则/边界情况 |
|---|---|---|
| 1 | score threshold wins immediately |
立即胜利条件①:一方总分≥11分(己方A+B+C+G=2+2+2+5=11,第1小轮立即获胜) |
| 2 | four markers win immediately |
立即胜利条件②:一方获得≥4枚标记且对方未达11分(对方4枚A/B/C/D,第2小轮) |
| 3 | round two continues when no win condition is met |
继续游戏:第1/2小轮未满足任何胜利条件时返回0(双方各2枚,均未达4枚或11分) |
| 4 | round three compares total score first |
第三小轮判定①:总分比较(己方A+E=2+3=5,对方F=4,己方总分高获胜) |
| 5 | round three breaks score tie by highest tier |
第三小轮判定②:总分相同,比较最高档位(己方有F=4分档,对方最高D/E=3分档,己方胜) |
| 6 | round three returns draw when highest non-empty tier is shared |
第三小轮判定③:平局情况(双方各2枚,总分相同,最高非空档位D/E中双方都有,返回2) |
完整性对应如下:
| 规则类别 | 覆盖状态 |
|---|---|
| 立即胜利条件①(≥11分) | ✅ 用例1 |
| 立即胜利条件②(≥4枚且对方<11) | ✅ 用例2 |
| 第1/2小轮继续游戏 | ✅ 用例3 |
| 第三小轮总分比较 | ✅ 用例4 |
| 第三小轮最高档位比较 | ✅ 用例5 |
| 第三小轮平局 | ✅ 用例6 |
随后又补充12个测试样例:
| 用例 | 名称 | 覆盖规则/边界情况 |
|---|---|---|
| 1 | over 11 points wins | 超过11分获胜(12分场景,验证≥11分条件) |
| 2 | exactly 4 markers with 9 points | 恰好4枚且总分<11获胜(A+B+C+D=9分,验证4枚条件独立于11分条件) |
| 3 | 5 markers wins | 超过4枚获胜(对方5枚,验证数量条件不严格等于4) |
| 4 | opponent 11 points | 对方11分获胜(验证-1返回值,双方胜负对称性) |
| 5 | all neutral round 1 | 全中立初始状态第1小轮继续(边界:零和状态,游戏未开始) |
| 6 | all neutral round 3 draw | 全中立第3小轮平局(边界:零和状态持续到终局) |
| 7 | round 3 score diff | 第3小轮总分不同(基础:总分优先判定胜负) |
| 8 | round 3 A/B/C tier draw | 第3小轮A/B/C档位平局(边界:同档位内无法区分,最终平局) |
| 9 | 0 vs 3 markers round 2 | 己方0枚对方3枚第2小轮继续(边界:极端不均衡但未达胜利条件) |
| 10 | all 7 markers | 单方全拿7枚(极端:满分21分,验证立即胜利条件触发) |
| 11 | round 3 F tier wins | 第3小轮F档位决胜(档位优先级:F > D/E,总分相同时高档位胜) |
| 12 | 3 markers round 1 | 3枚标记第1小轮继续(边界:接近4枚但未达条件,轮次继续) |
完整性如下:
| 规则维度 | 覆盖情况 |
|---|---|
| 立即胜利条件(≥11分) | 用例1、4、10 |
| 立即胜利条件(≥4枚且对方<11) | 用例2、3、12 |
| 轮次继续(round 1/2未达标) | 用例5、9、12 |
| 第3小轮总分比较 | 用例7 |
| 第3小轮档位比较 | 用例11 |
| 第3小轮平局 | 用例6、8 |
| 边界值(恰好/超过/不足) | 用例1、2、3、12 |
| 极端状态(全拿/全空) | 用例5、6、10 |
| 双方对称性(1/-1返回值) | 用例3、4 |
→ 📖 Q1.6(I) 请说明你对“先写测试再实现”与“先实现再补测试”两种方式的理解。
先写测试更适合这种规则明确的题,能先把判定标准卡死,写的时候不容易跑偏。先实现再补测试也有用,适合一开始还没完全想清楚的时候,先把主流程搭出来再查漏补缺。我们这次更像是先实现,再靠测试补边界。
总结
→ 📖 Q1.7(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
15:13
→ 📖 Q1.8(I) 请写下本部分的心得体会。
这一部分看起来简单,实际容易错在细节,尤其是第三轮的比较顺序。做完之后我感觉,把规则拆小、把测试补全,比一开始追求一口气写完更重要。
Chapter.2 不祥之影
准备
→ 📖 Q2.1(P) 请记录下目前的时间。
2026-04-04 23:08
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
预计耗时如下:
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 3 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 6 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 7 |
| - Coding Standard | - 代码规范 | 5 | 2 |
| - Design | - 具体设计(确定怎么实现) | 10 | 8 |
| - Coding | - 具体编码 | 20 | 18 |
| - Code Review | - 代码复审 | 10 | 6 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 6 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 7 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 3 |
| - Size Measurement | - 计算工作量 | 1 | 1 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 2 | 1 |
| TOTAL | 合计 | 98 | 68 |
完成任务期间的过程记录如下:
- 首先明确
calc_current_state(history, board)的输入输出形式,同时理解四条规则 - 实现时将问题拆成:字符串分词、单个行动解析、赠予/竞争的选择处理、场面牌计数更新、最后的
board结算 - 初版实现完成后,先通过仓库自带样例测试,然后编写更多更强的样例,包括:空历史、重复空格、全密约、全取舍、重复牌赠予、竞争组选取、顺序无关匹配、旧标记保留等边界情况。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
相较于T1,T2增加了如下内容:
- 新增了对字符串记录格式的解析能力。T1 基本只处理数组;T2 必须处理空格分割、
-连接的响应记录、以及竞争中前后两组牌的拆分。 - 新增了对四类行动语义的建模。
- 测试方面也从 T1 的规则点样例测试,扩展为 T2 的状态恢复测试
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
这次 T2 我们尽量把容易变化的规则拆开写。比如 tokenize 只负责分词,applyDirectAction 只负责处理 1/2/3/4 四类行动,resolveBoard 只负责结算标记。这样以后如果记录格式、行动规则或结算方式变了,只需要改对应函数,不用整段重写。另外我们没有直接改原 board,而是先复制成 nextBoard 再结算,这样更方便排查问题,也方便以后同时保留旧状态和新状态。
头脑风暴环节
→ 📖 Q2.5(P) 头脑风暴环节:
我们终于快要开始让程序玩游戏了!请尝试分析:T2 中不带 X 的操作记录比起实际对局多出了多少信息?如果加上 X,也就是失去了这部分信息的话,如何处理对小轮结束后状态的估计?
- 对手通过密约和取舍隐藏掉的具体牌面信息。如果对手执行了
1X或2XX,我们就只能知道对手消耗了几张牌,但无法知道具体是哪几张;但是在 T2小轮结束后这些信息会被公开,所以我们实际是上拿到了完整信息,可以据此恢复双方当前公开区和暗置区的牌数 - 所有需要保密的动作最终都能知道对应了哪些具体牌
如果重新把 X 加回来,那对于小轮结束后状态的估计就无法得到一个确定的结果,只能得到一个可能状态集合或概率分布。可以用当前已知信息维护一个约束集合,记录哪些牌已经公开、哪些牌已经被消耗但花色未知、哪些牌仍可能留在对手手中或暗置区。对于 1X 和 2XX 这类动作,仅更新“对手少了 1 张或 2 张未知牌”,但花色未知,并利用后续又出现赠予、竞争、公开选牌等动作缩小这些未知牌的可能范围;例如某些花色的总数已经被用满,就可以排除它们继续出现在未知牌中的可能。若需要估计小轮结束后的状态,可以枚举所有满足约束的合法状态;如果状态空间较大,则可改用采样或启发式评估,对每种可能状态计算一个权重,再输出期望分布或最可能状态
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录 A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026-04-04 23:08
→ 📖 Q2.7(I) 请写下本部分的心得体会。
这一部分感觉最大的作用就是带我准确的理解游戏规则,理解之后写起来还是好写的
Chapter.3 道途之荆
准备
→ 📖 Q3.1(P) 请记录下目前的时间。
2026.04.06 23:00 → 04.07 00:30 ; 04.08 12:00 → 04.08 14:00
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
头脑风暴环节
→ 📖 Q3.3(P) 头脑风暴环节:
假设提供更充裕的时间和资源,这个游戏中你能找到的最优策略有可能是什么形式的?进行调研并总结分析。你还可以在任务结束后试着实现(不计分)。
最优策略可能基于博弈论,如蒙特卡洛树搜索或强化学习,评估所有可能行动的胜率。花见小路类似的卡牌游戏,可以使用状态空间搜索模拟对局。实现可能需要构建树,计算每步的期望值,但由于时间有限,未实现。
需求建模和算法设计
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么选择行动类型?选牌如何更优?如何编程实现。
优先选择低编号行动,检查历史记录避免重复。选牌从手牌字符串前缀选取。编程实现:解析历史字符串提取已用行动,循环选择可用类型,验证手牌数量。
代码可复用性与需求变更
→ 📖 Q3.5(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
未复用T2代码,T3专注于决策函数,而T2是状态计算。
→ 📖 Q3.6(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
设计思想:模块化,将解析历史、选择行动分离。冗余:添加边界检查,如手牌不足时fallback。使用类型安全(Int8Array),便于扩展到更复杂策略。
软件度量
→ 📖 Q3.7(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块决策能力很强?”,尝试提出一些可能的定量分析方式或测试方式。
有效性通过测试框架验证:运行完整对局,检查无异常。定量:胜率统计(与随机对手比较)、决策时间(<2秒)、覆盖率(测试不同局面)。强决策:高胜率、低超时。
总结
→ 📖 Q3.8(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
04.08 14:04
→ 📖 Q3.9(I) 请写下本部分的心得体会。
与队友在沟通协作中实现了简单的决策策略,在过程中体会到沟通协作的重要性
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
过程整体顺利,但可以增加更多测试和用例,提升策略复杂度。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:性格开朗沟通顺畅;代码能力强;编写测试样例严谨细致
缺点:有点忙,不太好约时间
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:在沟通中能够产生很多新的想法
缺点:协调成本高。很吃配合
整体上结对编程强调协作,合理搭配下往往能够提高代码质量。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。

浙公网安备 33010602011771号