结对项目:博客问题清单

项目 内容
这个作业属于哪个课程 2025年春季软件工程(罗杰、任健)
这个作业的要求在哪里 结对作业:影蛇舞
我在这个课程的目标是 通过学习和团队合作,了解敏捷开发流程。提高个人编码素养,掌握软件工程的核心概念和方法。
这个作业在哪个具体方面帮助我实现目标 了解结队编程的基本流程,增强团队开发能力

Chapter.0 Belua multorum es capitums.(你是多首的怪物。)

引入

→ 📖 Q0.1(P) 请记录下目前的时间。

3月22日 8:55

调查

→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。

I. 没有听说过;

II. 仅限于听说过相关名词;

III. 听说过,且有一定了解;

IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。

I. 没有听说过

总结

→ 📖 Q0.3(P) 请记录下目前的时间。

3月22日 9:35

Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)

结对过程

→ 📖 Q1.1(P) 请记录下目前的时间。

3月22日 9:47

→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
Personal Software Process Stages 个人软件开发流程 预估耗时(分钟) 实际耗时(分钟)
PLANNING 计划 5min 3min
- Estimate - 估计这个任务需要多少时间 5min 3min
DEVELOPMENT 开发 113min 101min
- Analysis & Design Spec - 需求分析 & 生成设计规格(确定要实现什么) 10min 9min
- Technical Background - 了解技术背景(包括学习新技术) 0min 0min
- Coding Standard - 代码规范 15min 15min
- Design - 具体设计(确定怎么实现) 5min 5min
- Coding - 具体编码 40min 27min
- Code Review - 代码复审 7min 5min
- Test Design - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) 6min 4min
- Test Implement - 测试实现(设计/生成具体的测试用例、编码实现测试) 30min 36min
REPORTING 报告 22min 21min
- Quality Report - 质量报告(评估设计、实现、测试的有效性) 10min 9min
- Size Measurement - 计算工作量 2min 2min
- Postmortem & Process Improvement Plan - 事后总结和过程改进计划(总结过程中的问题和改进点) 10min 10min
TOTAL 140min 125min

在看到这个任务的编程语言要求后,我们首先调研了Assembly和Rust的实现难度。在经过一个小时的调研后,我们发现Assembly实现起来更加轻松高效,于是我们选取了Assembly进行开发。

针对第一部分的具体问题,我们首先在互联网上查询了一些贪吃蛇的算法。但最终发现,对于我们这种贪吃蛇长度不增长,问题规模小的情况,直接采取bfs比较合适。我们最终选取了用bfs求出蛇到果子的最短路径,依据该最短路径决定每一步方向的方法。

测试

→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。

我们参考了课程组给出的test.js文件,借用greedy_sanke_fn_checker函数并增加更多测试样例,我们主要测试了以下一些情况

  • 测试直接吃到食物
  • 测试角落导航
  • 测试环形身体阻挡路径
  • 测试垂直方向长蛇绕行
  • 测试贴边移动
  • 测试L型身体导航
  • 测试直角转弯逻辑

基本覆盖了所有贪吃蛇程序在实际运行过程中可能遭遇的情况。

这些测试样例在我们开发的过程中帮助我们发现了许多bug。

→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。

单元测试能够让我们能够及时发现软件中的缺陷,在一定程度上保证最终软件的质量,减少我们后续在debug上耗费的时间。

总结

→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。

3月22日 12:30

→ 📖 Q1.6(I) 请写下本部分的心得体会。

次艰难的作业,总是有一个看上去不那么艰难的开头。

有一说一,就第一次作业而言,我自己写不比结对编程快多了,毕竟bfs都不知道写过多少遍了。

不过我的队友确实在我编码的过程中及时发现了我的设计缺陷之处(虽然我觉得后续我也能靠写单元测试测出来就是了

Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)

结对过程

→ 📖 Q2.1(P) 请记录下目前的时间。

3月23日 9:12

