现代软件工程第二周作业——黄金点游戏

(本博文为现代软件工程第二周作业——黄金点游戏结对编程总结,本项目的Github源码在这里)

黄金点游戏介绍

假设有M个人参与黄金点游戏,每轮游戏每个人提两个(0, 100)间的有理数,共2M个数,求这2M个数的平均数再将这个平均数乘以0.618得到这一轮的黄金点,提出离黄金点最近的数的人得2M分(同样近的人一起得分),离黄金点最远的人扣两分。

在本次实验中,我们需要写一个bot来在每轮游戏中自动提出两个数,每次游戏前,bot能拿到之前所有轮次游戏的每个人提的两个数和黄金点,每场游戏共进行400轮,共有上半场和下半场两场游戏,累计得分最高的bot获胜。

我们的策略

我们的策略十分简单,第一,我们不会需要去预测别人提的数,所以游戏进行时我们只用黄金点的值来提出下一轮的结果,并没有用其他人提的数这一个信息。第二,我们是基于统计的方法,统计该次游戏的前50轮游戏出现最多的2个黄金点作为我们的输出,具体做法如下。

  • 对于前20轮游戏,采用拟合函数的策略预测前20轮的实验结果。
  • 对于之后的游戏,用一个有序列表pred_golden记录待预测的黄金点,用一个长度为50的队列que_cnt统计每次黄金点落到待预测的黄金点的附近对应的待预测黄金点在pred_golden里的下标,将最开始的前20轮游戏的黄金点都认为是待预测的黄金点,之后每一次游戏的黄金点若在任意两个待预测的黄金点中间的1/3区间,则插入为新的待预测黄金点,若在该两个待预测黄金点的其他的两个1/3区间,则离这次黄金点近的待预测的黄金点的下标记录到que_cnt中,并用这次的黄金点对对应的待预测的黄金点做一次滑动平均。如此进行下去,直到history的最后一轮。
  • 利用que_cnt的值选出出现最多的两个下标对应的黄金点作为我们的输出。

我们利用这一个方案在夏令营的复盘程序中拿了第一,第三(上半场,下半场)的名次,但在我们的比赛时拿了第四,第八(上半场,下半场)的名次,我看了我们比赛时黄金点的波动情况,比夏令营的复杂的多,可能因为我们的参数bot数目比较少的原因吧!

作业要求

2.在开始实现之前,用PSP表格记录下你预估完成项目需要的时间。

项目一开始,我们先讨论了我们的方案,最终讨论出这个方案后。因为我们的算法比较简单,具体实现起来也就100行左右的代码量,我们花了1个小时左右的时间就写完了,在夏令营的数据内复盘时我们又发现了我们的方案里的一些弊端,比如我们一开始是基于之前所有轮次的统计,但这样的话如果其他人在中间改变策略我们的方法可能反应不过来,讨论过后我们决定改进成基于前50轮的统计。就这样,我们在一边复盘发现问题,一边讨论改进我们的方案的循环过程中完成了我们的结对编程的作业,总共花时一个晚上左右的时间,但我们并没有明确的PSP表格。

3.看教科书和其他资料中关于Information Hiding, Interface Design, Loose Coupling的章节,说明你们在结对编程中是如何利用这些方法对接口进行设计的。

编程开始前,我们讨论由我来用一个函数来实现对待预测黄金点列表的插入与更新,并在函数内维护前50轮黄金点的统计列表,返回插入和更新后的待预测黄金点列表和近50轮的统计队列。另一位同学负责主函数来使用这个函数进行游戏的输入和输出,并负责前20轮游戏的策略。

4.描述重要模块接口的设计与实现过程。设计包括代码如何组织,比如会有几个类、几个函数,他们之间的关系是如何的,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。

我们主要就一个main函数和一个更新待预测黄金点列表函数[update]函数,主要就是mian函数调用update函数,所以也不需要流程图。我们的方法关键之处在于我们的待预测黄金点列表能够自适应黄金点的变化,如果黄金点波动十分小,收敛的很好,我们两个值的预测也会十分接近这个黄金点。如果黄金点在两个点之间波动,我们也能成功预测到这两个波动的峰值的位置,从而在这两个峰值间冲击黄金点。

