[P] 结对项目:影蛇舞
结对项目:影蛇舞
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/buaa/BUAA_SE_2025_LR |
| 这个作业的要求在哪里 | https://edu.cnblogs.com/campus/buaa/BUAA_SE_2025_LR/homework/13410https://edu.cnblogs.com/campus/buaa/BUAA_SE_2025_LR/homework/13410) |
| 我在这个课程的目标是 | 通过实际的工程实践,进一步体会现代软件工程构建的方法论,在这个过程中不断完善个人技术栈 |
| 这个作业在哪个具体方面帮助我实现目标 | 两人通过结对编程合作完成小项目开发,体验结对编程流程 |
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025年3月31日 19 : 08
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
我的等级是I. 没有听说过。除此之外对javascript,typescript等语言的了解也不多,仅局限于比较浅显的知识。
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025年3月31日 19 : 25
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025年3月31日 19 : 26
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 2 | 2 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 2 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 6 |
| - Coding Standard | - 代码规范 | 2 | 1 |
| - Design | - 具体设计(确定怎么实现) | 10 | 5 |
| - Coding | - 具体编码 | 60 | 36 |
| - Code Review | - 代码复审 | 10 | 7 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 2 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 18 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 3 |
| - Size Measurement | - 计算工作量 | 2 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 3 | 2 |
| TOTAL | 合计 | 142 | 84 |
首先结对成员一起阅读了结队项目指导书,明确了本题目要实现的具体任务,并且在github上fork了项目仓库,并clone到本地。之后明确了本项目使用的语言,初步学习了语法,比较接近typescript。
两人针对题目场景进行讨论,最终确定使用从果子开始的广度优先遍历,将遍历到蛇头的那一步的传播方向的反方向作为蛇的下一步移动方向,这样可以确保蛇的移动次数尽量少。之后进行代码编写,由于本人对相关语法不熟悉,而我的队友比较熟练,因此这一步在队友的讲解下逐步进行,边学习语法边进行代码编写。
代码编写完成后运行,发现无法通过样例,因此开始进行调试。最终发现了以下两个bug:
- 题目给出的棋盘坐标从1到8,而我的代码中对应的下标为0到7,忘记在两者之间转化,从而导致数组越界。
- 没有妥善处理蛇头与蛇尾。应当将蛇尾标记为空位,因为该位置下一步一定是空气,蛇也可以朝着该方向前进。蛇头也应处理为空气,这与我们的具体代码逻辑有关。
通过了本地样例后进行进一步测试。通过测试后将项目代码commit到仓库中。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
我们的测试不断自动生成新的合法的初始蛇状态和果子状态,并且将它传入greedy_snake_fn_checker函数,检测其输出是否大于等于0,即判断是否可以正常运行。
测试用例的生成方式是随机数生成。先生成一个蛇头坐标,再基于这个坐标向四个方向不断前进,直至将四个坐标全部生成,只需要保证坐标之间不重合,且坐标没有超出棋盘范围,否则重新生成该坐标。果子坐标随机生成在空闲的棋盘中。
对于本题不存在什么特殊测试样例需要考虑。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
单元测试可以帮助确保自己的开发代码实现了需求,防止出现意料外的bug。单元测试通过模拟不同情况下的输入与输出,并且覆盖各种可能的边界条件,来确保代码逻辑的正确。但是单元测试的粒度比较小,有一些bug可能在多个单元之间的交互中产生,因此还需要做进一步的系统测试。
单元测试可以帮助提高代码质量与可维护性。为了编写单元测试,需要对代码中的一些模块解耦,这样增强了代码业务逻辑的独立性,从而减少了潜在存在的代码漏洞。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025年3月31日 20 : 50
→ 📖 Q1.6(I) 请写下本部分的心得体会。
通过完成这部分项目,我初步了解了WebAssembly驱动的编程原理,并在简单的动手实践过程中进一步体会软件开发的流程。我第一次体验了结对编程,并担任“驾驶员”的角色。同伴的存在让我的代码编写更加轻松,减少了程序错误,提高程序质量,并且通过不断复审及时解决了问题,体会到了结对编程的优越性。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025年3月31日 20 : 50
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 2 | 2 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 2 | 2 |
| - Coding Standard | - 代码规范 | 2 | 2 |
| - Design | - 具体设计(确定怎么实现) | 20 | 2 |
| - Coding | - 具体编码 | 100 | 22 |
| - Code Review | - 代码复审 | 10 | 12 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 2 | 2 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 13 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 7 |
| - Size Measurement | - 计算工作量 | 2 | 3 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 2 | 3 |
| TOTAL | 合计 | 182 | 75 |
遇到的问题与解决: 分析T2任务发现与T1相似度高,仅仅是引入了障碍物,所以直接基于T1代码进行了迭代开发。对于通常情况并没有出现问题,但我们考虑到不可达的判断问题中,盘起的蛇的身体可能会产生干扰,为此我们将障碍与蛇身分别处理,进行了代码局部重构,解决了相应问题。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
对于寻路逻辑基本完全复用,主要添加了障碍物阻拦的判断,并在寻路失败时返回-1。为解决不可达判断的问题,将蛇身成环的情况特别处理。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
- 采取模块化设计,将部分重要函数封装起来。通过模块化整个系统的复杂度下降,减少了功能耦合与潜在漏洞的出现。除此之外,模块化设计可以降低后续功能迭代的成本。比如由于代码逻辑多次运用广度优先遍历,可以将相关代码独立出一个函数,这样可以方便的调用,减少重复编码,降低开发复杂度。
- 减少代码中魔法数字的出现。魔法数字过度依赖于某个特定情境,当发生场景切换再去整体代码会留下大量隐患,且切换不方便。应当将魔法数字替换为相关变量,如果子数量,场地长度,宽度等。
- 预留逻辑的切换点。在不同的对战模式下(如1 v 1与四蛇混战)可能要执行不同的代码逻辑,这时可以通过一个全局控制变量控制关键逻辑,从而保持对后续迭代新逻辑的开放。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
-
基本的寻路,T1,T2中使用的广度优先寻路可以找出与蛇头最近的果子,这一处理方式在多个果子存在的情况下可以寻到一条合适路径,大概率不是最短路径,但基本可用。
-
陷阱问题,由于吃完一个果子后并不会结束游戏,存在于死路中的果子会成为杀死蛇蛇的陷阱,由于保证至少存在一条合法路径,这类陷阱果子必须放在最后吃掉。 可以加入死路的检测, 将果子分为陷阱中和陷阱外,有限吃完外部果子在去踏足陷阱。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025年3月31日 22 :03
→ 📖 Q2.7(I) 请写下本部分的心得体会。
首先是本地开发环境对开发体验的重要影响。我的vscode中没有安装typescript的调试器,只能使用vscode自带的debugger,为我带来了不少开发的不便。自带的调试器的监控变量界面经常反复切换,而且还出现了bug。如果有趁手的开发环境相比整个开发流程会顺畅很多。
其次,队友提出了我没有想过的特殊情况,从而使得代码逻辑更加完善。在编程时应当多设想边界情况,完善整个代码逻辑后再去进行代码开发,否则后续再更改工作量比较大。
我对AssemblyScript的语法等仍然不太熟悉,大量时间花费在搜索正确语法上,真正编程时间并不多。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025年4月2日 14 :30
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 8 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 2 | 2 |
| - Coding Standard | - 代码规范 | 2 | 2 |
| - Design | - 具体设计(确定怎么实现) | 15 | 27 |
| - Coding | - 具体编码 | 120 | 82 |
| - Code Review | - 代码复审 | 20 | 32 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 5 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 2 |
| - Size Measurement | - 计算工作量 | 5 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 2 |
| TOTAL | 合计 | 214 | 179 |
-
T3中我们最初计划沿用T1,T2的代码,继续单纯朴素的广度搜索来追求最近的果子,并自信满满的展开了行动,这里的开发及其顺畅, 仅需在T2的基础上将障碍物换成对手蛇的身体。
-
但是问题显然没有这么简单,只知冲向最近果子的小傻瓜一方面太容易一头撞死在对手蛇上,另一方面也容易被抢先而陷入拉扯中难以得分。 我们尝试查找贪食蛇相关的优化算法,咨询查特-吉皮蒂先生。很遗憾,大部分的建议指向了模型训练, 这对于刚摸清as的我们不太友好。商讨过后我们认为可以参考模型训练的思路, 将目标从寻路转变为优劣决策, 使用收益惩罚打分的机制输出行进方向。
-
我们将目标设置为远离争斗,稳中吃果,我们优先选择果子多,对手少的方向,并以对战的方式逐步优化权重系数的设计,调整小蛇在冒险与吃果之间的倾向,小蛇的表现基本趋于稳定。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
将每一轮决策视为三个可能的前进中方向中选一个(第二节身体的方向首先排除)。首先排除 不可选的方向,包括对手蛇的身体,自己的身体,墙面,再对剩下的选项进行打分评估(有选择余地的情况下): 需要选择能够尽可能多吃果子并远离障碍的方向。如果仍然存在因为分数相等而无法决策的情况,则根据特定顺序选择最终前进方向。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
-
优先靠近果子: 移动方向下可达果子的距离的倒数为收益, 优先靠近果子多且近的位置,通过以前进方向为中心做广度优先遍历实现。
-
优先远离对手: 移动方向下可达危险区域的距离倒数为惩罚,优先远离对手蛇多的区域,通过以前进方向为中心做广度优先遍历实现。
-
远离墙面: 靠近墙面的位置会相应一定惩罚,减少墙边堵死的情形,具体体现为在分数上减去特定惩罚值,使得蛇蛇尽量不忘靠近墙的方向前进。
-
利用
round控制倾向: 随着轮数增加,死亡的损失会相应减小, 因此控制果子的"诱惑力"逐步增大, 增加终盘得分能力。通过果子奖励系数随round的动态变化实现。 -
预测一步以内对手蛇的动向,远离潜在危险区域, 避免蛇头碰撞。代码上表现为将对手蛇蛇的可能前进位置设为“危险位置”。
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
-
我们的决策方案关键在于果子带来的"吸引力"与对手带来的"排斥力"之间的权衡, 具体表现程序中收益与惩罚系数。 我们使用不同系数的配置的蛇进行大量对决,统计胜率, 决定更优的参数配置。
-
定量分析方式: 在固定轮数下统计不同配置蛇蛇的胜率,最终得分, 死亡率等数据。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025年4月2日 17 :34
→ 📖 Q3.7(I) 请写下本部分的心得体会。
我体会到两个人的思维碰撞可以得出比自己一个人独立思考更加全面更加优秀的结果。对于T3的具体实现算法,在确认使用评分机制之后,我原本的想法是以每一个果子和每一个危险区域为中心做BFS,从而得到可能前进方向上的评分。但是我的队友提出了一种时间复杂度更低的方法,即以前进方向为中心做BFS,每次碰到果子或危险区域就做奖励或惩罚,减少了无用的计算量。我们也一起想到了一些需要特判的情形,提升了代码的鲁棒性,而这些仅由一个人是很难考虑全面的。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
-
代码管理, 最初直接fork了仓库,不能改隐私设置,导致代码共享有限,更多以两人看一屏的方式讨论,效率比较低, 应该直接开新仓库复制作业项目。
-
语言选择, 在这方面并没有过多调研就选择了推荐的as语言, 但两人实际都没有写过,所以编码过程持续的遭遇着语言相关工具不熟悉的问题,一定程度上影响了后续作业的发挥。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
- 代码编写能力强,有很强的编程语言基础与算法基础
- 对软件工程的实践开发流程熟悉,善于利用各种辅助工具
- 想象力强,可以想到很多未考虑的边界情况
缺点:
- 队友实力过于强大,给我带来了一些压力
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:代码编写和代码审查同时进行,代码质量得到提升;当发现问题时,两名成员可以及时沟通讨论并解决问题,不留下潜在问题,也统一了不同成员对该问题的理解。当两个成员水平不一样时,高水平成员可以交给低水平成员许多知识,达成知识共享,并在这个过程中共同进步。
缺点:结对编程的质量主要由水平较高的成员决定。当轮到水平低的成员编写代码时代码质量会比较差,导致总体质量良莠不齐,易发生潜在漏洞。除此之外两个人有可能出现争吵的情况,这会拖慢整体开发进度。
结对编程是一种极限编程的方式,因此我认为结对编程比较适合在开发时间很紧迫,并且两位成员的总体水平相近的时候实施。虽然两个人一起进行结对编程有比较新奇的体验,也能有更宽广的视野,但是有时候会开始聊天,导致效率不高。而且有一位大佬在旁边看我写代码也给我带来不少紧张情绪,发生不少简单失误。
代码实现提交
→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。
posted on 2025-04-03 21:15 earendilzhu 阅读(51) 评论(0) 收藏 举报
浙公网安备 33010602011771号