[P] 结对项目:影蛇舞
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 首页 - 2025年春季软件工程(罗杰、任健) - 北京航空航天大学 - 班级博客 - 博客园 |
| 这个作业的要求在哪里 | [P] 结对项目:影蛇舞 |
| 我在这个课程的目标是 | 在实践中掌握软件工程的基本方法,提高开发能力 |
| 这个作业在哪个具体方面帮助我实现目标 | 了解结对开发,提高合作能力 |
结对项目:博客问题清单
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
3月26日14点
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
II. 仅限于听说过相关名词。听说过Wasm,知道可以通过C/Rust等高级语言编译成Wasm。
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
3月26日14点20分
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
3月26日14点20分
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
- 查阅贪吃蛇游戏的策略算法,将贪吃蛇问题建模成一个图论里的两点间最短路径问题
- 为了方便解决后续引入障碍物的情况,我们使用了A*算法求解这个问题
- 在设计测试样例时,我们使用了random库来随机生成数据,但是在构建为wasm时会出现问题,排查后发现是使用了random,因此我们写了一个简单的random工具类
- 对蛇身碰撞理解有问题,在通过仓库提供的测试用例时,有两个用例我们的代码会找不到路径返回空。在打包成wasm后报错信息为访问错误地访问了某块内存,非常难调试,最后用rust跑样例才发现了问题。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
测试方案参考了仓库中的js代码greedy_snake_fn_checker ,通过模拟一整局游戏来进行测试,如果最后能安全吃到果子则视为通过。
在测试样例设计上,主要考虑蛇会不会发生碰撞导致死亡,因此设计了如下场景:
- 蛇初始位置在棋盘边缘,果子位置在棋盘角落
- 蛇初始位置在棋盘边缘,果子在蛇身边
- 蛇初始卷成一个田字形,果子的位置离蛇较远
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
-
提高代码质量:通过对每个功能单元进行测试,能及时发现并修复bug,减少后期问题。
-
加快开发效率:早期发现问题避免后期调试代价,提升整体开发效率。
-
方便在CI/CD流程中快速验证每次提交的正确性。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
3月26日18点50分
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | 120 | 130 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 15 | 20 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 20 | 15 |
| - Coding | - 具体编码 | 45 | 50 |
| - Code Review | - 代码复审 | 5 | 5 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 15 | 20 |
| REPORTING | 报告 | 20 | 15 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 5 |
| TOTAL | 合计 | 145 | 150 |
→ 📖 Q1.6(I) 请写下本部分的心得体会。
-
第一部分不难,借这个机会我了解了网络汇编的原理,掌握了基本的rust语法以及构建WebAssembly项目的过程
-
在结对编程的过程中,我提高了沟通交流能力,能够及时和队友沟通想法、指出代码中的问题。我没有负责直接写代码,开始时经常出现两个人没有理解对方思路的情况,在编码前一定要先进行设计多沟通想法
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
3月26日20点
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
首先我们在第一题的基础上分析引入障碍物后寻路算法需要做出哪些改变,讨论后发现只需要修改碰撞检测代码,其他地方不需要更改,然后在T1代码的基础上对接口进行调整,专门处理输入数据,尽可能复用代码。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
相比于T1,T2需要考虑障碍物对路径规划的影响。由于T1采用的算法可以支持有障碍物的场景,因此我们只需要在碰撞检测代码colision_check加入一个参数obstacles表示障碍物,在实现时新增判断下一个移动方向会不会与障碍物重合即可。这样就完成了算法部分。
接下来是需要适配新的接口,蛇位置的传入方式发生了变化,我们希望可以尽可能减少更改,因此借鉴了设计模式中的适配器模式思想,新增一个函数process_input用来处理输入,转化成T1的形式。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
设计思想
-
模块化设计:在设计时,将寻路算法、输入输出处理都单独封装成模块,这样可以灵活地控制功能变更时进行局部修改。
-
适配器模式:T2和T1需要提供的接口在输入方式上出现了不同,使用适配器模式可以很好地适应接口输入输出的变更。
-
接口与实现分离:在本题中需要根据不同情况设计不同的寻路算法,如果将寻路定义为一个抽象接口,根据要求实现不同算法,那么可以较少侵入地修改主要代码,简化流程。
冗余设计
-
预留参数和拓展点:在T1我们就预留了可能存在有障碍物的情况,可以灵活的扩展。
-
配置解耦:将可变内容(如地图尺寸、障碍物数据)提取为配置参数,避免硬编码,便于灵活调整。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
枚举每个果子,作为第一次行动的目标,吃到第一颗果子后,枚举剩下的四个果子作为第二次行动的目标,重复上述过程,直到吃到果子。
过程中可能会出现有一颗果子位于死路中,也就是吃到这颗果子后就无法行动,由于必然存在一条可以吃完所有果子的路线,这样的果子至多存在一个,我们只需要把这样的果子放在最后一个吃就可以了。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
3月30日14点10分
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 5 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | 115 | 95 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 5 | 5 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 10 | 5 |
| - Coding | - 具体编码 | 30 | 25 |
| - Code Review | - 代码复审 | 10 | 5 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 45 | 40 |
| REPORTING | 报告 | 15 | 15 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 135 | 115 |
→ 📖 Q2.7(I) 请写下本部分的心得体会。
由于第一题在设计算法时已经提前考虑了第二题新增的障碍物,因此我们的实现很顺利。同时,由于使用了适配器模式来调整接口,进行了合理的模块封装,我们基本完全复用了T1的代码,只进行了部分新增,这让我感受到设计的重要性。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
3月30日14点30分
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
首先我们在网上查找资料,考虑使用机器学习解决问题。之后搜索了在Rust上运行机器学习模型的资料,认为工作量太大无法顺利完成,决定采用朴素的算法来解决,每次优先保证不装到对方和墙壁,在此基础上贪心地吃最近的果子,这样可以高度复用T2代码,无需进行太多修改。
在初步设计完策略完成代码后进行对战,发现我们的蛇存活率不高,同时在竞争果子上也表现不佳。在分析对局后,我们重新设计了存活策略和得分策略,并编写了测试脚本,相比最初有了很大提升。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
把其他蛇的蛇身去除最后一节加上蛇头可能的三个移动方向都视作障碍物处理,优先保证蛇不会相撞。如果发现无法移动,则不考虑对方蛇头的可能移动方向。最终目标是在满足以上约束条件下寻找最快吃到果子的一条路径,据此得到下一步移动方向。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
存活策略:
- 在决策时考虑两个因素:对方蛇的位置和自身到墙角的距离。
- 当蛇头到达墙角时,如果对方蛇在附近可能会无法找到存活路径死亡,在决策时需要避免过于靠近墙角
得分策略:
- 由于无法预测对方蛇的移动方向,使用贪心策略规划移动路线,并没有全局考虑吃到最多果子,每次只考虑吃到最近的果子
- 在实现上,在满足存活条件情况下,分别计算出场上吃到每个果子的最短路径,选择最短的一条作为下次移动方向
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
我们和其他六组交换了最后的pkg进行了对局。通过脚本进行大量对局,统计结果的获胜次数和胜率作为有效性的依据。
同时,由于我们的策略在最初存在蛇容易在墙角死亡的问题,因此我们专门准备了苹果生成在墙角的情况进行测试,以检测新的策略是否可以提高存活率。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
时间:4月3日11点
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 10 | 10 |
| - Estimate | - 估计这个任务需要多少时间 | 10 | 10 |
| DEVELOPMENT | 开发 | 305 | 350 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 15 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | 20 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 40 | 60 |
| - Coding | - 具体编码 | 120 | 140 |
| - Code Review | - 代码复审 | 20 | 30 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 20 | 20 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 60 | 60 |
| REPORTING | 报告 | 15 | 15 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 5 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 330 | 375 |
→ 📖 Q3.7(I) 请写下本部分的心得体会。
T3需要考虑很多因素,这里我初步感受到了结对编程的优点,我们可以及时沟通策略,对别人的想法提出质疑,考虑问题更加全面,不会一个人思考陷入死胡同。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。
→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
-
在设计寻路算法时没必要担心超时,实际上不需要使用实现起来更复杂的A*算法,只需要用BFS
-
一开始就编写自动打包和测试的脚本,提高开发效率
-
在讨论时要多做记录,减少两人的沟通成本,特别是在第三题设计策略时,讨论了很多可行方案,但是没有记录下来,最后由一个人编码实现时并不顺畅
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
-
编程能力强,熟悉Rust语法,开发效率高
-
行动力强,干活很积极
-
思维活跃,可以想到好的策略
缺点:
- debug速度不快,代码中会出现一些小bug
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:两人共同审查,能及时发现问题,减少bug,能明显提高代码质量;出现问题时可以马上讨论、共同思考,避免独自卡壳;在合作的过程中可以学到对方的优点,请教技术问题
缺点:相比于两个人并行开发,结对编程效率明显低了很多,尤其是在任务简单或双方水平差距较大时严重影响开发效率。另一方面,结对编程需要良好的沟通和协作,否则容易因为意见不合影响效率,长时间结对编程可能会带来人际关系压力。
我认为结对编程是一个非常适合学习和解决复杂问题的方式。在开发过程中,有人陪你一起思考、一起 debug,这种实时反馈的机制可以提高的信心减少压力,尤其是在刚开始接触一个新项目、或者面对逻辑复杂的问题时。
浙公网安备 33010602011771号