→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
Personal Software Process Stages 个人软件开发流程 预估耗时(分钟) 实际耗时(分钟)
PLANNING 计划 5min 5min
- Estimate - 估计这个任务需要多少时间 5min 5min
DEVELOPMENT 开发 94min 102min
- Analysis & Design Spec - 需求分析 & 生成设计规格(确定要实现什么) 7min 6min
- Technical Background - 了解技术背景(包括学习新技术) 0min 0min
- Coding Standard - 代码规范 5min 8min
- Design - 具体设计(确定怎么实现) 5min 3min
- Coding - 具体编码 30min 28min
- Code Review - 代码复审 7min 7min
- Test Design - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) 10min 8min
- Test Implement - 测试实现(设计/生成具体的测试用例、编码实现测试) 30min 42min
REPORTING 报告 15min 21min
- Quality Report - 质量报告(评估设计、实现、测试的有效性) 7min 10min
- Size Measurement - 计算工作量 5min 8min
- Postmortem & Process Improvement Plan - 事后总结和过程改进计划(总结过程中的问题和改进点) 3min 3min
TOTAL 114min 128min

在本次作业中,我们发现我们上一次的作业基本可以套用,只需要加一个Set类型变量表示障碍物,于是我们较快地决定贪吃蛇运行策略,迅速完成了编码。

代码可复用性与需求变更

→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑‍💻 T2 中已实现的代码进行了哪些复用和修改。

我们修改了eedySnakeMoveBarriers的函数实现,添加了barriers参数表示障碍物,添加了isBarrier函数判断某个坐标是否为障碍物。我们要求蛇不能走到标注为“障碍物”的格子。

→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。

出于利好后续迭代开发的考虑,我们在实际开发的过程中比较重视“高内聚低耦合”的设计思想:我们将程序的各个功能函数化、模块化,并在程序的关键节点预留拓展的余地(比如决定蛇要往哪个方向移动)。

这样的设计方法使得我们在开发过程中维持了较好的代码可读性,增强了程序的可拓展性。因此我们在开发过程中大量复用前几次作业的代码,基本都是增量开发,大大减轻了我们的工作量。

头脑风暴环节

**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:

🧑‍💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。

若一条果子到其他果子存在2条以上路径,则蛇一定不会困毙。通过BFS搜索单个果子到其他果子的路径,建立一张图。所以问题就变成了,如何访问图的节点,找到一条可以经过所有点的路径。由于度为1的节点只能最后访问,我们从度为1的节点开始搜索,总能找到一条路径。(因为其他点的度不小于2,否则将不存在路径)

总结

→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。

3月23日 11:23

→ 📖 Q2.7(I) 请写下本部分的心得体会。

大概是因为第一次作业打下了良好的基础,第二次作业我们很快就完成了。但是在编写测试样例进行测试时发现了bug,而且隐藏得比较隐蔽。这导致我们花费了较多得时间在debug上。

我也不禁想,在两个人高度关注代码的情况下尚且能出现这种Bug,那如果是我一个人完成编码那得出多少bug啊。这也是我第一次实实在在感受到了结对编程能够在一定程度上保证代码质量这一优点。

Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)

结对过程

→ 📖 Q3.1(P) 请记录下目前的时间。

3月31日20.30

→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
Personal Software Process Stages 个人软件开发流程 预估耗时(分钟) 实际耗时(分钟)
PLANNING 计划 10min 8min
- Estimate - 估计这个任务需要多少时间 10min 8min
DEVELOPMENT 开发 390min 322min
- Analysis & Design Spec - 需求分析 & 生成设计规格(确定要实现什么) 20min 15min
- Technical Background - 了解技术背景(包括学习新技术) 0min 0min
- Coding Standard - 代码规范 30min 20min
- Design - 具体设计(确定怎么实现) 30min 25min
- Coding - 具体编码 120min 110min
- Code Review - 代码复审 20min 30min
- Test Design - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) 30min 38min
- Test Implement - 测试实现(设计/生成具体的测试用例、编码实现测试) 40min 85min
REPORTING 报告 70min 72min
- Quality Report - 质量报告(评估设计、实现、测试的有效性) 20min 23min
- Size Measurement - 计算工作量 20min 17min
- Postmortem & Process Improvement Plan - 事后总结和过程改进计划(总结过程中的问题和改进点) 30min 32min
TOTAL 370min 402min

