作业要求: https://edu.cnblogs.com/campus/ustc/InnovatingLeadersClass/homework/2231
项目源码: https://github.com/jackroos/golden_number
本次作业我们是设计一个玩黄金点游戏的Bot,游戏的要求如下:
项目计划和实际实现
(我们没有设计这个PSP表格,但是回想当时的想法我大概估计了一下)
PSP阶段 | 预估用时(分钟) | 实际用时(分钟) |
---|---|---|
计划:明确需求,估计以下任务时间 | 20 | 20 |
需求分析 | 30 | 20 |
设计文档 | 30 | 50 |
设计复审 | 0 | 40 |
代码规范 | 5 | 5 |
具体设计 | 30 | 45 |
具体编码 | 300 | 360 |
代码复审 | 20 | 20 |
测试 | 60 | 60 |
测试报告 | - | - |
事后总结 | 120 | 120 |
总共用时 | 595 | 660 |
我们开始的想法太美好了,企图用强化学习一步到位,没有计划设计复审,然而训练出的效果并不好,所以到最后又花了大量时间重新设计和分析我们的bot.....,重新复审设计...
接口设计
算法的核心:
假设其他玩家提交数据的和上一轮黄金点强相关,统计各个玩家提交数据均值和上一轮黄金点的比例的概率分布,同时对于估计捣蛋的玩家(比例过大或过小),统计捣蛋值的平均数,通过上面的信息加权平均来获取每人下一轮最可能的提交值。
最终提交的版本是bot0.py,代码很简单。主要分为以下几个函数
函数名称 | 函数功能 |
---|---|
get_stat | 输入是历史数据 根据历史数据统计当前提交和上一轮黄金点的比例的概率分布,并计算捣乱值的平均数 输出 |
pred | 输入是概率分布和捣乱的平均值以及上一轮的黄金点,通过加权求和预测其他玩家下一轮的提交数的平均值输出 |
bot | 输入是标准输入中的历史数据,输出是预测的黄金点,前20轮采用简单测试,后面调用get_state和pred统计历史计算黄金点 |
三个函数的关系是:
入口是bot函数,bot中传入历史数据调用get_stat获取概率分布,得到的值传入pred预测他人提交,计算出我们的提交黄金点输出。
没有面向对象编程,函数逻辑也很简单,所以UML类图好像没有必要...
Design by Contract
契约式设计(英语:Design by Contract,缩写为 DbC),一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。
By Wiki
优点是:保证了函数各司其职,只处理规定好的满足前置条件的输入,保证输出等满足后验条件。同时也可以看成一种代码的规范和契约。
我们结对编程中,并没有显示的使用断言语句来进行这种契约式设计。只是简单规定了输入输出格式,没有用assert等检查,这也是我们之后要注意的点。
规范和异常处理
代码规范我们主要默认python的缩进是4个空格,大家都不取没有意义的名字等,并没有明确的约定别的规范。设计方面,保证函数各司其职,异常处理方面,主要是代码中一些可能除0的地方,我们简单的加上了0.001防止除0,别的没有进行什么异常处理。
界面
描述界面模块的详细设计过程。你的程序有用户界面么?在博客中详细介绍你如何设计你的界面模块。
描述界面模块与其他模块的对接。详细描述UI模块的设计与其他模块的对接,并在博客中截图实现的功能。
没有界面,此条不适用,因为已经给出了模拟复盘程序的UI,我们的程序也比较简单...
结对编程过程
项目一开始,我们进行了讨论,采用强化学习的策略,这时候需要大量的数据,因此我们的方案是写一些简单的Bot和一个模拟服务器的程序,来训练我们的Bot。但一方面我们自己设计的Bot太简单了,另一方面可能强化学习的状态和动作定义的不是很合适,学出来的Bot感觉在过拟合数据....此时时间已经很紧迫了,我们决定采用基于统计的简单策略Bot,ddl的前一晚完全推翻了之前的方法,两人重新来过。在项目的一开始,我们急于快点搞出来一个Bot,采用分工的方式,后来发现效果不好后,采用领航员和驾驶员的模式。发现的确有bug的时候对方都能实时指出,而且如果一方思路不明确的时候,另一方能及时提醒和梳理。
(照片忘记照了....gg)
我的优点:
- 比较善于找bug,有bug能及时提醒
- 比较及时的和队友沟通对项目的想法/策略
- 耐心的测试和复审
缺点:
对numpy这些不太熟悉,导致在这些点上有时候被队友带着走(队友非常确定没有bug,我就选择相信了他,然后最后测试的时候发现这个拷贝还是出问题了..)
队友的优点:
- 对numpy之类的非常熟悉
- 能很快的有思路,清整个项目的思路
- 对我不靠谱的想法也乐于倾听,分析哪里不对,改进之后采纳
缺点:
写代码有些粗心
其他收获
我们的项目在两轮里结果差异比较大...还是因此程序没有根据一些结果的反馈来挑战自己的策略,前提假设性较强,也不能实时的学习。同时,之后要注意好对时间的规划。