[P] 结对项目:花见小路

[P] 结对项目:花见小路

项目 内容
这个作业属于哪个课程 2026春软件工程
这个作业的要求在哪里 个人第二次作业
我在这个课程的目标 帮助了解结对编程、敏捷开发全流程,同时提升两人协作能力,提升交流效率
这个作业在哪个具体方面帮助我实现目标 从项目设计到实现,从交流到合作

→ 📖 Q0.0(P) 【你可以在结对结束后补充】如果你的代码仓库包含 AIGC 的部分,列举使用的工具、模型和使用范围。若未使用则填写:本组提交的全部代码不包含AI补全或生成的部分。

本组提交的全部代码不包含AI补全或生成的部分

Chapter.0 wasm从安装到入门

引入

→ 📖 Q0.1(P) 请记录下目前的时间。

2026/4/2 16:43

调查

→ 📖 Q0.2(I) 【你可以在结对结束后另行补充。】作为本项目的调查:

请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)

I. 没有听说过;

请如实标注在开始项目之前对桌游花见小路的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)

I. 不了解玩法和规则;

总结

→ 📖 Q0.3(P) 请记录下目前的时间。

2026/4/2 17:13

Chapter.1 七色之缨

结对过程

→ 📖 Q1.1(P) 请记录下目前的时间。

2026/4/2 17.14

→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:

  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
Personal Software Process Stages 个人软件开发流程 预估耗时(分钟) 实际耗时(分钟)
PLANNING 计划
- Estimate - 估计这个任务需要多少时间 68 115
DEVELOPMENT 开发
- Analysis & Design Spec - 需求分析 & 生成设计规格(确定要实现什么) 2 2
- Technical Background - 了解技术背景(包括学习新技术) 5 45
- Coding Standard - 代码规范 5 5
- Design - 具体设计(确定怎么实现) 10 5
- Coding - 具体编码 10 15
- Code Review - 代码复审 5 3
- Test Design - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) 5 5
- Test Implement - 测试实现(设计/生成具体的测试用例、编码实现测试) 10 20
REPORTING 报告
- Quality Report - 质量报告(评估设计、实现、测试的有效性) 5 5
- Size Measurement - 计算工作量 5 5
- Postmortem & Process Improvement Plan - 事后总结和过程改进计划(总结过程中的问题和改进点) 5 5
  • 通过视频网站了解花间小路规则,包括游戏规则、玩家操作、判断条件等。
  • 通过阅读wasm官方文档、课程组提供的guide.md,并结合AI询问,了解wasm的基本概念和使用方法。
  • 通过视频网站和rust官网学习rust的基本语法和概念。
  • 交流并讨论设计相关的判定函数。
  • 测试:先撰写一些边界情况测试,然后写python脚本随机生成测试用例。

设计

→ 📖 Q1.3(P) 请说明你们为这个判定模块设计了哪些中间量或辅助函数;如果没有额外设计,也请说明为什么认为直接实现已经足够清晰。

  • SCORE 全局变量,记录所有的分数。

  • judge_score_11 判定函数,用于判断玩家是否在当前轮中获得了 11 分。

  • judge_num_4 判定函数,用于判断玩家是否在当前轮中获得了 4 个艺妓的青睐。

  • judge_more_point 判定函数,用于在第三轮中,如果双方玩家不能通过judge_score_11和judge_num_4判断胜负,则通过比较分数高低来判断。

  • judge_dictionary 判定函数,用于在第三轮中,如果双方玩家不能通过judge_score_11,judge_num_4,- --

  • judge_dictionary 和判断胜负,则通过比较最高分倾心标记判断。

→ 📖 Q1.4(I) 请说明在这样一个规则判定类模块中,如何避免“漏判”“错判”或分支顺序错误等问题。

  • 在设计时:按照游戏的判断顺序,确定所有可能遍历的分止。可以画出一个流程图(树),展示所有的判断路径。
  • 在测试时:对于所有的分支,都编写一些测试案例。然后再撰写一些边界情况测试。

测试

→ 📖 Q1.5(P) 请说明你们设计了哪些测试用例,这些测试分别覆盖了哪一类规则或边界情况。

  • 一方超过11分情况
  • 一方获得11分另一方获得4个艺妓情况
  • 一方获得4个艺妓但无11分情况
  • 前两轮平局情况
  • 第三轮超过11分情况
  • 第三轮4个艺妓情况
  • 第三轮均未超过11分且未获得4个艺妓
    • 总分更高者赢情况
    • 同分下得分字典序大者赢情况
    • 平局情况

→ 📖 Q1.6(I) 请说明你对“先写测试再实现”与“先实现再补测试”两种方式的理解。

两种方法各有优劣

  • 先写测试再实现:提前考虑到所有的分支情况,编写合适的测试案例。同时先写的测试也对代码的实现有提示。
  • 先实现再补测试:代码已经实现。对于代码中可能会出现的问题,做出特定的测试案例验证。但有可能会忽略特定情况。