本次最初计划采用强化学习,但是由于没有可靠的训练,以及对于强化学习的理解不够深入,经过尝试后发现不理想放弃采用,继而采用了一种启发式的算法来解决此次任务。
为了搜索好的算法,我们前去网站观看较好地贪吃蛇算法,不过由于其问题大多不会考虑对抗,yield的使用不熟练,因此放弃。
设计启发式的算法,两人对“好”的定义,纠结了一会,(以蛇为主体/以果子为主体),最后决定是评判果子的得分来进行抉择。

需求建模和算法设计

→ 📖 Q3.3(P) 请说明你们如何建模这一需求。

对抗,意味着出现了多个目标果子和一个动态的障碍物。因此我们首先需要选取相对最近最优的目标果子,同时预测躲避障碍物。在这个过程中,可能不存在最近的果子和到达果子的路线,这时,我们不能输出无法找到路径,而是应该尽可能地活下去,选取出现障碍物最小概率的方向进行行走。

→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。

由于场上存在众多果子,为了尽可能地吃果子,需要计算所有果子相对我们的距离 $d$,然后计算果子相对其他蛇的距离,综合评估出最近的果子,这些果子评为“好果子”。选取“好果子”,作为目标进行寻路。当场上不存在“好果子”,都是“坏果子”时,那么我们就会自旋,或者随机游走,等待好果子的出现。

蛇蛇死亡来源于撞墙和其他蛇的碰撞,我们引入寻找果子时,需要远离其他蛇。假设其它蛇会尽可能地选取较近的目标,那么对于“好果子”的选取,就尽量选择距离“坏果子”最远的“好果子”。

此外,当存在碰撞风险时,即两蛇头部可选区域重合,我们将计算蛇头命中各自最小概率的格子进行选取,具体为统计所有蛇头到达此处的次数(假设每个格子的概率相同)。

死亡的另一种情况为困毙。为了避免这种情形,我们引入了外移惩罚。在选择移动方向时,蛇头会降低外移到边界的概率,因为大多数的困毙来源于走到角落。

编程对于上述策略的实现,我们采用了评价函数,量化决策的方向,根据计算得到的评价值,选择最优的方向。如果子的分数为$score = \sum{d_e} - d_{mine} \times k$,。其中$d_f$为果子到敌人蛇头的距离,$d_{mine}$为蛇头到自己的距离,$k$为调整系数。通过此来区分“好果子”和“坏果子”。

软件度量

→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。

图片

总结

→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。

4月1日 18.00

→ 📖 Q3.7(I) 请写下本部分的心得体会。

队友(ykq)伟大,无需多言。感谢队友为毫无头绪的我提出了大量贪吃蛇运行的启发式算法,使我们的蛇蛇获得了一定的博弈能力。

结对项目总结

结对过程回顾和反思

→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

图片

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
  • 我们在完成第三次作业时选择了碎片化时间进行编码,导致效率有所降低;
  • 我们对ts语言了解不深,很多ts语言特性了解不够深入。因此我们在编码过程中基本沿用C语言的编程习惯,代码可读性有待加强。
  • 编码时忍不住玩手机,导致浪费了一些时间。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。

优点:

  • 创意多,能够为第三次作业提出大量启发式算法;
  • 对待结对作业认真积极负责;
  • 编码能力强,代码中比较困难的部分基本都由我的队友负责。

缺点

  • 当领航员时忍不住玩手机(当然我也一样)。

对结对编程的理解

→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。

就个人体验而言,结队编程的优缺点如下:

  • 优点:
    • 代码质量有一定程度的保证;
    • 多人一起完成编码可以让编码过程不那么枯燥;
    • 多人集思广益,常常能集双人之所长,最终提高程序的性能、
  • 缺点:
    • 会带来一定程度上时间的浪费;

我认为,结队编程的方式适合那些对软件性能要求较高,任务量不大,单一重复工作较少的任务,这样可以最大程度上发挥结队编程”集思广益“的优点,兼顾开发效率和代码质量,同时减轻单人长时间编码可能带来的疲劳问题。

代码实现提交

→ 📖 Q4.5(P) 请提供你们完成代码实现的代码仓库链接。

mysterious-name/PairCompile: 个人所有结对编程作业

附录

附录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 合计
posted on 2025-04-06 08:53  Myst_name  阅读(22)  评论(0)    收藏  举报