[P] 结对项目:影蛇舞
| 项目 | 内容 | 
|---|---|
| 这个作业属于哪个课程 | <2025年春季软件工程> | 
| 这个作业的要求在哪里 | <[P] 结对项目:影蛇舞> | 
| 我在这个课程的目标是 | 学习软件工程的理论,将理论与实际相结合,提升系统思维的能力 | 
| 这个作业在哪个具体方面帮助我实现目标 | 通过实现一个简单的贪吃蛇游戏,体验和理解结对编程 | 
结对项目:博客问题清单
请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025-03-27 19:42:24
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
I. 没有听说过
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025-03-27 20:07:03
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025-03-27 20:07:03
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
 
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
 
1、表格见总结部分
2、在开始之前,我先进行了运行环境的配置,然后看了给出的[G.2]文档,对AssemblyScript语言有一个基本的了解。查阅了AssemblyScript语言的基础语法,进行了简单的开发实践。发现这个语言和JavaScript/TypeScript 语法类似,虽然有一定的出入,但是上手写一些简单的代码也比较容易。在对这个语言有一个基本的了解以后,我们就上手开发了。在开发过程中也会遇到一些问题,可能是因为对新语言的一些基本语法不太熟悉,但是在查阅相关资料后都能够及时解决,总体进展还比较顺利。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
T1的需求是比较简单的,只需要考虑一个果子,蛇移动到果子的位置就可以,需要保证蛇不会碰到自己的身子以及不会碰到墙壁。在测试时需要考虑蛇的初始位置和果子的位置。我们考虑将果子放在边界以及对角的位置,保证蛇在移动的过程中不会碰到墙壁。测试的有效性就是保证测试样例是符合题目要求的。
我们需要考虑以下几种情况:首先是最基础的情况,即蛇头与果子直线无障碍时,验证能否直接移动;接着是避免碰撞,即蛇头靠近场地边缘时,验证是否避免越界;最后是避免回头撞身。这样基本保证了测试的全面性。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
单元测试对于软件开发有着非常重要的作用,首先可以验证功能的正确性,然后可以促使我们编写更模块化的代码,使得代码更加容易维护,避免了之后可能的重构,每次单元测试之后相当于对已有的代码的一个梳理,有助于程序员理解代码。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025-03-27 21:42:38
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | 3 | 3 | 
| - Estimate | - 估计这个任务需要多少时间 | 3 | 3 | 
| DEVELOPMENT | 开发 | 112 | 125 | 
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 7 | 
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 15 | 
| - Coding Standard | - 代码规范 | 2 | 3 | 
| - Design | - 具体设计(确定怎么实现) | 10 | 10 | 
| - Coding | - 具体编码 | 40 | 40 | 
| - Code Review | - 代码复审 | 10 | 20 | 
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 20 | 20 | 
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 10 | 
| REPORTING | 报告 | 28 | 18 | 
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | 15 | 
| - Size Measurement | - 计算工作量 | 3 | 3 | 
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 | 
| TOTAL | 合计 | 143 | 151 | 
→ 📖 Q1.6(I) 请写下本部分的心得体会。
第一个题还是比较简单的,对于我来说更多的是收获了如何构建wasm。在这上面还是踩了一点坑。第一题虽然简单,但是还是出了一点点问题,不过很快就解决了。相当于为之后的代码实践打好基础。在结对的过程中,还是从对方身上学到了不少我不知道的东西,收获蛮大的。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025-03-29 19:10:38
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
 
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
 
第二题相比第一题增加了障碍物的设置。蛇有可能由于障碍物的存在永远无法吃到果子。蛇是否能够吃到果子是一开始就可以确定的。在判定蛇能否吃到果子,我们采用了广度优先搜索进行可达性检查。所以我们搜集了相关的资料,依据BFS进行第一步的可达性检查。在程序的第一步,首先判断是否可达,接下来设计蛇移动的方向。首先排除反方向,这样会导致蛇与自己相碰,接下来再进行避免与障碍物和墙壁的碰撞。此时可能会有多种有效的方向,为了避免蛇永远绕圈子,我们选择优先直行。
在编码过程中,我们遇到的bug是在第一步排除反方向之后将有效方向存在了一个数组里面,但是在之后排除其他方向的时候,我们又使用了未排除反方向的数组,导致发生错误。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
在第二题的实现中,我们对第一题的代码进行了以下复用和修改:
- 
复用部分:继续T1的蛇头和身体坐标的处理方法:在T1中,我们已经定义了蛇头和身体各部分的坐标,并计算了蛇头与身体第一节的相对方向。在T2中,我们保留了这些处理逻辑,以确保蛇的基本运动机制不变。
 - 
