[P] 结对项目:影蛇舞

结对项目:博客问题清单

请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。

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

引入

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

2025.3.31 19:08

调查

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

I. 没有听说过;

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

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

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

II

总结

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

2025.3.31 19:25

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

结对过程

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

2025.3.31 19:26

→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
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. 题目给出的棋盘坐标从1到8,而我的代码中对应的下标为0到7,忘记在两者之间转化,从而导致数组越界。
  2. 没有妥善处理蛇头与蛇尾。应当将蛇尾标记为空位,因为该位置下一步一定是空气,蛇也可以朝着该方向前进。蛇头也应处理为空气,这与我的具体代码逻辑有关。

​ 通过了本地样例后进行进一步测试。通过测试后将项目代码commit到仓库中。

测试

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

​ 我们的测试不断自动生成新的合法的初始蛇状态和果子状态,并且将它传入greedy_snake_fn_checker函数,检测其输出是否大于等于0,即判断是否可以正常运行。

​ 测试用例的生成方式是随机数生成。先生成一个蛇头坐标,再基于这个坐标向四个方向不断前进,直至将四个坐标全部生成,只需要保证坐标之间不重合,且坐标没有超出棋盘范围,否则重新生成该坐标。果子坐标随机生成在空闲的棋盘中。

​ 对于本题不存在什么特殊测试样例需要考虑。

2025.3.31 20:50

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

单元测试是软件开发中的重要环节,通过测试代码的最小单元来确保其正确性和稳定性。它有助于早期发现错误,提高代码质量,简化调试过程,促进代码重构,并为持续集成和部署提供基础。单元测试是保证软件质量和开发效率的关键实践。

总结

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

2025年3月31日 20 : 50

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

要说任务难度,T1还是相当简单的,但陌生的语言带来了附加的压力,以至于相当大部分的时间消耗都是来自于语法纠错. 此外,也许是as还并没有迎来它的发展春天, 调试配置的信息极其稀少,T1中debug工作基本是依赖原始控制台输出,效率极低(而且怎么会有现代语言toString兼容都没做完善啊).后续开发一定不能在开发工具链上偷工减料, 稳定而高效的测试+debug方案是优良开发的基石.

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

结对过程

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

2025.3.31 20:50

→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
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相似度高,仅仅是引入了障碍物,所以直接基于T2代码进行了迭代开发.对于通常情况并没有出现问题,但我们考虑到不可达的判断问题中,盘起的蛇的身体可能会产生干扰干扰,为此我们将障碍与蛇身分别处理,进行了代码局部重构,解决了相应问题.

代码可复用性与需求变更

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

对于寻路逻辑基本完全复用, 主要添加了障碍物阻拦的判断,并在寻路失败时返回-1.为解决不可达判断的问题,将蛇身成环的情况特别处理.

→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些<u>设计思想</u>、考虑哪些<u>设计冗余</u>,来提高既存代码适应需求变更的能力。
  • 模块化, 一段实际应用代码一定是分成若干部分的,例如本任务需要初始化,寻路,方向决策几个部分. 编码时将各个部分的变量隔离,单独处理内部工作.

  • 不定长读取, 贪食蛇问题中题设给出了很多有具体长度的数据,如棋盘大小,蛇长,果子数,障碍数, 可以适当考虑这些长度变动的可能性. 整理这些长度参数并提取为宏统一管理,代码中可以部分考虑边长的情况.

头脑风暴环节

**→ 📖 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) 请写下本部分的心得体会。
  • 模块化管理是个好东西, T1坚持让搭档各模块分离编写, T2复用起来效率很高, 具体编码时间只有预估时间的四分之一左右

  • 测试, 随机测试覆盖能力是有限的, 对待设计出的蛇蛇要狠一点,多尝试刁钻的路线, 环蛇的特殊性就是在边缘测试中测出的

  • 编程基本工具要熟悉. 最初T1由于没有查到as语言调试的方法, 出现bug只能打print或者脑内模拟,十分痛苦. 后续沿用js风格基本实现了调试,整体测试效率提升很多.

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

结对过程

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

2025.4.2 14:30

→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
  1. 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
  2. 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
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) 请说明你们如何<u>建模</u>这一需求。

将每一轮决策视为三个可能的前进中方向中选一个(第二节身体的方向首先排除)。首先排除 不可选的方向,包括对手蛇的身体,自己的身体,墙面,再对剩下的选项进行打分评估(有选择余地的情况下): 需要选择能够尽可能多吃果子并远离障碍的方向。如果仍然存在因为分数相等而无法决策的情况,则根据特定顺序选择最终前进方向。

