[P] 结对项目:影蛇舞
结对项目:博客问题清单
请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025 年 3 月 26 日 14:22。
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
II. 仅限于听说过相关名词。
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025 年 3 月 26 日 14:47。
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025 年 3 月 26 日 14:47。
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
 - 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
 
任务期间:
- 查阅AssemblyScript文档,学习基本语法
 - 设计防撞函数和防吃自己函数
 - 初步设计函数结构,遍历四个方向计算曼哈顿距离从而决定最终方向
 - 改进函数,变为判断$\Delta x$和$\Delta y$来决定放向,但是遇到了不好判断防撞的问题
 - 改回初步设计并进行代码复审
 - 构造测试样例,通过测试
 - 提交代码
 
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
设计测试:在设计过程中,我们认为测试的重点在于确保蛇不会撞墙或者吃到自己,因此我们主要考虑果子和墙与蛇的相对位置,并尽可能覆盖更多情况。
实现测试:我们在原有代码框架的基础上,新增了两组测试数据,希望能覆盖更多情况。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
单元测试对软件的最小单元进行测试,可以将测试拆分为多个模块,降低每个模块的测试复杂度。当软件产生 bug 时,通过单元测试也可以尽早发现并快速定位到 bug。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025 年 3 月 26 日 16:20。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | 10 | 5 | 
| - Estimate | - 估计这个任务需要多少时间 | 10 | 5 | 
| DEVELOPMENT | 开发 | 100 | 75 | 
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 20 | 15 | 
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | 20 | 
| - Coding Standard | - 代码规范 | 0 | 0 | 
| - Design | - 具体设计(确定怎么实现) | 10 | 10 | 
| - Coding | - 具体编码 | 20 | 10 | 
| - Code Review | - 代码复审 | 10 | 10 | 
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 5 | 
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 5 | 5 | 
| REPORTING | 报告 | 15 | 13 | 
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 4 | 
| - Size Measurement | - 计算工作量 | 5 | 4 | 
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 | 
| TOTAL | 合计 | 125 | 93 | 
→ 📖 Q1.6(I) 请写下本部分的心得体会。
这是我第一次体验结对编程。除去设计、编码、测试,我在回答指导书提出的问题上花费了不少时间。尤其是 PSP 表格:预估耗时的估计结果不太准确,实际耗时计算起来也比较困难。我对这些问题的回答质量都一般,很明显对结对编程还不够熟悉,需要多加练习。
另外本次结对编程给了我一个入门 WebAssembly 的机会,对我很有帮助。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025 年 3 月 28 日 19:22。
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
 - 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
 
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
由于需求变化大,我们对 T1 中已实现的代码复用较少,仅仅复用了判断碰撞逻辑。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
设计思想:可以将地图的数据和方法封装在地图类里,以便日后进行扩展或修改。
设计冗余:可以将代码中的魔数定义为常量,便于日后统一修改。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
直接使用搜索即可。在 T2 的场景中,需要搜索蛇从当前位置移动到果子位置的路径。在给定的场景中,需要搜索蛇从当前位置以一定顺序经过所有果子位置的路径。这种情况下,我们需要依次枚举第一个、第二个……最后一个经过的果子,然后使用 T2 的算法生成移动路径。
值得注意的是,在某些特定的地图中,蛇在吃掉果子后会无路可走,撞墙死亡,例如下图:
 #       ##     # 表示障碍物
#*      #*      * 表示果子
 #       ##