修改部分:修改了方向选择和碰撞检测逻辑:T1的 greedy_snake_move 函数通过计算与食物的曼哈顿距离来选择移动方向。在T2的 greedySnakeMoveBarriers 函数中,我们在此基础上增加了障碍物的检测,通过传入的 barriers 参数构建了一个障碍物集合,并在计算新头坐标时检查该位置是否为障碍物。如果是障碍物确保蛇在移动时避开障碍物。我们在开始时使用广度优先搜索(BFS)进行可达性检查,只有在存在可达路径的情况下,才会有后续动作。
 
通过上述修改,我们在保留 T1 中基本逻辑的基础上,增强了蛇在有障碍物环境下的智能决策能力,使其能够避开障碍物,朝向食物移动。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
设计思想:
- 模块化设计。我们在学习面向对象的时候曾经接触过SRP原则,即每个模块只负责单一职责,将功能划分为独立的模块。在这个题当中,就是把判断是否可达放在了另一个函数中,而不是混杂在主函数里面,这样提升了代码的模块性。而其他一些简单的功能并没有单独设置函数,那样可能会导致太复杂
 - 测试驱动开发。我们在每次实现一个新功能的时候,都进行一个简单的测试,避免最后找不到bug
 
设计冗余:
我们使用了通用的,易于扩展的数据结构,便于以后的扩展。在设计时预留扩展,持动态添加新功能。
头脑风暴环节
→ 📖 Q2.5(P)只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
当不止一个食物时,可能出现某些食物位于角落或被障碍物包围时,贪吃蛇吃掉这些果子后可能陷入困境,无法继续行动。为解决这一问题,可以先定顺序,再找路径。
先确定吃果子的顺序。 用贪心法,每次选离当前蛇头位置最近且周围障碍物少的果子(比如中心区域的)。例如,假设有三个果子,其中两个在中间、一个在角落,优先吃中间的。计算每个果子的“安全分”:周围格子中障碍物越少得分越高,优先选高分果子。再分阶段找路径。按顺序用BFS算法找当前到下一个果子的最短路径。根据这样的方法,基本能够找到一条吃完所有果子的行动路径。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025-03-29 21:21:04
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 | 
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 | 
| DEVELOPMENT | 开发 | 140 | 97 | 
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 | 
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 5 | 
| - Coding Standard | - 代码规范 | 15 | 5 | 
| - Design | - 具体设计(确定怎么实现) | 15 | 15 | 
| - Coding | - 具体编码 | 60 | 30 | 
| - Code Review | - 代码复审 | 10 | 15 | 
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 15 | 10 | 
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 7 | 
| REPORTING | 报告 | 30 | 20 | 
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 15 | 10 | 
| - Size Measurement | - 计算工作量 | 5 | 3 | 
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 7 | 
| TOTAL | 合计 | 175 | 122 | 
→ 📖 Q2.7(I) 请写下本部分的心得体会。
即使是两个人还是会写出bug的。不过比第一题来说,只需要考虑算法和实现的问题而不用想半天环境部署的问题了,实际上比第一题更加轻松一点。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025-03-29 21:21:04
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
 
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
 
我们首先是理解题目的意思,并且开始思考我们的策略。当我们在思考蛇移动的策略的时候,已经有人提交了结对编程的作业了。我们试着参考了别人的思路,但是感觉到太复杂,所以我们还是使用比较朴素的策略进行实现。在开发之前,我们对于题目的意思还是有点理解不清,查阅了资料学习如何部署。我们在最开始实现了一个没有任何策略的贪吃蛇,试着部署跑一下。当我们跑通以后才开始实际的编码。在开发过程中我们发挥两个人的智慧,想法设法优化代码。最后把我们的代码跑通以后出现了不和预期的结果,最终仔细走读代码,发现是在确定蛇头的下一步位置的时候,将蛇头位置放在了斜对角,而不是相邻的位置。修改代码以后试验了几轮,都是符合预期的。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
我们通过以下方式对多蛇共斗的需求进行建模:
- 碰撞系统建模:建立双重障碍检测机制。
 
- 即时障碍集合:包含其他蛇当前身体坐标(除尾部),确保移动时不与现有蛇身碰撞
 - 预测障碍集合:将其他蛇头周围四邻域坐标视为潜在障碍,预防下一步可能的头撞头情况
