[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) 请写下本部分的心得体会。
在完成本部分的任务时,看完任务的描述时,发现其实在身长为4的情况下,蛇根本不会撞到自己(除非扭头自杀),也没有路障阻碍蛇去吃果子,整体感觉是一个很简单的贪心实现:蛇只要每次选取能够缩短自己与果子距离的方向就行。主要的难点集中在对AssemblyScript的不熟悉,花了一定的时间在学习和熟悉AssemblyScript上,在编写代码的时候也会磕磕绊绊写出语法错误。在这种情况下,我们没有选择一个扩展性比较高的算法和结构,之后的任务中应该会进行重构。
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) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
设计思想有模块化设计,将各个功能封装成各个模块。比如在设计贪吃蛇的寻路算法时,将该算法封装成一个函数,这样子在后续需要按需更改寻路逻辑时可以方便切换。这样子把贪吃蛇的主决策函数分为初始化障碍物模块、优选寻路算法模块和其他备选的寻路算法模块。
设计冗余可以是预留扩展点,比如对于在后续任务中可能变化的棋盘大小预留一个变量,在现在先设为8。还有设计障碍物数组,统一记录蛇身和障碍这些不可移动的位置。
头脑风暴环节
**→ 📖 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) 请写下本部分的心得体会。
本次任务对于在T1里简单实现的我们有点压力。原本T1中只有一个函数,而在本次我们创建了多个函数模块,T1中的几处主要代码段都遭到了废弃。
这次任务中的障碍引入带来的问题的程度是我们始料未及的,原本只是设想通过简单的BFS去搜索果子,若暂时搜索不到就找一个暂时安全的方向前进。但是发现存在“陷阱”这种特殊情况后,就不得不设计避免进入“陷阱”的函数。
为了一个特殊情况,我们花费了超出预想的时间。不禁感慨准确预估耗时也是一项技术活......
控制蛇的运动(ヘビウォーク)还真是件麻烦事(ヘビーワーク)
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) 请写下本部分的心得体会。
好玩。
为什么这个任务的标题用了5个感叹号,明明结对只有2人!!😡
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
花的时间有点长,每次任务之间代码复用度低。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
-
代码编写能力强、速度快
-
善于交流讨论
-
查找资料能力强
缺点:
刚入坑明日方舟就用AI代肝
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
结对编程的优点是能进行实时的代码审查,两人共同关注实现细节,如边界条件、等号方向等,降低测试阶段的返工成本,两人交流也避免了思维盲区。
缺点是对两人精力消耗有点大,两人需要随时沟通理解,若双方对代码理解不一致,就可能陷入冗长的讨论。
结对编程并非简单的“一人写代码,一人看”,而是实时同步的设计讨论与实现。领航员需主动思考代码设计等问题,而非仅关注语法错误,而驾驶员也需及时理解意图,兼顾稳定编写。
代码实现提交
→ 📖 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号