总结

→ 📖 Q1.7(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。

2026/4/2 18:54

→ 📖 Q1.8(I) 请写下本部分的心得体会。

本部分主要是通过一个简单的例子来熟悉rust的基本语法和概念,以及wasm的基本使用。同时初次体验了结对编程。在两个人的代码风格和思路都不同的情况下,通过讨论的方式得到最优解。同时熟悉后也为后续的开发提供了基础。

Chapter.2 不祥之影

准备

→ 📖 Q2.1(P) 请记录下目前的时间。

2026/4/2 19:08

→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:

  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
Personal Software Process Stages 个人软件开发流程 预估耗时(分钟) 实际耗时(分钟)
PLANNING 计划
- Estimate - 估计这个任务需要多少时间 165 215
DEVELOPMENT 开发
- Analysis & Design Spec - 需求分析 & 生成设计规格(确定要实现什么) 10 10
- Technical Background - 了解技术背景(包括学习新技术) 10 20
- Coding Standard - 代码规范 10 10
- Design - 具体设计(确定怎么实现) 10 20
- Coding - 具体编码 60 70
- Code Review - 代码复审 15 20
- Test Design - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) 15 10
- Test Implement - 测试实现(设计/生成具体的测试用例、编码实现测试) 20 40
REPORTING 报告
- Quality Report - 质量报告(评估设计、实现、测试的有效性) 5 5
- Size Measurement - 计算工作量 5 5
- Postmortem & Process Improvement Plan - 事后总结和过程改进计划(总结过程中的问题和改进点) 5 5
  • 依旧阅读指导书和rust文档
  • 设计Player和Action结构体,用于存储玩家信息和操作记录。
  • 为Player设计get_board(), add_card(), apply_action()方法,用于获取玩家当前状态、添加牌、应用操作。
  • 编写strip_history()函数,用于处理输入
  • 最后完成calc_current_state()函数
  • 手工编写了三个测试用例后,通过python脚本随机生成测试用例。

代码可复用性与需求变更

→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑‍💻 T1 中已实现的代码进行了哪些复用和修改。

无T1复用代码。

→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。

单一职责原则:将功能拆分,每个函数只负责一个功能,避免函数过长或复杂。
开放封闭原则:当需求变化时(比如发现要新添加参数),尽量通过新增代码来实现,而不是修改已有稳定代码。

头脑风暴环节

→ 📖 Q2.5(P) 头脑风暴环节:

我们终于快要开始让程序玩游戏了!请尝试分析:T2 中不带 X 的操作记录比起实际对局多出了多少信息?如果加上 X,也就是失去了这部分信息的话,如何处理对小轮结束后状态的估计?

T2相当于上帝视角,相比正式游戏可以多了解对少操作1和操作2的牌;

如果失去此信息,可以通过枚举牌的组合、计算概率或者从博弈论角度(即假定对手是理性最优策略反向推断其未展示的牌)等方法来预估。

总结

→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录 A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。

2026/4/3 19:54

→ 📖 Q2.7(I) 请写下本部分的心得体会。

第二部分主要是字符串的处理,难度比第一部分高,很容易出现一些疏忽的错误。深刻体会到了结对编程的好处。在结对编程中,因为用审核员的存在,一些小错误得以在开发早期被发现和修复。同时,还体会到了规范编程的重要性,在命名函数时还是要清晰,并注上必要的注释。在此次任务中就出现了混用函数的错误,耽误了不少时间检查。

Chapter.3 道途之荆

准备

→ 📖 Q3.1(P) 请记录下目前的时间。

2026/4/5 15:54

→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:

  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
Personal Software Process Stages 个人软件开发流程 预估耗时(分钟) 实际耗时(分钟)
PLANNING 计划
- Estimate - 估计这个任务需要多少时间 375 615
DEVELOPMENT 开发
- Analysis & Design Spec - 需求分析 & 生成设计规格(确定要实现什么) 20 20
- Technical Background - 了解技术背景(包括学习新技术) 10 10
- Coding Standard - 代码规范 10 20
- Design - 具体设计(确定怎么实现) 60 100
- Coding - 具体编码 220 400
- Code Review - 代码复审 20 30
- Test Design - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) 10 10
- Test Implement - 测试实现(设计/生成具体的测试用例、编码实现测试) 10 10
REPORTING 报告
- Quality Report - 质量报告(评估设计、实现、测试的有效性) 5 5
- Size Measurement - 计算工作量 5 5
- Postmortem & Process Improvement Plan - 事后总结和过程改进计划(总结过程中的问题和改进点) 5 5
  • 依旧阅读rust文档,学习rust的基本语法和概念。
  • 设计中考虑复用T2中的Player和Action结构体。
  • 通过进行多轮花间小路游戏分析策略,同时调研分析得到打分策略、蒙地卡罗模拟等方法,最后结合自身代码实力,选择贪心策略
  • 先实现整体框架,定义Strategy trait,然后优先实现随机策略,在test.js中测试,确认框架正确性。
  • 再实现贪心策略,在test.js中测试,确认正确性。同时与随机策略对比,分析贪心策略的优势与不足。
  • 通过修改test.js进行随机发牌后多次测试。
  • 与其他组同学进行对战,根据结果调整策略。

