→ 📖 Q0.0(P) 【你可以在结对结束后补充】如果你的代码仓库包含 AIGC 的部分,列举使用的工具、模型和使用范围。若未使用则填写:本组提交的全部代码不包含AI补全或生成的部分。
本组提交的代码包含少量 AIGC 辅助生成的部分。使用的工具主要是 Codex / GPT-5,使用范围主要包括:帮助理解题目要求、生成和补充测试样例、辅助完成 T2/T3 的部分代码实现。最终代码均经过人工检查和修改。
→ 📖 Q0.1(P) 请记录下目前的时间。
2026-04-04-20-10
→ 📖 Q0.2(I) 【你可以在结对结束后另行补充。】作为本项目的调查:
I,I
请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
请如实标注在开始项目之前对桌游花见小路的熟悉程度分级,可以的话请细化具体的情况。(分别回答两人各自的情况)
I. 不了解玩法和规则;
II. 听说过,且有一定了解;
→ 📖 Q0.3(P) 请记录下目前的时间。
2026-04-04 20:31
→ 📖 Q1.1(P) 请记录下目前的时间。
2026-04-04 20:35
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(例如查阅了哪些资料、如何设计判定逻辑、如何设计测试样例、遇到了什么问题、如何解决)。
2.查阅的资料:
查阅了https://www.assemblyscript.org/来学习as的基本语法
判定逻辑设计较为简单,根据指导书的说明直接实现
测试样例的设计:借助 AI 阅读指导书,根据规则给出了一些测试用例
遇到的问题:没有遇到什么难以解决的问题,可能也就是对语法不熟悉看了看官方教程
→ 📖 Q1.3(P) 请说明你们为这个判定模块设计了哪些中间量或辅助函数;如果没有额外设计,也请说明为什么认为直接实现已经足够清晰。
仅仅设计了“我”和对手的分数以及“我”和对手得到的倾心数作为变量,没有设计额外的辅助函数。T1的逻辑比较清晰,按照题目所给的逻辑依次下推不会出现什么大问题。
→ 📖 Q1.4(I) 请说明在这样一个规则判定类模块中,如何避免“漏判”“错判”或分支顺序错误等问题。
最好按照题目所给的判定逻辑,按照逻辑一步一步向下分析各种情况,最好是列个表格,避免错判漏判,这样能考虑周全。同时最好也要列好每种情况的优先级,容易实现的放在前面,这样分支的逻辑就会很清晰,顺序不会错。
→ 📖 Q1.5(P) 请说明你们设计了哪些测试用例,这些测试分别覆盖了哪一类规则或边界情况。
测试用例如下:
it("case1", () => { // 一方分值达到 `11` 分而获胜; assert.equal(judge([1, 1, 1, 1, 1, 0, 0], 1), 1); }); it("case2", () => { //一方获得至少 `4` 枚倾心标记而获胜; assert.equal(judge([1, 1, 1, 1, 0, -1, 0], 2), 1); }); it("case3", () => { //前两小轮结束时尚未满足胜利条件,应返回 `0`; assert.equal(judge([1, -1, 0, 0, 0, 0, 0], 2), 0); }); it("case4", () => { // 第三小轮结束时,总分不同,由总分高者获胜; assert.equal(judge([1, 1, 0, -1, 0, 0, 0], 3), 1); }); it("case5", () => { //第三小轮结束时,总分相同,由最高档位倾心标记判定胜负; assert.equal(judge([-1, 0, 0, -1, 0, 0, 1], 3), 1); }); it("case6", () => { //第三小轮结束时平局,应返回 `2`。 assert.equal(judge([1, -1, 0, -1, 1, 0, 0], 3), 2); });
→ 📖 Q1.6(I) 请说明你对“先写测试再实现”与“先实现再补测试”两种方式的理解。
先写测试再实现:更加严谨,但是比较反直觉,完成的代码安全性更好,但是交付更慢,适合一些对代码安全性要求高的情景
先实现再补测试:相对来说更加符合直觉,适合没有那么严谨的项目的开发,可能代码的bug数量不如前一种方法。
→ 📖 Q1.7(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
22026-04-04 21:58
→ 📖 Q1.8(I) 请写下本部分的心得体会。
及时编写测试是在开发中很重要的一部分。先写测试还是先实现可以视具体开发需求来定。面对复杂的开发要求可以先写测试,这样可以考虑周全。
→ 📖 Q2.1(P) 请记录下目前的时间。
2026-04-04 22:00
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
2.查阅的资料:
除了官方指导书没有参考其他资料
官方的指导书对于题目规则解释的很清楚,看着指导书要求直接写代码就行。
测试样例的设计:先跑了官方提供的样例,然后又拿 README 里的那组完整行动记录自己手动核对了一遍输出是否合理。
遇到的问题:一开始对 3 赠送和 4 竞争这种带选择的操作理解得不是很清楚,后来看了 README 里的表格和 T3 的实现之后才理顺。
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
复用了 T1 里用数组按 A-G 顺序处理状态的思路,得分标记 board 沿用了原来的表示方式。不同的是 T2 不再是直接判定胜负,而是先根据 history 统计双方场面上每种牌的数量,再根据这个结果去更新 board。另外为了处理行动记录,又补了几个小函数,比如牌字符转下标、给某一方加牌、比较两组牌是否一致等。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
可以把“解析记录”“更新场面”“根据场面更新得分标记”这几部分拆开写,这样子更加清晰。像牌数和得分标记这种信息也统一用数组来表示,不要写成很多分散的变量,这样后续改动会方便很多。对于赠送和竞争这种特殊操作,单独分类处理也会让代码更清晰。
→ 📖 Q2.5(P) 头脑风暴环节:
我们终于快要开始让程序玩游戏了!请尝试分析:T2 中不带 X 的操作记录比起实际对局多出了多少信息?如果加上 X,也就是失去了这部分信息的话,如何处理对小轮结束后状态的估计?
T2 中不带 X 的记录,比实际对局多出来的信息主要就是“最后公开后的完整信息”。也就是说,在 T2 里可以知道双方密约和取舍实际用了什么牌,也可以知道 3 赠送和 4 竞争里到底提供了哪些牌、最后又选了哪一组,因此可以把整轮结束后的场面唯一还原出来。
如果加上 X,就会失去这部分隐藏信息,尤其是不知道对方暗置的牌和弃掉的牌到底是什么。这种情况下,小轮结束后的状态通常就不能唯一确定了。比较合理的做法是维护一个“可能状态集合”,把所有和当前已知信息不矛盾的情况都保留下来;如果不想维护这么复杂,也至少可以统计每种牌出现的可能性,给出一个估计结果,而不是像 T2 这样直接给出唯一答案。
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录 A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026-04-04 23:10
→ 📖 Q2.7(I) 请写下本部分的心得体会。
T2 比 T1 更像是在做状态还原,重点不再只是写几个判定分支,而是先把输入记录真正看懂。做这一题时最明显的感觉就是,格式理解清楚以后实现并不算特别难,反而是一开始如果没有把 3 赠送和 4 竞争的含义理顺,就会很容易把整个逻辑写乱。
→ 📖 Q3.1(P) 请记录下目前的时间。
2026-04-04 23:15
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
2.查阅的资料:
主要还是查阅了 README 中 T3 的规则说明和测试方式。
因为 T3 需要和引擎对接,所以也看了 src/T3/hanamikoji-engine.js,主要是为了搞清楚 history 的格式、每一轮的出牌顺序以及输出不合法时会怎么判负。
实现时先做了 history 的解析,把当前回合已经发生的事情尽量还原出来,再枚举当前可选行动,最后用一个局面分数来选相对更优的行动。
遇到的问题:T3 最大的问题不是语法,而是策略怎么写。一开始如果只是随便合法出牌虽然也能跑,但效果很一般。后面改成先枚举、再评估局面的方式以后,逻辑就稳定很多。
→ 📖 Q3.3(P) 头脑风暴环节:
假设提供更充裕的时间和资源,这个游戏中你能找到的最优策略有可能是什么形式的?进行调研并总结分析。你还可以在任务结束后试着实现(不计分)。
如果时间和资源更充裕,最优策略大概率不会是简单的规则判断,而会更接近博弈搜索。
一种比较自然的思路是把游戏建模成一个带有隐藏信息的双人零和博弈,然后在当前信息集上做搜索。比如对未知牌的分布做采样,再对每个可能状态进行极小化极大搜索,最后综合这些结果选择期望收益最高的行动。
如果再进一步,也可以考虑用 MCTS 或者 CFR 这类方法。前者适合在大状态空间里做近似搜索,后者更适合处理不完全信息博弈。从理论上说,这种方向比手写启发式规则更有可能逼近真正的最优策略。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么选择行动类型?选牌如何更优?如何编程实现。
我们最后采用的是先还原状态,再枚举合法行动,最后给局面打分的做法。
先根据 history 判断当前是我行动还是我响应,同时统计双方已经用过哪些行动、自己和对手当前场面上已知的牌、对手还剩多少隐藏信息。这样就能先把当前局面尽量还原清楚。
在行动选择上,会把当前所有合法的 1、2、3、4 行动都枚举出来。对于 3 赠送和 4 竞争,还会把对手可能的选择一起考虑进去,不是只看自己当前能拿到什么,而是看如果对手选择了最不利于我的选项,这个行动值不值得出。
在选牌上,主要依据是局面分数。这个分数会综合考虑当前场面差距、哪些倾心标记更值钱、哪些标记已经偏向某一方、自己手里剩下的牌能不能在后续继续争夺,以及对手隐藏牌可能带来的影响。最后在所有合法行动中选择分数最高的那个。
→ 📖 Q3.5(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
T3 复用了 T2 中对 history 的理解方式,也继续沿用了按 A-G 顺序用数组来表示牌数和标记状态的方式。像牌字符转下标、给某一方加牌、处理 3 赠送和 4 竞争这些思路,本质上都是从 T2 延续过来的。
和 T2 相比,最大的变化是 T3 不再只是“还原结果”,而是在还原当前状态以后继续往前走一步,去决定接下来应该做什么。所以在 T2 的基础上又补了合法行动枚举、对手响应处理、局面评估和选优这些部分。
→ 📖 Q3.6(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
对于这种策略类代码,最好不要把解析输入、生成行动和评估局面全都混在一起写。拆开以后,如果以后规则变化,比如行动格式变了,或者评估方式要改,就只需要改某一部分。
另外,把场面信息统一表示成数组和状态对象也会比较方便。这样后面无论是增加新的评估维度,还是想尝试别的搜索方法,都不需要把整个代码推翻重写。
→ 📖 Q3.7(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块决策能力很强?”,尝试提出一些可能的定量分析方式或测试方式。
最直接的方法还是对局测试。
一种方法是固定几组不同风格的对手,比如随机策略、贪心策略、偏保守策略,然后统计多轮比赛里的胜率、平局率和先后手情况下的表现。如果对这些不同风格的对手都能稳定拿到比较好的结果,说明策略是有一定强度的。
还可以专门设计一些局面测试。比如给定某种已经很接近胜负手的 history、cards 和 board,看程序会不会做出明显更合理的选择。这样虽然不等同于真实比赛胜率,但能更细地看出程序的决策质量。
另外,也可以统计程序在每一步的耗时,确保不仅策略有效,而且能稳定在时限内做出决策。
→ 📖 Q3.8(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2026-04-05 02:38
→ 📖 Q3.9(I) 请写下本部分的心得体会。
T3 是三道题里最像真正写程序、实现软工的一题。前两题更多是按规则实现,搭积木就好了,而 T3 需要在规则之上再去想策略怎么设计。做完以后最大的感觉就是,规则理解只是第一步,真正难的是怎么把看起来合理的想法写成程序里可以稳定运行的决策逻辑。
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。
→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
这次结对整体上还是比较顺利的,主要的优点是两个人一直在对着同一个问题讨论,没有出现明显的分工割裂。
不过也有可以改进的地方。比如在 T2 和 T3 一开始理解题意的时候,如果能先把输入输出和关键规则都整理成一个更清晰的小表格,后面的返工应该会更少。还有就是在 T3 上花的时间明显更多,如果一开始就早点想好“先写一个能跑的版本,再逐步增强”,效率可能会更高一些。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:比较有耐心,讨论的时候愿意把问题一点点讲清楚;对整体任务进度有把握,不容易跑偏;在写代码和写文档之间切换得比较快。
缺点:有时候会先急着往下写,题目细节还可以再看仔细一点。
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
我觉得结对编程最大的优点是可以及时交流,很多一个人会卡很久的问题,两个人边说边想往往会很快理顺。缺点就是效率不一定始终比单人高,如果两个人都没有先把问题想清楚,也可能一起在错误方向上走很久。总体来说,我觉得结对编程更适合这种规则复杂、需要反复确认理解的任务。
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
sh/2026-SE-pair
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/258116.html