采用哈希集合(键为100*x+y的编码值)实现O(1)时间复杂度的碰撞检测 
- 策略建模:基于贪心算法。
 
- 方向排除:通过计算当前移动方向的反方向,避免转向
 - 可行性筛选:检查四方向移动后的边界合法性及障碍物冲突
 - 目标驱动:对有效方向计算距离,选择离最近食物的方向作为最优解。
 
- 安全优先级设计:采用两级决策机制。
 
- 优先考虑预测障碍集合下的安全路径(minDirs)
 - 若不存在绝对安全路径,则在即时障碍集合下选择最优路径(maxDirs)
 
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
避免死亡:在T3中,死亡有几种可能的形式,即撞墙或者撞到其他蛇的蛇身。为了避免撞到墙,需要对蛇的下一个位置进行判断,具体来说,就是避免蛇头的下一个位置不会“越界”。为了避免碰到其他蛇的蛇身,需要将当前蛇的位置保存起来,进行方向判断的时候排除这些位置。需要注意的是,当蛇移动的时候,蛇尾是一定保持在原来的位置的,所以可以不用考虑蛇尾。而蛇的蛇头可能处在不同的位置,需要将蛇头的可能位置考虑进来。
吃到更多果子:在我们的策略中,首要目标是避免死亡,其次是吃到更多果子。为了吃到更多果子,蛇每次选择与自己最近的果子然后进行移动,如果可能会碰到其他的蛇(包括蛇头),那么蛇就不去吃这个果子。
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
可以通过三个核心维度定量评估程序的有效性:
一、生存能力验证
通过在100场标准对局中统计存活数据,分析平均存活回合数和最终存活率,以评估策略的基础避障能力和长期生存策略的有效性。例如,如果程序在四蛇混战中平均存活超过15回合,或在30%的对局中成为最后幸存者,则说明其生存逻辑有效。
二、觅食效率衡量
计算“得分/存活回合”比值来量化觅食效率。以检测目标追踪算法的灵敏度。
三、对抗压力测试
设计多种高风险场景,如两蛇对冲和多蛇围堵等,记录程序在碰撞前的规避决策正确率。当程序在80%以上的测试场景中做出安全响应时,证明其对抗策略有效。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 | 
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 | 
| DEVELOPMENT | 开发 | 165 | 161 | 
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 15 | 13 | 
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 8 | 
| - Coding Standard | - 代码规范 | 5 | 5 | 
| - Design | - 具体设计(确定怎么实现) | 20 | 15 | 
| - Coding | - 具体编码 | 90 | 80 | 
| - Code Review | - 代码复审 | 15 | 20 | 
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 10 | 
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 10 | 
| REPORTING | 报告 | 35 | 25 | 
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 15 | 10 | 
| - Size Measurement | - 计算工作量 | 10 | 10 | 
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 5 | 
| TOTAL | 合计 | 205 | 191 | 
→ 📖 Q3.7(I) 请写下本部分的心得体会。
第三题的关键还是思考出一个可行的算法来,对于实现来说反而简单一点。第三题可以实际看到贪吃蛇的运动,对于我来说有了很大的满足感。第一题和第二题在debug的时候还是自己手画格子和蛇,简直太艰苦了。感觉有了图形的辅助,也更加容易看到问题在哪里了。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
在结对编程的过程中,最重要的是及时的沟通。在刚开始的时候,我们还不是特别放得开,有的事情没有及时说明白。我们在结对的时候,驾驶员和领航员的角色实际上应该及时交换,但是我们往往是一个人已经很累的时候才交换。这也是需要提升的地方。而且我们两个人各自有各自擅长的方面,但是没有充分发挥各自的优势。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
- 思考问题比较全面
 - 沟通及时
 - 认真负责
 
缺点:
- 查阅资料的能力可以再提升
 
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:能够及时发现和修复潜在问题,减少代码中的错误,提高代码质量。两人合作可以相互学习,分享各自的经验。能够增强我们的沟通能力。相比一个人来说,两个人的角色可以互换,可以避免单人长时间编码导致的疲劳和效率下降。
缺点:比较考验两个人的沟通能力,而且不够灵活,必须要两个人都能够凑出时间才行。
结对编程是一种强调协作的开发模式,尽管我们是刚刚接触这个名词,但是以前也有过类似的经历(两个人在一台机器上面写代码)。结对编程不仅仅是简单的分工,而是通过角色的动态切换实现高效协作。在方法得当的情况下,结对编程是能够起到1+1>2的效果的。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
https://github.com/dongfengwuyishi/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号