→ 📖 Q3.4(P) 请说明针对该任务,你们采取了<u>哪些策略</u>来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
  • 优先靠近果子: 移动方向下可达果子的距离的倒数为收益, 优先靠近果子多且近的位置,通过以前进方向为中心做广度优先遍历实现。

  • 优先远离对手: 移动方向下可达危险区域的距离倒数为惩罚,优先远离对手蛇多的区域,通过以前进方向为中心做广度优先遍历实现。

  • 远离墙面: 靠近墙面的位置会相应一定惩罚,减少墙边堵死的情形,具体体现为在分数上减去特定惩罚值,使得蛇蛇尽量不忘靠近墙的方向前进。

  • 利用round控制倾向: 随着轮数增加,死亡的损失会相应减小, 因此控制果子的"诱惑力"逐步增大, 增加终盘得分能力。通过果子奖励系数随round的动态变化实现。

  • 预测一步以内对手蛇的动向,远离潜在危险区域, 避免蛇头碰撞。代码上表现为将对手蛇蛇的可能前进位置设为“危险位置”。

软件度量

→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。
  • 我们的决策方案关键在于果子带来的"吸引力"与对手带来的"排斥力"之间的权衡, 具体表现程序中收益与惩罚系数. 我们使用不同系数的配置的蛇进行对决,统计胜率, 决定更优的参数配置

  • 定量分析方式: 固定轮数统计胜率, 最终得分, 死亡率等.

总结

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

2025.4.2 17:34

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

T3部分从简单可爱的单击小游戏一下上升到了凶残的多人竞争, 对于不善卷性能的我也是带来了巨大压力, 尽管最后也只是实现了一个简单版本的决策方案. 要说这一部分给我带来最大的感悟就是"取舍".我们队友之间最初花费了不少时间讨论各种复杂情况, 尝试找到那个大概根本不存在的最优寻路方案, 方案处在改变与被否的循环之中, 相当痛苦. 参考模型训练的思路, 我们试着将思路从寻找具体路径,转到更含糊的决策倾向上, 这一下打开了我们的思路, 才有了现在的设计.

结对项目总结

结对过程回顾和反思

→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。
→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
  • 代码管理, 最初直接fork了仓库,不能改隐私设置,导致代码共享有限,更多以两人看一屏的方式讨论,效率比较低, 应该直接开新仓库复制作业项目

  • 语言选择, 在这方面并没有过多调研就选择了推荐的as语言, 但两人实际都没有写过,所以编码过程持续的遭遇着语言相关工具不熟悉的问题,一定程度上影响了后续作业的发挥

→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
  • 优点

    关注细节,能快速指出我代码中的细节问题(错字,拼写,名称复用等)

    有耐心, 能够认真听完我跳脱的脑回路下产生的诡异点子, 并给出评价或建议

    行动力强, 督促我推动任务进度, 没有当ddl战士

  • 缺点

    代码编写效率较低,提效的编程工具使用较少

对结对编程的理解

→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
  • 结队编程一方面确实对于个人代码习惯带来了很大改善, 毕竟代码还要向另一人解释, 规范性与逻辑性都会下意识的优化一下; 但另一方面, 一边讨论一边编程对于开发效率确实影响极大,需要一边解释一边写, 很破坏开发体验.
    uploading-image-26966.png

  • 我认为结队编程可能算是个很好的提高自我的渠道, 与另一个不同的人深入的交流思考过程, 在编码思路上能带来很多意想不到的启发, 这我深有感受. 队友想出的一些边缘情况能够快速指出我想法的漏洞, 由于思维惯性很多时候我自己并不能注意到, 最后产出的代码bug率也大大下降了.

    同时我也认为, 结队编程是不适合应用到现实开发工作中的(叠甲: 通常情况下). 一方面是开发效率的极度低下, 不断的沟通会打断编码的思路, 让两个人都处于一种不能全身心专注的状态. 另一方面是开发中决断力的下降, 对于一些细小问题, 可能由于两人习惯的差异会带来不必要的决策成本.

代码实现提交

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

PairProgramming - Shadow of Dancing Snakesuploading-image-834835.png

posted @ 2025-04-03 14:43  sevspoons  阅读(53)  评论(0)    收藏  举报