由于题目保证存在路线,所以这种情况只会最多出现一次,遇到这种情况时,需要进行回溯,回到上一个果子处,然后尝试另一种排列方式。时间复杂度为 $O(n)$。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
- 3 月 28 日 19:22 - 19:27:读题
 - 19:27 - 19:32:估计耗时
 - 19:32 - 19:52:解题
 - 19:52 - 20:02:初始化项目
 - 20:02 - 20:07:解题
 - 20:07 - 20:52:写代码
 - 20:52 - 21:01:休息
 - 21:01 - 21:29:复审
 - 21:29 - 22:02:测试实现(测试设计在解题过程中完成)
 - 22:02 - 22:12:修 bug
 - 3 月 29 日 15:42 - 16:34:修 bug
 - 16:34 - 16:52:答题
 - 16:52 - 17:00:统计耗时
 
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 | 
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 | 
| DEVELOPMENT | 开发 | 105 | 198 | 
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 15 | 5 | 
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 0 | 
| - Coding Standard | - 代码规范 | 0 | 0 | 
| - Design | - 具体设计(确定怎么实现) | 10 | 25 | 
| - Coding | - 具体编码 | 30 | 107 | 
| - Code Review | - 代码复审 | 10 | 28 | 
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 0 | 
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 33 | 
| REPORTING | 报告 | 30 | 26 | 
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 0 | 
| - Size Measurement | - 计算工作量 | 0 | 8 | 
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 18 | 
| TOTAL | 合计 | 140 | 229 | 
→ 📖 Q2.7(I) 请写下本部分的心得体会。
本部分花了近 4 个小时完成,比预期多了 1 个多小时。为什么会花费这么久呢?我认为原因有二。一是题目较难,需要涉及到搜索算法。二是我们被两个 bug 困扰了很久:一个是坐标转换,另一个是转圈圈。
为了理解直观与调试方便,我们用字符画来存储地图,但是由于忘了做坐标转换,在测试环节老是出错。最后我们引入了在输入输出时使用的 (x, y) 坐标与存储时使用的 (i, j) 坐标间转换的函数。另外,由于我们设定在目标可达时优先向上、左、下、右移动,这就导致蛇在某些地图中会不停的转圈圈,为此我们不得不在搜索时添加了路径记忆的功能。
通过本部分的开发,我们认识到了 bug 对软件开发的影响,并尽量在设计阶段考虑更为周密,减少 bug 的产生。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025 年 3 月 30 日 19:18
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
 - 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
 
任务期间:
- 分析编码路线,人工设计还是运用强化学习
 - 使用强化学习训练初始模型,效果并为达到期望值
 - 用基于T1的模型以及强化学习的模型辅助完善人工设计的模型
 - 与其他组协商,一起测试模型
 
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
数据建模
- 蛇与果子的位置:代码使用一维整型数组来存储蛇体的位置(例如 
[head_x, head_y, body1_x, body1_y, ...]),以及存储果子位置的数组[food_x, food_y]。这种数据结构简单明了,便于在固定尺寸的棋盘(例如 8×8)上进行计算。 - 方向建模:定义了 
Direction类,其中包含水平方向和垂直方向的偏移量(dx和dy)以及对应的编码。代码中用 0、1、2、3 分别表示上、左、下、右,从而建立方向空间。 
逻辑建模
- 移动决策模型:代码分成几个阶段,首先根据当前头和第二节的相对位置推导当前运动方向,然后过滤掉反向(逆转)和非法(出界或与己身碰撞)的方向。
 - 威胁评估模型:引入了 
DangerPoint类,通过为其他蛇的头、第二节、第三节以及预测的危险移动位置赋予不同的权重,从而建立起“危险地图”,为决策提供风险量化。 - 目标追踪模型:通过计算曼哈顿距离来估算蛇头与果子之间的距离,进而对方向进行打分,目标是最小化与果子的距离,从而实现吃到更多果子的目的。
 
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
- 避免死亡
- 边界检测:函数 
is_out_of_bounds用于判断新蛇头是否越界,防止走到棋盘边缘之外。 - 碰撞检测:函数 
collides检查新蛇头是否会与蛇体内部(特别是第二节)相撞;同时在基础候选方向阶段通过遍历蛇体的部分坐标避免自身碰撞。 - 危险地图:在阶段2中,代码根据其他蛇的位置和预测的移动(通过 
greedyOtherSnakeMove)构造了一个危险点地图,对高风险区域给予较高的扣分,从而在评分阶段降低选取此方向的可能性。 - 逆向避让:在评估方向时,如果当前候选方向正好与其他蛇的运动方向相反(说明对方可能主动避让),则会适当增加分数。
 
 - 边界检测:函数 
 - 吃到更多果子
