[P] 结对项目:影蛇舞
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 2025年春季软件工程(罗杰、任健) |
| 这个作业的要求在哪里 | [P] 结对项目:影蛇舞 |
| 我在这个课程的目标是 | 学习软件工程知识和软件开发中的通用方法,提升实际项目开发的能力,参与从需求分析、设计、编码、测试到维护的完整软件开发流程,并完成一个完整、实用、好用的软件 |
| 这个作业在哪个具体方面帮助我实现目标 | 学习结对编程的思想,实践结对编程的方法,锻炼自己在陌生的技术背景下进行极限编程的能力 |
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
3月26日 14:00
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
I. 未听说过 Wasm
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
3月26日 14:30
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
3月26日 14:35
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 315 | 240 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 120 | 60 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 60 | 40 |
| - Coding | - 具体编码 | 30 | 60 |
| - Code Review | - 代码复审 | 15 | 15 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 20 | 20 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 20 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 5 |
| TOTAL | 合计 | 315 | 240 |
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
我们首先通读了一遍指导书,再商量过后,决定使用Rust语言进行相关开发。在开发过程中,我们查阅了Rust的官方文档进行学习。遇到的主要问题为Rust语法问题,例如HashSet和VecDeque的用法,我们通过查阅官方文档、使用搜索引擎等方式来解决该问题。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
从函数的参数出发,考虑了各种测试用例。函数的参数有两个:蛇的位置、唯一一个果子的位置。首先是一般的常规测试用例,可以随机生成;然后测试了边界情况,例如果子的位置在四个角,蛇头在四个角且身体盘旋为四个紧挨着的方格的情况,主要是测试蛇是否会出现撞墙和咬自己的情况。蛇是否会正确地向着果子前进可以由一般的测试用例给出。
测试样例涵盖的情况种数越多,越是有效的;若测试用例能测出代码正确性上的Bug(咬到自己、撞墙、一定回合内不吃到果子),也可以说明测试用例是有效的。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
可以测试程序单个模块运行的正确性,比整体测试更有针对性,且更方便和迅速
使软件开发各模块可以独立地测试其正确性,实现边开发边测试,而不是非要等到全部模块都写完后再一起测试
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
3月26日18:40
→ 📖 Q1.6(I) 请写下本部分的心得体会。
软件开发前,分析清楚需求很重要,尤其是对软件关键概念的理解(例如碰撞、位置移动),以免因理解不清而给自己增加开发难度或进行错误开发。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
3月30日 14:00
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 55 | 50 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 0 | 0 |
| - Coding Standard | - 代码规范 | 0 | 0 |
| - Design | - 具体设计(确定怎么实现) | 0 | 0 |
| - Coding | - 具体编码 | 10 | 10 |
| - Code Review | - 代码复审 | 0 | 0 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 0 | 0 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 15 | 20 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 5 |
| TOTAL | 合计 | 55 | 50 |
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
我们复用了T1中的代码和思路,由于新增代码较少,并未遇到任何问题。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
我们在进行T1前已经通读了整篇指导书,决定将T1和T2一起实现,在进行T1的编码设计时,已经考虑到了T2的障碍物,留下了扩展空间。即在实现T1时,将蛇的第二节身体视为“障碍物”加入障碍物数组,在T2时,只需将实际障碍物的坐标再加入障碍物数组即可。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
考虑到 T1 事实上就是 T2 中障碍物个数为 0 时的特殊情况,我们第一问和第二问都采用了 BFS 做,区别仅在于 BFS 时障碍物数组的内容(蛇的第二节身体 / 蛇的第二节身体 + 12个障碍物)。因此, BFS 代码其实就是 T1 和 T2 的公共部分,可以提取公共部分,避免重复造轮子,来提高代码的可复用性。设计代码时,要考虑可能的扩展地方,预留扩展空间,来提高代码适应需求变更的能力。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
由于每个果子均可达,且至少存在一条可以成功吃掉所有果子的路线,所以每两个果子之间都存在一条可行路线。于是,我们可以先使用BFS找到前往当前最近果子的路线,然后再以这个果子为起点,重新调用BFS,找到前往下一个果子的路线。以此类推,我们可以找到所有果子,将每一段路线相加就得到了一条可以吃完所有果子的行动路径。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
3月30日14:50
→ 📖 Q2.7(I) 请写下本部分的心得体会。
编写代码时,要在需求分析阶段明确好所有的需求,并考虑好可扩展空间,而不是只考虑一部分需求或只顾及当下。这样做写出来的代码可更好地适应需求的变更,为开发带来许多方便。就如本题中,需求分析阶段先明确三个阶段的任务,再设计实现方案,因此选择了 T1 和 T2 使用同一套思路和代码实现,变得十分方便,且不容易产生新的Bug。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
3月30日 14:50
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 265 | 200 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 0 | 0 |
| - Coding Standard | - 代码规范 | 0 | 0 |
| - Design | - 具体设计(确定怎么实现) | 60 | 60 |
| - Coding | - 具体编码 | 60 | 45 |
| - Code Review | - 代码复审 | 60 | 40 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 30 | 20 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 10 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 5 |
| TOTAL | 合计 | 265 | 200 |
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
我们这一题互换了“导航员”和“驾驶员”的角色。在开发过程中,遇到的主要问题是思路与代码出现不一致,我们通过重新整理思路、设计代码来解决。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
由于引入多蛇互斗,各蛇的位置都会在场景中不断变化,因此,我们设定:
除本蛇外,场上其它蛇的第1、2、3节身体为本回合决策中的 “硬障碍”,即下一回合中,一定不能走到否则必死无疑的位置(下一回合中,其它蛇的第2、3、4节身体分别移动到这3个位置;本回合中其它蛇的第4节身体不会再有后面的身体移动到它的位置)。场地边界当然也为硬障碍。
本蛇蛇头周围的、不是硬障碍的、同时也在其它某蛇头周围的位置为本回合决策中的 “软障碍”,即 (本蛇头可以移动到 && 其它蛇头可以移动到 && !不在硬障碍中)的位置。硬障碍判定优先级高于软障碍。这些位置是下一回合中,若走到可能死亡的位置。显然,由于这样的位置要在本蛇头周围,因此一回合中,这样的位置不超过三个。
考虑软障碍是为了尽量避免蛇头相撞,同时由于软障碍是一种“可能”(其它蛇可能走到此位置),因此不必考虑得过于精确,只考虑本蛇头周围的位置即可,这样已经保证了本回合决策中预防头头相撞。若直接将所有其它蛇头可达的位置视为软障碍,则一个蛇头就要产生3个软障碍,数量过多,很可能导致许多果子被判定为“不可达”,而对防止本回合决策中蛇头相撞没有任何提升。
这样考虑下来,本回合中对于8 * 8的棋盘,障碍物数量将控制在12个左右(3条其它蛇产生的9个硬障碍 + 本头周围不超过3个软障碍),与 T2 中的规模类似,同时尽最大可能避免了自己撞死,预防了头头相撞。
本回合决策中的核心动作就是:硬障碍 + 软障碍 = 障碍物,然后避开障碍物使用 BFS 找到一个路径最近的果子,向此果子移动一步。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
建模与核心动作已在上问介绍。为了进一步避免死亡和吃到更多果子,我们还有如下策略:
当 BFS 认为没有任何一个果子可达时,很可能出现了蛇头被围得比较严重的情况,此时检查周围情况,按照 无障碍 > 软障碍 > 硬障碍 的标准避难:
若周围还存在“既不是软障碍也不是硬障碍”的方向,随机朝这样的方向移动一步。若不存在:
若周围还存在“是软障碍”的方向,随机朝这样的方向移动一步。这一步决策存在赌的成分,有可能导致头头相撞而死亡,这取决于自己和周围那条蛇的决策。若不存在:
说明周围的方向已全部都是硬障碍,很不幸本局走到了死胡同,神仙难救,随便返回一个方向等待来生。
由于果子的密度较大,因此我们认为这个游戏活得越久,越有利,各种硬软障碍,尤其是躲避软障碍的考虑都是为了优先保证生存,而不是抢果子,保证了生存就有很大可能吃到更多果子;同时,依然由于果子的密度较大,向最近的果子移动也有利于尽快吃到更多果子。
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
我们使用自己的蛇反复进行1v1、4蛇大乱斗两种模式的测试,在测试过程中,利用可视化界面观察决策结果、生存回合数和最终得分。
- 通过观察每一步的决策结果,我们可以判断程序的正确性,即我们的蛇是否按照我们的策略来行动,这是该程序模块有效的前提条件;
- 生存回合数均值:我们统计了10次测试的20/40条蛇的平均值。
- 1v1:数值波动范围较大,从十几回合到50回合均可能出现,生存回合数均值为43.8。此外,符合预期的是,当一条蛇死亡后,另一条蛇一定会存活至最后,绝大多数情况下至少有一条蛇活到最后。
- 4蛇大乱斗:数值波动范围更大,从几回合到100回合均可能出现,生存回合数均值为71.8,死亡率比1v1要高很多。
- 每回合得分均值:我们统计了10次测试的20/40条蛇的平均最终得分,并用该值除以生存回合数均值。
- 1v1:最终得分均值为:23.75。考虑到平均存活回合数43.8,我们可以认为每回合近似得到23.75/43.8=0.54分。考虑棋盘上的果实密度,我们认为这个结果可以接受。
- 4蛇大乱斗:最终得分均值为:32.15。每回合近似得到32.15/71.8=0.45分,我们认为可以接受。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
3月30日 18:09
→ 📖 Q3.7(I) 请写下本部分的心得体会。
算法设计的时候,有时会“鱼和熊掌,不可兼得”,此时要仔细权衡利弊,抓住问题的主要矛盾,优先考虑对结果影响更大的因素,设计更好的策略。例如 T3 中,在一回合中,绝大多数情况下,保住生存要比向果子前进一步重要得多,也比蛇头争食重要得多。由于果子的密度较大,保下生存多走几步就可能吃到多得多的果子,比冒一步险划算得多。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
对于本次结对编程的体验,我们总体来看十分满意。可能的问题是:
在编程过程中,由于以往的编程习惯,“驾驶员”并没有完全集中注意力在完成当前任务的“战术”方面,以将安全问题全权交付给“导航员”,这一定程度上减少了“导航员”对工作的贡献。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
善于合作,编程能力强,善于沟通,是不可多得的好合作伙伴
在结对编程开始前的准备工作不够充分,如安装工具链
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
结对编程的优点:两个人互相审查代码,更好地保障代码质量;编程过程中不断互换“驾驶员”与“领航员”的角色,有利于防止因一个人长时间编程而导致疲劳、低效和错误,有利于在短时间内快速推进项目。
结对编程的缺点:在编程过程中增加了一些沟通的成本,例如因观点不同或理解错误而花费额外的沟通时间,但影响不大。
我认为结对编程是促进更高质量地完成项目、提升自己能力的有效手段。与人交流往往能比闭门造车得到更多的思路、产生更好的实现方式,而两个人在编程过程中的互相审视、互相学习,也有利于提升自己的能力,包括但不限于编程能力、代码规范、沟通能力等,结对编程的过程给我带来很多收获。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
https://github.com/lyx-Rainbow/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号