头脑风暴环节

→ 📖 Q3.3(P) 头脑风暴环节:

假设提供更充裕的时间和资源,这个游戏中你能找到的最优策略有可能是什么形式的?进行调研并总结分析。你还可以在任务结束后试着实现(不计分)。

1、引入对手信息建模,分析对手所需手牌。同时观察对手动作,通过贝叶斯更新其手牌的概率分布。从而可以预测对手想要的牌,可以添加诱饵策略。

2、进行长期规划,对后续抽牌和轮次分别建模。例如第一轮可以牺牲收益换取信息,越往后越注重得分。

3、对卡牌的重要性进行打分评估,从而决定牌的取舍。

4、通过CFR算法离线求解贝叶斯纳什均衡,得到可查表的最优混合策略。

需求建模和算法设计

→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么选择行动类型?选牌如何更优?如何编程实现。

行动类型选择:优先级策略。

  • 手牌有三张相同则执行赠与操作
  • 手牌有两对则进行竞争操作
  • 优先弃掉对方比自己多的牌,阻止对手得分
  • 根据双方中牌的数量判断牌的重要性,然后选取密约
  • 回退至随机策略

选牌策略:

  • 密约时:提高高分牌的优先级,同时避免拿对手已经有优势的牌
  • 回应赠与选牌时:优先选大牌,除非对手已经领先;其次抓可完成收集的牌,再抓对手少数牌,最后退回随机策略
  • 回应竞争选牌时:优先选打牌,除非对手领先;其次选完成度更高的组合的牌,其次选数值更大的牌,最后随机

编程实现:

  • 设计Player结构体:记录手牌、桌面牌、已做动作、未做动作
  • 设计Action结构体,对action封装
  • 定义Strategy trait,同时定义两个决策接口(give_advice和give_feedback)

辅助函数:

  • have_triple():检测三连张牌(供赠与选择)
  • have_double_double():检测两对(供竞争选择)
  • have_discard():检测玩家手里可丢弃的牌
  • is_critical():比较双方持有量判断手牌的关键性
  • would_complete():判断拿了此牌是否可以直接收集成功

构建RandomStrategy,用随机策略作为保底

代码可复用性与需求变更

→ 📖 Q3.5(P) 请说明针对该任务,你们对 🧑‍💻 T2 中已实现的代码进行了哪些复用和修改。

复用了T2中的Player结构体和Action结构体。

→ 📖 Q3.6(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。

将策略类与基础代码进行分离:这样只需要设计好接口,就可以方便地切换不同的策略。在这次项目中,我们设计了随机策略、贪心策略。如果后续需要添加其他策略,只需要实现对应的策略类,即可。

软件度量

→ 📖 Q3.7(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块决策能力很强?”,尝试提出一些可能的定量分析方式或测试方式。

通过修改给予的test.js代码,使其可以随机发牌,同时写脚本进行100次测评,观察胜率以及对局过程。(借用同学的胶水文件,或者与随机策略进行对比)

总结

→ 📖 Q3.8(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。

2026/4/9 18.36

→ 📖 Q3.9(I) 请写下本部分的心得体会。

最难的一部分是设计和实现策略,反而编程因为前两问的存在没有太难。
在设计方面,为了权衡代码工作量和实现效果部分,在讨论的部分花费了大量的时间。最终选择了局部最优化和贪心算法的结合。
在设计的过程中,两个人互补,说服对方改进方案从而不断优化,这也是结对编程的一个优势。

结对项目总结

结对过程回顾和反思

→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

13eb176c1addbbe40bb802ef332642fe

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。

1、部分函数命名不够直观,导致调用辅助函数时需要在代码中反复查找才能理解其用途

2、在动手编码之前,对整体架构和模块划分的设计讨论不够充分。

3、结对过程中的技术讨论有时表述不够精准,导致双方对同一问题的理解出现偏差。

→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。

优点:1、仔细,无论作为编程手还是审核员都能仔细检查代码,避免错误。
2、代码能力强,学习新语言非常快,同时还能指出我的错误。
3、有合作精神,善于通过讨论解决问题。

缺点:自称懒()

对结对编程的理解

→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。

优点:

  • 两个人一起做代码审核,可以及时发现错误,提高代码质量。
  • 提高效率,避免摸鱼。
  • 两人讨论出的方案通常比单人的更稳健,不易陷入思维盲区。

缺点:

  • 需要有足够的时间讨论,还要有时间磨合
  • 结对有时比单人更疲倦,需要保持良好的沟通和合作精神。

代码实现提交

→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。

代码仓库

posted @ 2026-04-10 14:26  Morty666  阅读(15)  评论(0)    收藏  举报