[P] 结对项目:影蛇舞
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 北京航空航天大学2025年春季软件工程 |
| 这个作业的要求在哪里 | [P] 结对项目:影蛇舞 |
| 我在这个课程的目标是 | 系统学习软件工程的基本原理和方法,掌握软件开发的基本流程,能够在通过团队协作完成一个具备实际应用价值的软件。 |
| 这个作业在哪个具体方面帮助我实现目标 | 分析现有的优质软件,学习编写软件的技巧与原则 |
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025.3.22 14:50
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
没有听说过
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025.3.22 15:45
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025.3.22 16:00
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 10 | 11 |
| - Estimate | - 估计这个任务需要多少时间 | 10 | 11 |
| DEVELOPMENT | 开发 | 85 | 75 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 0 |
| - Coding Standard | - 代码规范 | 5 | 2 |
| - Design | - 具体设计(确定怎么实现) | 5 | 3 |
| - Coding | - 具体编码 | 30 | 30 |
| - Code Review | - 代码复审 | 5 | 10 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 10 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 15 |
| REPORTING | 报告 | 20 | 20 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 7 |
| - Size Measurement | - 计算工作量 | 5 | 3 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 10 |
| TOTAL | 合计 | 115 | 106 |
完成编程任务期间,依次做了什么:
-
浏览了包括guide在内的有关资料
-
设计实现算法
-
测试
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
本次的任务需求较为简单,我们通过简单编写了一个测试例生成代码,借用了submit-test中的代码,最后利用其生成的测试例和我们针对蛇在边缘情况下设计的测试例进行了测试。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
单元测试可以针对某个函数进行检测,验证函数正确性,减少函数中的低级错误。测试失败时可以快速定位到某个函数。
在目前T1的实现中,我们结对的实现较为简单,只有一个函数,所以单元测试就是对整个函数输出的检测。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
见 Q1.2(P)
→ 📖 Q1.6(I) 请写下本部分的心得体会。
因为是和舍友组队,在进入结对编程的过程中没有遇到太多的阻碍,交流的效率也很高,我们在创建仓库后迅速上手编程,T1的内容主要由我编写,也就是说我是驾驶员,搭档是副驾驶)
在一开始我们仔细阅读了所有三道题目和问题清单(但事实证明后面的题阅读不够仔细),希望通过迭代的方式从T1完成到T3。首先我们试图在网上寻找相关的资料,也想过用神经网络训练蛇的模型,但苦于相关实践经验不足,同时网络训练出的模型是一个黑箱,不能够实际了解蛇做出决策的具体策略,所以最后还是选择了自己构思策略。但在编写的过程中,发现T1的蛇采用贪心即可,一些特殊的策略我们想等到T2T3再去完成。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025.3.24 18:21
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 10 | 11 |
| - Estimate | - 估计这个任务需要多少时间 | 10 | 11 |
| DEVELOPMENT | 开发 | 125 | 155 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 0 |
| - Coding Standard | - 代码规范 | 0 | 0 |
| - Design | - 具体设计(确定怎么实现) | 10 | 20 |
| - Coding | - 具体编码 | 60 | 88 |
| - Code Review | - 代码复审 | 5 | 7 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 20 | 15 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 15 |
| REPORTING | 报告 | 20 | 23 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 7 |
| - Size Measurement | - 计算工作量 | 5 | 3 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 13 |
| TOTAL | 合计 | 155 | 189 |
完成编程任务期间,依次做了什么:
- 针对新增的障碍,修改障碍物数组的更新
- 由于障碍的排列,T1的贪心算法失效,编写了BFS作为新的寻路算法
- 进行BFS的单元测试
- 设计出一个测试例:
- 蛇被卡在一格宽,暂时无法转向的路径中,此时蛇会认为自己身后的果子是吃不到的
- 修改障碍物数组更新,把自己的身体不视作障碍,而是维护一个禁止方向来防止蛇扭头
- 修改原本的BFS寻路函数,编写基于BFS判断果子实际是否可达的函数
- 当BFS寻路函数返回-1,但果子实际可达的情况下,设计一个备选寻路算法:
- 我们先设计了一个基于T1的贪心实现,暂时移动到一个可行方向的算法
- 测试发现该算法会导致蛇进入“陷阱”:一个格子有三个方向是障碍,蛇进入后就只能撞向障碍
![]()
- 设计了一个BFS算法,让蛇暂时前往一个最近的无障碍2x2格子区
- 再次设计测试,完成任务
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
沿用了原本的Point类型,和barriers障碍物数组。
大修了寻路有关的算法。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
常见的思想有SOLID原则,针对本项目,我觉得单一职责功能比较关键,我们的使用了多次BFS,导致变更时影响的范围较大,对我们的编写造成了一定的影响。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
由于存在多个果子,吃果子的顺序就要加入考虑了,我们不希望看到这种情况:场上存在一个吃了之后就只能撞上障碍的果子,而蛇上来就去吃这个果子。
我们沿用我们本次实现中寻找无障碍2x2区域的思路,将果子分为三类:
- 处于一个无障碍2x2区域的果子
- 以及连通到两个不同的处于无障碍2x2区域的格子的果子
- 不处于无障碍2x2区域,且只能连通到一个无障碍2x2区域的果子
上述最后一类果子必须在最后吃,如果保证了至少存在一条成功吃掉所有果子的路,那么这些果子应该都集中在一个没有回头路的单行道上,蛇吃掉它们的顺序也是固定的
而前两类果子必须先于最后一类果子被吃掉(除非蛇出生在这条单行道上),但其内部吃的顺序无所谓,也就是说在这种思路下设计的蛇的行动路径不一定是最短的。
具体实现时,我们对每个果子维护一个bool值,表示它是前两类的还是最后一类的果子,对不处于无障碍2x2区域每个果子,从其位置出发进行一次BFS搜索,搜到一个处于无障碍2x2的格子时,不将其加入队列,若搜到两次处于无障碍2x2的格子,认为它是第二类的果子,否则是第三类;蛇吃果子的策略改为,除非剩余果子都是第三类果子,否则只吃前两类果子。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.3.24 21:11 见Q2.2(P)
→ 📖 Q2.7(I) 请写下本部分的心得体会。
T2部分的内容主要由我的搭档编写,我负责Review,真是辛苦他了。
印象非常深刻的是对策略设计的预估时间不够,也就是说把项目想简单了,通过人工设计陷阱样例和蛇蛇对抗,我们针对蛇蛇出现的问题,修改了先前使用的策略。这个过程让我们感受到了结对编程的独特魅力,即头脑风暴并热情高昂地继续编码,这在我独自编程时往往是少见的。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025.3.29 20:13
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | 275 | 350 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 30 | 30 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 15 | 10 |
| - Coding Standard | - 代码规范 | 10 | 10 |
| - Design | - 具体设计(确定怎么实现) | 90 | 110 |
| - Coding | - 具体编码 | 60 | 90 |
| - Code Review | - 代码复审 | 30 | 30 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 10 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 40 |
| REPORTING | 报告 | 60 | 65 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 30 | 40 |
| - Size Measurement | - 计算工作量 | 10 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 20 |
| TOTAL | 合计 | 330 | 420 |
完成编程任务期间,依次做了什么:
- 沿用T2代码,针对本次任务进行一些修改,包括函数传参和障碍物数组的更改
- 设计实现不同蛇看到的障碍物数组和蛇果距离数组
- 实现蛇dijkstra寻路
- 29号的22:18提交一次
- 30号的15:40继续
- 设计实现处决函数和预防处决函数
- 单元测试
- 图形化测试,进行了自己与自己镜像(减少了某些模块)的对战
- 修改bug
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
当前环境是一个多条蛇博弈的局面。为了提高胜率,我们要考虑的有:
- 平均每回合得分多
- 避免死亡和不合法方向输出
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
为了更好的说明,这里定义几个名词:
-
?环
- 外环:棋盘最外圈
- 二环:从外向内数,第二圈
- 三环同理
考虑到果子刷新是一个均等分布,所以占据格子数较多的外环和二环在概率上来说较为容易出现果子。尤其是5x5棋盘的情况下,外环直接占据了16格。但是外环由于其紧贴边界,会导致蛇的行动受限,还有可能被人夹死,所以风险是最高的。而二环被夹死的概率较低,且能活动到外环和三环,行动范围大,吃到果子的概率高,所以推荐二环。
-
障碍类型,站在某一条蛇的视角下的描述
- 实障碍,指边界和其它蛇的蛇头、蛇身第1节、第2节
- 虚障碍,另一条蛇可能行动的方向上的格子,或者周围有三个蛇头或蛇身的格子,即“陷阱”
-
激进/保守,蛇的策略模式
- 激进模式下,蛇会敢于进入虚障碍,也敢于去竞争和别人距离一样的果子
- 保守模式下,蛇不会主动进入虚障碍,也不去竞争和别人距离一样的果子
-
处决
(焚蛇打taHebi)必要条件:
- 当我们的蛇处于二环
- 我们的蛇外侧存在一条蛇,这条蛇的蛇头被我们的蛇头/身和边界卡住,只能平行于边界方向移动
我们的蛇可以选择一直卡住这条蛇,直到其死于边界角落
或者,我们的蛇若领先于外侧蛇两格时,可以拐向外环,主动卡死对方
-
预防处决
根据必要条件进行预防:
-
若不处于外环,不需要预防
-
处于外环时,有三种情况:
-
蛇头在角落
-
蛇头和蛇身第一节平行于边界
-
蛇头和蛇身垂直于边界
-
-
对于在角落,可行动方向只有一个,没得选
-
对于平行情况,可行动方向有回二环和待在外环,需要检测附近有没有蛇来确定
-
对于垂直情况,可行动方向有两个,左拐还是右拐,需要检测两侧有没有蛇,选其中之一
-
我们蛇蛇的决策流程如下:
根据场上蛇的数量,决定当前是否是激进模式
- 蛇数量<= 1就改为激进模式,反之保守
- 当进入1v1时,若对方也是激进,那么我们不亏;若对方是保守,那么我们明显有利
- 进入4snakes模式,优先保守周旋
查看是否可以处决另一条蛇蛇,杀另一条蛇总是有利于我们的
查看是否在外环,是否要预防被处决
-
陷入没得选的情况:
优先回二环
-
需要预防的情况:
直接选择预防函数建议的方向
-
不需要预防的情况:
进入后面的决策函数
BFS计算对于i蛇到j果子的距离,比较我们蛇与其它蛇到果子的距离:
- 若存在只离我们蛇最近的果子,选择它
- 不满足上一条,但存在一个果子离我们和另外某条蛇的距离都是最近,且我们是激进的,选择它
- 不满足上一条,回二环
对于选择了果子的情况,用dijkstra计算最短路径
- 为二环设置最小权重,偏好二环
- 外环权重最大
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
存活时间,在保守模式下,蛇蛇可以轻易存活超过1000turn
结束时的得分数第一的概率,对于4snakes模式,胜率能大于1/4;1v1模式则是大于1/2。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.3.29 21:39 见Q3.2(P)
→ 📖 Q3.7(I) 请写下本部分的心得体会。
T3的内容因为内容较多,由我们两人交换着写。
虽然不想卷性能分,但是因为蛇蛇大乱斗中不断发现问题,所以思考+编写策略花的时间并不少,感觉结对编程更像是两个人一起写一道大模拟算法题)总的来说,结对编程是非常愉快的。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
花的时间有点长,每次任务之间代码复用度低。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
-
思考非常活跃,能想出非常独特的新思路。
-
注释和文档编写非常的生动,
可爱的蛇蛇 -
推进结对编程非常主动,debug大王
缺点:
- 可恶,哈吉助一定要让我写缺点么,那只能说函数的命名有点天马行空比如
ponderingBFS
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
结对编程是一个Coding和Review共同推进的过程,过程中的确多次指出和被指出了代码编写的错误,同时debug能力也得到了成倍的提升。结对编程的模式可以让两个人都专注于代码,减小了外界干扰。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
https://github.com/w1cker/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号