- 曼哈顿距离计算:在阶段3中,对每个合法方向,代码计算了蛇头到所有果子的曼哈顿距离,并使用公式 
5 * (2 * board_size - minFruitDist)对方向打分,鼓励选择能更快接近果子的方向。 - 方向评分:结合距离、危险权重、以及边界距离(作为安全缓冲)对方向进行综合评分,确保既追求果子也保持生存空间。
 
 - 曼哈顿距离计算:在阶段3中,对每个合法方向,代码计算了蛇头到所有果子的曼哈顿距离,并使用公式 
 - 编程实现策略
- 分阶段决策:代码分为“候选方向筛选”、“威胁预测”和“方向评分”三个阶段,使逻辑分层清晰,每一部分都针对特定风险和目标进行评估。
 - 权重调控:通过对不同危险点赋予不同的权重(例如头部权重 7、第二节权重 5、第三节权重 3,以及由果子距离产生的额外权重),从而使决策既考虑进攻(吃果子)也考虑防守(避免危险)。
 - 排序与选择:最后通过将候选方向按照综合分数排序,选取得分最高的方向,保证最终决策能在风险与收益之间达到平衡。
 
 
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
可以采用以下几种定量分析方式来说明程序模块的“对弈”能力和决策效果:
- 生存回合数
- 统计平均存活回合:在大量模拟游戏中,记录蛇在游戏中存活的回合数,计算平均值和分布情况。生存时间越长,说明决策在规避危险方面表现较好。
 
 - 果子获取率
- 果子吞噬数量:统计每局游戏中蛇获取果子的数量或比例,与其他策略或随机走法进行对比。更多的果子往往意味着更强的进攻性和目标达成效率。
 
 - 胜率或排名
- 对弈胜率:在多人对弈的场景下,可以统计模块与其他蛇之间的胜率、排名情况、淘汰率等指标,从而判断其综合对弈能力。
 
 - 决策时间和资源占用
- 响应速度:测量每次决策的计算时间,确保决策过程在实时对弈中足够高效。
 
 - 仿真对比试验
- 多策略对比:构造基准策略(如随机移动、固定方向移动等),在相同环境下模拟多次对弈,比较各策略在生存、得分、果子获取等指标上的表现,利用统计方法(例如 t 检验)验证改进的决策策略是否具有显著优势。
 
 
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025 年 4 月 4 日 19:36
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | 10 | 15 | 
| - Estimate | - 估计这个任务需要多少时间 | 10 | 15 | 
| DEVELOPMENT | 开发 | 400 | |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 30 | 15 | 
| - Technical Background | - 了解技术背景(包括学习新技术) | 60 | 40 | 
| - Coding Standard | - 代码规范 | 0 | 5 | 
| - Design | - 具体设计(确定怎么实现) | 30 | 20 | 
| - Coding | - 具体编码 | 180 | 240 | 
| - Code Review | - 代码复审 | 20 | 15 | 
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 20 | 25 | 
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 60 | 55 | 
| REPORTING | 报告 | 40 | 35 | 
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | 15 | 
| - Size Measurement | - 计算工作量 | 0 | 5 | 
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 15 | 
| TOTAL | 合计 | 450 | 465 | 
→ 📖 Q3.7(I) 请写下本部分的心得体会。
在本部分开始,我们尝试使用强化学习来优化性能,但最终因失败而放弃。成功的道路上难免会遭遇失败,此时需要我们总结经验教训,选择新的方向。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
- debug的策略和流程可以再完善一下
 - 测试的流程与方式也有改进空间,可以与队员有更多的思考与沟通
 
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
我的搭档是高子贺。
优点:
- 学识渊博:编程知识与经验较为丰富。
 - 眼疾手快:编写代码速度快、质量高。
 - 憨态可掬:面带微笑,平易近人。
 
缺点:
- 加强合作:在合作时还需要多沟通、多交流。
 
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:结对编程可以结合两个人的力量,通过分工来提高共同的效率。结对编程也可以通过“老带新”模式快速提升新人编程水平。
缺点:有些时候,结对编程的效率不如两人单独开发的效率高。如果结对的两人实力差距过大,在沟通交流方面会出现困难。
我的理解:结对编程是一种有趣的开发模式,适用于单人项目或小型项目。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
https://github.com/Aron00123/BUAASE2025-PairProgramming
附录
附录A:基于 PSP 2.1 修改的 PSP 表格
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | ||
| 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号