[P] 结对项目:影蛇舞
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 首页 - 2025年春季软件工程(罗杰、任健) - 北京航空航天大学 - 班级博客 - 博客园 |
| 这个作业的要求在哪里 | [P] 结对项目:影蛇舞 - 作业 - 2025年春季软件工程(罗杰、任健) - 班级博客 - 博客园 |
| 我在这个课程的目标是 | 掌握软件工程核心方法论与实践能力 |
| 这个作业在哪个具体方面帮助我实现目标 | 通过一次结对编程的实践,强化编程能力与团队沟通合作的能力 |
结对项目:博客问题清单
请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025.3.25 19:33
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
I
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025.3.25 19:49
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025.3.25 20:03
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
2.查阅了关于AssemblyScript 和Rust 的资料,确定了使用AS进行开发;
根据题目所给信息编写了目标函数,并使用ai生成测试样例进行测试;
测试过程中遇到问题:函数缺少“不允许蛇头直接转向第一节身体方向”的限制,导致没有通过测试;
根据题目逻辑编写了关于蛇头方向限制的辅助函数,在主函数中调用辅助函数避免了上述问题。
此外,还遇到了没有可视化分析的问题,解决方法是,使用ai生成了一个简单html的贪吃蛇可视化界面,通过可视化界面,对蛇的运动进行可视化地调试。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
1.基础移动逻辑
- 需求:蛇应根据当前方向和食物位置选择合理移动方向(如向食物靠近)。
- 对应的测试用例:
- 案例1:蛇头朝右,食物在右侧 → 预期方向为“右”(直接向食物移动)。
- 案例2:蛇头朝右,食物在左侧 → 预期方向为“上”(需转向避开自身或障碍)。
- 复杂路径场景
- 需求:蛇在复杂路径(如回字形)中仍能规划合理路径。
- 对应的测试用例:
- 案例3:蛇头在左上角,食物在右下方 → 预期方向为“右”(需绕过蛇身)。
- 案例4:蛇在左下角回字形,食物在右上方 → 预期方向为“上”(需突破回字形路径)。
- 案例5:蛇在右上角回字形,食物在左下方 → 预期方向为“左”(需绕开自身)。
3.边界条件
- 需求:蛇在边界(如角落)或极端位置时仍能正确移动。
- 对应的测试用例:
- 案例3:蛇头在左上角(坐标4,2),需向右移动。
- 案例4:蛇在左下角回字形(坐标1,1),需向上移动。
- 案例5:蛇在右上角回字形(坐标8,7),需向左移动。
4.方向优先级
- 需求:蛇应优先选择向食物移动的方向,同时避免碰撞自身或墙壁。
- 对应的测试用例:
- 案例2:蛇头朝右,但食物在左侧 → 预期方向为“上”(可能因右侧无空间,需转向)。。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
单元测试是软件开发中针对代码最小单元(如函数、模块)的验证手段,核心作用包括:保障代码质量,通过自动化检测提前发现逻辑错误或设计缺陷;降低修复成本,因问题在早期被发现,避免后期高昂的修改代价;支持代码重构,确保修改后功能不变,提升维护效率;同时作为团队协作的“质量标准”,减少沟通成本,并通过覆盖多种场景增强系统稳定性。它是高效开发、可靠交付的基础,通过“以小博大”的方式从源头把控质量。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.3.25 21:46
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 2 | 2 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 20 | 10 |
| - Coding Standard | - 代码规范 | 5 | 3 |
| - Design | - 具体设计(确定怎么实现) | 10 | 5 |
| - Coding | - 具体编码 | 10 | 55 |
| - Code Review | - 代码复审 | 10(并行) | 55(并行) |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 5 | 5 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 2 |
| - Size Measurement | - 计算工作量 | 1 | 1 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 10 |
| TOTAL | 合计 | 76 | 103 |
→ 📖 Q1.6(I) 请写下本部分的心得体会。
第一次接触结对编程,感觉还是挺新鲜的。与自己单打独斗相比较,我觉得结对的意义主要在于决策方面。比如对于“应该使用Rust还是AssemblyScript”这个问题,我自己通常会陷入纠结的状态很久,而结对时彼此可以交换各自的经验和掌握的信息,通过权衡利弊很快地做出决定,节省了大量的时间。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025.3.26 9:26
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
首先,阅读了题目要求,了解了贪吃蛇的基本规则和目标函数的要求。
根据题目要求,讨论、编写了bfs移动的基本逻辑。在过程中,查找了有关map和set的相关资料。
遇到了问题:在使用map和set时,使用自定义的类型,会出现重复添加的问题。
在ai的指导下,将自定义类型编码为字符串,解决了上述问题。
此外,针对AssemblyScript难以调试的问题,改写了之前T1中的可视化界面,以支持TypeScript,使用编译前的ts代码进行可视化调试。
另外,设计了一点测试用例,测试了蛇头运动的正确性。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T2 中已实现的代码进行了哪些复用和修改。
复用了一些辅助函数,如getCurrentDirection获取当前蛇头方向。
放弃了之前使用的贪心策略,改为利用BFS搜索并记录路径,直接令贪吃蛇沿着该路径移动。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
设计思想方面,遵循开闭原则,通过接口、策略模式等将核心逻辑与实现分离,允许新增代码而非修改原有代码满足新需求;采用单一职责原则,确保每个模块专注单一功能,减少耦合;通过模块化设计将系统拆分为独立组件,降低变更影响范围。
设计冗余方面,可预留扩展点,支持未来功能扩展;抽象关键逻辑为接口,隐藏实现细节,便于替换底层实现;采用配置化设计,将可变参数抽离到配置文件,避免硬编码;添加容错机制应对未预见的输入变化;为接口设计版本化,确保新旧功能并行兼容。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
由于蛇不会撞自己,因此,蛇的状态可以使用蛇头位置和朝向表示。通过对(每个果子*4个方向 + 初始位置)分别进行bfs搜索,判断每个果子之间的可达性。对于可以到达的果子之间,连一条有向边。
之后,在这张图上做dfs搜索,求得经过所有果子的一条吃果子顺序。
再根据这个顺序,求得一条所求的路径。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.3.26 12:02
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 3 | 3 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 0 | 0 |
| - Coding Standard | - 代码规范 | 0 | 0 |
| - Design | - 具体设计(确定怎么实现) | 20 | 10 |
| - Coding | - 具体编码 | 60 | 90 |
| - Code Review | - 代码复审 | ||
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 5 | 10 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 10 | 20 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 5 |
| - Size Measurement | - 计算工作量 | 2 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 10 |
| TOTAL | 合计 | 120 | 155 |
→ 📖 Q2.7(I) 请写下本部分的心得体会。
本部分主要在第一题的基础上加入了障碍物的实体。在前期讨论时,我们二人都认为可以通过BFS来实现,因此很快就开始了编码环节。然而在具体实现过程中,我对于BFS的使用理解还是不够到位,导致我的蛇经常会进入原地转圈的死循环状态。我对此无法理解,只是闷头猛测,在浪费了大量时间后还是没有解决,这时我才开始向队友求助。经过两人的分析,彻底改变了算法的思路,问题很快迎刃而解。这次的经历告诉我们在结对编程时遇到问题要及时与队友沟通,时刻发挥结对的优势,才能以更高的效率完成工作。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025.4.2 19:00
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
首先,根据题目需求,大体上设计了贪吃蛇的基本逻辑。即根据果子,其他蛇的位置信息,为某个运动方向打分,选择分数最高的方向。
然后,根据需求分析,大致实现了贪吃蛇运动的基本逻辑。
在编码过程中我们通过反复交流,讨论关于打分的细节问题。
主要遇到的问题是,调试过程中,反复出现数组越界的问题,在仔细检查代码后,将各种硬编码的数值改为变量,解决了上述问题。
同时,发现之前的T2中的逻辑有些问题,花了一些时间,修改T2中bfs的逻辑,添加了更多测试。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
首先,我们仔细阅读了题目需求,了解了贪吃蛇的基本规则和目标函数的要求。将输入的蛇头位置、食物位置、障碍物位置等信息进行建模。
然后,我们了解到一些游戏ai, 仿生编程中,会使用打分的方式,代替实际的寻路搜索。基于这一思想,我们也设计了类似的打分逻辑,通过食物->奖励,障碍物(即其他蛇)-> 惩罚的方式,来设计蛇的运动方向。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
- 存活策略
- 确保选择不会立即死亡,根据不能反向,不能直接撞墙/其他蛇的规则,利用T1中的实现,先筛选出合法方向。
- 对于其他蛇,使用bfs计算他们接下来若干步的可能位置,为可能到的方向打分(称为危险分数),避免选择可能被其他蛇撞到的方向。
- 针对可能会被挤到角落的情况,利用dfs计算走之后的自由度(可能剩余的空间),为该方向打分(称为自由度分数),避免被挤到角落。
- 得分策略
- 对于食物,根据距离,为每个方向打分,越近的方向分数越高,以引导蛇朝食物方向移动。
根据以上策略,合理选择参数,从而实现合理的运动方向。
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
通过在迭代过程中,与不同参数,不同版本的蛇进行对战,并将T2中的蛇简单改写到T3中,参与对战。
对课程组提供的运行程序进行简单改造,反复多次执行,在200次对战中,统计平均得分。根据平均得分的高低,来评估蛇的对战能力。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.4.2 23:15
此外,在2025.4.5 14:50 - 15:15 期间对蛇的对战能力进行了测试。
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 3 | 3 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 10 |
| - Coding Standard | - 代码规范 | 0 | 0 |
| - Design | - 具体设计(确定怎么实现) | 20 | 20 |
| - Coding | - 具体编码 | 100 | 195 |
| - Code Review | - 代码复审 | ||
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 10 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 5 | 5 |
| - Size Measurement | - 计算工作量 | 2 | 2 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 10 | 10 |
| TOTAL | 合计 | 190 | 270 |
→ 📖 Q3.7(I) 请写下本部分的心得体会。
最后一部分涉及“多人联机”,我们一致认为可以将地图中的另外三条蛇当作可以移动的障碍物来处理。在具体实现时,我们二人各自都有实现的思路,因此决定同时进行编程,最终取性能更好的一方。然而实际的实现难度还是超出了预期,我们花费了大量时间只能勉强得到一版中规中矩的代码,并没有剩下很多优化的时间。我们对此也进行了反思,对于结对编程中遇到的复杂问题,应该在初期确定尽可能合理的一个实现方向,然后再集中力量区去完善和优化。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
- 沟通与同步不足
- 问题:双方对需求或代码逻辑的理解存在偏差,导致设计与实际编写代码的不一致。
- 改进:两人合理地参与交流,确保信息共享的一致性。同时需要更加主动地复审与指出问题。
- 测试用例覆盖不全面
- 问题:测试用例集中在简单场景,可能存在未覆盖的极端情况。
- 改进:一人负责设计用例,另一人通过ai等工具补充遗漏场景。
- 代码审查流于形式
- 问题:急于推进代码实现,未仔细检查彼此的代码。导致花费大量时间返工修bug。
- 改进:交替担任“编码者”和“审查者”;使用ai工具辅助检查。
- 时间管理不灵活
- 问题:固守预设时间分配,导致某些复杂问题的处理较为粗糙。
- 改进:遇到难点时先暂停,集中力量优先解决核心矛盾;优化分工,提升工作效率。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:
- 较强的洞察力:能快速抓住问题核心,避免在细枝末节上面浪费时间。
- 较强的韧性:对于技术上的难题不轻易妥协,坚持努力到问题彻底解决为止。
- 全局观与平衡感:在技术深度与实现难度之间能够把握平衡,确保最终的方案既正确又可行。
缺点:
过度追求完美主义:对细节近乎苛刻的执着,偶尔因反复打磨代码或方案而花费过多时间,轻微影响了整体的进度。
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
结对编程是两人共同完成开发任务的协作模式,其核心是实时协作与知识共享。优点在于:通过双人实时讨论与检查,能快速发现逻辑漏洞、统一代码规范,减少后期修复成本;同时促进经验传递,加速新人成长,并降低关键知识集中于单人的风险。此外,双人思维碰撞有助于突破技术瓶颈,提升问题解决效率。缺点则包括:短期需投入双倍人力,可能降低编码速度;沟通不畅或观点冲突可能影响效率;远程协作时工具限制或时差问题也可能削弱效果。此外,并非所有任务都适合结对,比如简单的调试工作可能更适合单人完成。
我认为结对编程的本质是以协作换取质量与团队能力的提升。它尤其适合复杂模块开发、技术难点攻关或团队知识共享场景,但需根据任务性质灵活选择搭档,并注重营造开放沟通的氛围。其长期价值在于减少技术债务、增强团队协作默契,但需平衡短期成本与实际收益,避免盲目适用。
浙公网安备 33010602011771号