5.阅读有关UML的内容。画出UML图显示计算模块部分各个实体之间的关系(一个图即可)。

因为我们的方法里并没有类,并没有采用面向对象编程,我们都是基于面向过程的方法,所以这并不适用我们的方案。

6.看Design by Contract的内容,描述这些做法的优缺点,说明你如何把它们融入结对作业中。

  • 优缺点
    • 优点:每个类有自己的明确义务,有确定的功能,保证良好的接口,而且功能模块化的话更有利于代码的复用和管理。
    • 缺点:时间开销较大,需要大量的时间实践才能真正体会到契约式设计的好处。
  • 我们这次任务实现比较简单,接口也比较简单,实践时并没有采用这种设计方式。

7.程序的代码规范、设计规范。你们俩如何达成共识、采用什么规范?程序中是否有异常处理?你如何处理各种异常?

代码规范的话我们在实现时并没强制要求,主要是在容易混淆的地方加注释就行了,保证代码的可读性。程序并没有出现异常,但在夏令营数据复盘时发现过方案的弊端,经过讨论后改进了我们的方案。

8.描述界面模块的详细设计过程。你的程序有用户界面么?在博客中详细介绍你如何设计你的界面模块。

我们并没有用户界面,所以这并不适用我们。

9.描述界面模块与其他模块的对接。详细描述UI模块的设计与其他模块的对接,并在博客中截图实现的功能。界面/控制/数据模块体现了MVC的设计模式了么?

理由同上

10.描述结对的过程。提供两人在讨论的结对照片。遮挡和美化都是允许的。

11.看教科书和其他参考资料中关于结对编程的章节,说明你们采用了哪种合作方式,以及结对编程的优点和缺点。a) 结对的每个人的优缺点在哪里(需列出至少三个优点和一个缺点)?b) 你如何说服你的伙伴改进他/她的缺点?请考虑一下三明治方法。

  • 我们这次结对过程中采取的是驾驶员与领航员的合作方式,通过指导和监督的方式完成了这次的实验。这次实验中,我的另一个伙伴指导并监督我进行编程,在复盘时出现问题后我们又接着讨论又进一步改善我们的方案。
  • 结对编程的优缺点:优点在于合作编程时我们都会有自己的想法,和别人交流自己的想法可以引发思维上的碰撞,从而得到更好的解决方案,另外与人合作可以提高我们双方的积极性,而且有助于我们写出更优质的代码。
  • 我的合作伙伴Jinhua Zhu在讨论时很有想法,而且很擅长与人交流,善于表达自己的想法,思维十分敏捷,能快速看到问题并想到解决方案,和他合作真的太愉快了!!

12.在你实现完程序后,请在PSP表格中记录下你在开发各个步骤上实际花费的时间。说明差异的原因。

我们并没有采用PSP表格记录各个步骤的时间,但相比于编程的时间,我们的大部分时间都发在方案的讨论和改进上,在实验时发现原始方案的不足,不断讨论不断改进方案,最终得到我们的最终版本的bot。

13.其他收获。例如,如何攻克技术难点,你做了哪些阅读和探索,可以把资料和经历描述一下。如果你的项目是和其他同学一起比赛(例如比赛速度),描述一下你的程序和其他程序的优劣。

我们小组的方案是基于统计的方法,实验结果应该可以达到一个比较中庸的分数,但我想所有基于统计的方案都有的一个弊端,就是对环境变化反应的很慢,如果黄金点变化收敛到另一个值,那么按我们的方法,我们可能要20轮左右的时间才能反应过来,这是我们的方案的最大的弊端。我们也尝试了许多方案来解决这个弊端,比如减小que_cnt的最大队列长度,但统计的轮次太小会导致统计结果无意义,最后我们也并没有完全解决这个问题,只能稍稍缓和了这个问题。

猜你喜欢

转载自www.cnblogs.com/kaihu/p/9825395.html