[P] 结对项目:影蛇舞
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 2025年春季软件工程 |
| 这个作业的要求在哪里 | [I.1] 个人作业:阅读和提问 |
| 我在这个课程的目标是 | 学习现代软件构建的工程方法,锻炼团队协作能力。在团队的共同合作下产出符合流程的高质量软件。 |
| 这个作业在哪个具体方面帮助我实现目标 | 体验结对编程,锻炼极限开发 |
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025/3/20 13:30
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
I. 没有听说过
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025/3/30 14:13
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025/3/30 14:14
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
- 预估时间:
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | |
| - Estimate | - 估计这个任务需要多少时间 | 5 | |
| DEVELOPMENT | 开发 | 202 | |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | |
| - Coding Standard | - 代码规范 | 2 | |
| - Design | - 具体设计(确定怎么实现) | 30 | |
| - Coding | - 具体编码 | 60 | |
| - Code Review | - 代码复审 | 20 | |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 40 | |
| REPORTING | 报告 | 50 | |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | |
| - Size Measurement | - 计算工作量 | 10 | |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | |
| TOTAL | 合计 | 257 |
- 我们首先通过题目的描述和要求进行讨论解决方法。我们主要考虑快以及不发生碰撞。起初我们采用贪心的想法,但是发现对于有些果子以及蛇的位置,直接贪心肯定会发生碰撞。
为了解决这个问题,我们分类讨论分析多种位置情况,结果发现,蛇只会和第二节身子相撞,不会与第三节身子和蛇尾相撞,于是就简化了碰撞的复杂度,蛇头只能向三个方向行动。 然后分类讨论不同位置情况,利用贪心,我们开始代码编写。同时因为果子肯定在场地里面,所以可以减少部分场地边界的判断。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
我们重点针对碰撞情况(越界情况)进行测试。
最开始随便设计一个参数进行测试,看看代码是否能正确运行,然后进行课程组的测试。
后面设计了一些特殊情况,比如(1,1)(1,8)(8,1)(8,8)等边界情况,测试是否碰撞。同时针对蛇需要“绕”一下的情况设计测试样例。
再后面,用随机生成的方式写了一个评测程序,进行大量的随机测试,测试蛇的行动是否合理,是否会碰撞。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
单元测试可以在软件开发中帮助我们尽早发现和修正错误,确保每个模块按照预期工作,从而在重构或扩展代码时降低出错风险。它能提高代码质量、便于维护和增强团队协作效率。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
15:12 结束代码编写,开始测试
16:47 完成测试17:52 复查代码和测试
18:40 完成测试复查,修改了测试程序的bug
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 3 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 3 |
| DEVELOPMENT | 开发 | 202 | 257 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | 10 |
| - Coding Standard | - 代码规范 | 2 | 1 |
| - Design | - 具体设计(确定怎么实现) | 30 | 30 |
| - Coding | - 具体编码 | 60 | 58 |
| - Code Review | - 代码复审 | 20 | 10 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 20 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 40 | 123 |
| REPORTING | 报告 | 50 | 30 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | 10 |
| - Size Measurement | - 计算工作量 | 10 | 10 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 10 |
| TOTAL | 合计 | 257 | 290 |
→ 📖 Q1.6(I) 请写下本部分的心得体会。
第一阶段的任务相对基础,更多是为整个结对编程项目做好准备。这个部分的目标主要是熟悉开发流程、明确合作方式,并掌握项目所需的技术栈。在这一过程中,我们选择了 Rust 作为开发语言,这对我们来说是一个全新的尝试。
因为我们是熟人,沟通起来没有障碍,也能直接表达各自的看法。不过有时候正因为太熟了,彼此都比较有主见,一些实现细节会反复讨论,效率不算特别高。但这些讨论也并非没有收获,有时一个小小的分歧反而能让我们跳出思维定式,发现更优的解决方案。
我们还花了不少精力在测试上,希望尽量覆盖各种情况。为此写了自动生成随机数据的测试工具,虽然这个过程有些繁琐,加上对 Rust 的调试流程不熟练,卡了不少时间,但也确实提升了我们对语言本身和测试工具链的掌握程度。
这部分虽然不算困难,但在合作节奏、技术选型、思路交流等方面都起到了重要的磨合作用。希望在后面的开发中,我们能在这个基础上配合得更高效。
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025/3/31 20:35
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
- 预估时间
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | |
| - Estimate | - 估计这个任务需要多少时间 | 5 | |
| DEVELOPMENT | 开发 | 282 | |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | |
| - Coding Standard | - 代码规范 | 2 | |
| - Design | - 具体设计(确定怎么实现) | 60 | |
| - Coding | - 具体编码 | 100 | |
| - Code Review | - 代码复审 | 10 | |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 60 | |
| REPORTING | 报告 | 50 | |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | |
| - Size Measurement | - 计算工作量 | 10 | |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | |
| TOTAL | 合计 | 337 |
- 我们根据题目要求,首先进行了讨论,将问题转换为蛇头为起点,果子为终点,存在障碍物且不发生碰撞的最短路径问题。
我们首先想到的是采用bfs算法,蛇头为了不碰撞身体,只有三个方向可以走,再考虑障碍物位置,进行bfs搜索。如果没找到路径,就返回-1,否则就返回第一步的方向。
我们紧接着讨论了这个想法的可行性,我们发现存在一些障碍的情况导致,蛇可能需要“绕一下”,会走“回头路”,这就导致,普通的visited数组无法解决这个问题。
遇到这个问题,我们查询了相关资料,并询问了大模型,最终我们选择A*的算法来解决这个问题。visited数组增加一个参数来进行判断。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
因为T1的代码是基于贪心算法实现的,而我们现在需要的是A*算法,所以我们对T1的代码进行了重构,主要是将贪心算法的部分替换为A*算法的实现。我们保留了原有的函数结构和变量命名,以便于理解和维护。
对于碰撞判断部分,蛇身碰撞和边界判断依旧使用了T1的代码,只是增加了对障碍物的判断。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
- 设计思想:
- 模块化设计:将功能划分为独立、职责单一的模块(如碰撞检测、评分函数、路径搜索等),便于替换或扩展。
- 高内聚低耦合:每个模块只负责自己的逻辑,尽量减少模块之间的依赖。
- 设计冗余:
- 预留扩展字段:在数据结构中预留字段或支持元数据字段,便于将来加入新状态或标记。
- 冗余参数设计:函数定义中提前包含一些暂未使用但可能有用的参数,提升未来功能接入的灵活性。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
采用“优先吃最近果子”的贪心策略,选取距离当前蛇头最近的果子,使用A*算法(T2算法)判断是否可达,当无法到达时引入回退机制,尝试次优目标或重构路径。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025/3/31 21:53 中途暂停
2025/3/31 22:25 继续
2025/4/1 0:18 结束
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 3 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 3 |
| DEVELOPMENT | 开发 | 282 | 177 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 5 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | 30 |
| - Coding Standard | - 代码规范 | 2 | 1 |
| - Design | - 具体设计(确定怎么实现) | 60 | 20 |
| - Coding | - 具体编码 | 100 | 71 |
| - Code Review | - 代码复审 | 10 | 10 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 10 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 60 | 30 |
| REPORTING | 报告 | 50 | 11 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | 5 |
| - Size Measurement | - 计算工作量 | 10 | 3 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 3 |
| TOTAL | 合计 | 337 | 191 |
→ 📖 Q2.7(I) 请写下本部分的心得体会。
我们在这个部分经历了2个阶段的设计。
首先是想使用简单的BFS去搜索是否有可达路径,但经过讨论后,我们发现了一种情况:当蛇必须绕一大圈甚至“回头”才能抵达目标位置时,普通的 BFS 会错误地把某些本应可达的位置标记为不可达。
这个问题暴露了我们在设计状态空间时的不足。BFS 本身不是不能处理,只是我们当时为了图方便,使用了一个过于简化的 visited 数组,忽略了蛇身动态变化的影响。在意识到这个问题后,我们通过查找资料,转向了 A* 算法,因为它支持启发式搜索,看起来能更“聪明”地找到合适路径。但回过头来看,其实只要在 BFS 中对访问状态建模得更细致,例如把蛇身长度或回合数纳入状态判重条件,也应该是可以解决问题的。
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025/4/2 19:28 开始
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
- 预估时间
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | |
| - Estimate | - 估计这个任务需要多少时间 | 5 | |
| DEVELOPMENT | 开发 | 267 | |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | |
| - Coding Standard | - 代码规范 | 2 | |
| - Design | - 具体设计(确定怎么实现) | 60 | |
| - Coding | - 具体编码 | 120 | |
| - Code Review | - 代码复审 | 10 | |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | |
| REPORTING | 报告 | 50 | |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | |
| - Size Measurement | - 计算工作量 | 10 | |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | |
| TOTAL | 合计 | 322 |
- 我们首先针对问题进行讨论,然后记录需要考虑的因素,进行建模,在这期间,主要询问大模型,帮助我们分析,然后利用传统的方式进行第一版开发。后面经过和别人的测试,发现效果不好,尝试深度学习开发,训练不出来,放弃,重新进行传统方式的改进,利用大模型,增加更多的评估变量。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
在本任务中,我们将蛇的每一步行动建模为一个多目标评分问题,通过对各方向的综合打分来进行最优决策。我们根据对战模式的不同,分别设计并采用了两套差异化策略体系,以更好地适应 1v1 和 4v4 的博弈环境。
4v4 模式:更注重对抗与生存
- 在 4v4 场景中,地图空间较大、敌人数量少,我们更强调“果子控制力”与“局部对抗中的生存能力”。
- 建模时,我们重点考虑以下评分项:
safety_score: 避免被对方蛇头围堵;free_score: 使用洪水填充评估当前自由空间;food_score: 结合我方与敌方到果子的相对距离评估“吃到果子的优势”(实现了果子竞速建模);center_score: 鼓励靠近地图中心,增强后续可行动性。
- 策略特点: 以对抗为导向,控制局部资源,防止头对头碰撞,稳定吃果。
1v1 模式:更注重快速得分与多目标评估
- 在 1v1 多蛇环境中,空间拥挤、节奏快,强调果断吃果子与避开混战,我们采用了简化模型、快速评估策略。
- 建模时采用以下核心评分项:
food_score: 纯粹使用距离驱动,快速吃到最近果子;danger_score: 避免进入敌方密集区域或墙角;free_score: 粗略估计自由格子数量,确保蛇不被封死。
- 策略特点: 快速、果断、避免碰撞为主,牺牲复杂性换取实时性。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
一、如何避免死亡
我们通过多维度判断来确保蛇尽可能存活,尤其在与敌方接近或空间受限的情况下,更加保守和避险。
- 安全性评分(
safety_score)- 计算当前位置与敌方蛇头的最小曼哈顿距离;
- 距离越远评分越高,避免被头对头夹死;
- 空间评分(
free_score)- 使用洪水填充算法,估计当前方向的可行动空间大小;
- 避免进入死胡同或封闭区;
- 边界惩罚与陷阱惩罚(
danger_score)- 如果当前位置靠近墙角或边界,或者空间极小,则给予惩罚;
- 敌人预测与头对头碰撞规避
- 模拟敌方可能的移动方向,若发生头对头冲突,则当前方向降权;
二、如何吃到更多果子
为了最大化得分,我们在路径规划中积极争抢果子,尽量选取我方“能更快吃到”的目标果子。
- 果子接近度评分(
fruit_score)- 对每个方向,使用A*计算当前蛇头到所有果子的最小距离;
- 距离越近,评分越高;
- 果子控制力评分
- 若我方比其他所有蛇更快吃到某个果子,则提升得分;
- 中心控制策略(
center_score)- 鼓励靠近地图中心,提升未来吃果子灵活性;
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
在多轮测试对抗中,统计输赢情况以及死亡情况,统计胜率和死亡率。胜率越高,死亡率越低越有效。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025/4/2 20:40 完成部分代码,因为要软工开会,中途暂停,完成了evaluate_safety
2025/4/2 23:13 继续完成代码
2025/4/3 00:25 结束第一版本2025/4/6 11:00 继续
2025/4/6 13:00 吃饭
2025/4/6 13:40 继续
2025/4/6 18:00 暂停
2025/4/6 21:00 继续
2025/4/6 23:30 结束
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | 5 | 3 |
| - Estimate | - 估计这个任务需要多少时间 | 5 | 3 |
| DEVELOPMENT | 开发 | 267 | 638 |
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 5 | 3 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 30 | 40 |
| - Coding Standard | - 代码规范 | 2 | 1 |
| - Design | - 具体设计(确定怎么实现) | 60 | 60 |
| - Coding | - 具体编码 | 120 | 459 |
| - Code Review | - 代码复审 | 10 | 10 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 30 | 60 |
| REPORTING | 报告 | 50 | 13 |
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 20 | 5 |
| - Size Measurement | - 计算工作量 | 10 | 3 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 20 | 5 |
| TOTAL | 合计 | 322 | 654 |
→ 📖 Q3.7(I) 请写下本部分的心得体会。
这个部分我们思考和讨论了非常久,需要考虑的因素非多。反复推敲才最终选定分1v1与4蛇策略。
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。
→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
在结对的过程中,我们的配合默契度较高,讨论也很顺畅,但是在一些问题上会有争论,导致效率降低。我们可以尝试使用一些工具来帮助我们更好地进行讨论,比如使用白板工具进行可视化讨论。
还有就是对一些问题纠结太多导致不能及时打代码,导致很多纸上谈兵。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
-
优点:
- 执行力强;
- 查找资料的能力很强;
- 思维敏捷;
-
缺点
- 有时候太急了!
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
- 结对编程的优点:
- 问题发现更及时:两人实时讨论,一方编码时另一方思考更高层逻辑或细节盲区,可以更早发现 bug 或潜在风险,减少返工。
- 思维互补,提升方案质量:两个人往往有不同的理解和解决问题方式,在沟通中容易碰撞出更优的思路,有时候一个人没想到的点,另一个人能及时补上。
- 学习效率高,知识共享快:尤其是一个人对某个工具或语言更熟时,另一个人能在实践中快速上手,边做边学,效率远胜单人摸索。
- 结对编程的缺点:
- 效率未必更高,甚至可能更低:如果两人节奏不一致,或者讨论太久卡在一个问题上,反而会拖慢整体进度;有时一个人独立实现反而更快。
- 容易产生冲突:尤其是认识较熟的搭档,更容易出现“坚持己见”的情况,对代码风格、结构、优先级的分歧可能影响效率。
我认为结对编程的核心不是“轮流写代码”,而是“共同思考,持续对齐”。它更适合需要深入逻辑推理、算法设计或结构架构的开发任务,比如本次结对项目,讨论路径规划、评分策略这些复杂问题时,结对编程显著提升了我们方案的深度和代码的可靠性。
结对编程不是适合所有任务的“万能解”,但对于需要多人思维协作的问题来说,它是一个非常有价值的开发方式。
浙公网安备 33010602011771号