一、相关链接
二、具体分工
郑志强:后端(AI)
叶泽林:前端(UI)
##没错,不用怀疑,就是这么简单
三、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 1200 | 1800 |
Development | 开发 | 800 | 800 |
Analysis | 需求分析 (包括学习新技术) | 900 | 1000 |
Design Spec | 生成设计文档 | 10 | 5 |
Design Review | 设计复审 | 10 | 5 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 0 |
Design | 具体设计 | 400 | 400 |
Coding | 具体编码 | 60 | 100 |
Code Review | 代码复审 | - | - |
Test | 测试(自我测试,修改代码,提交修改) | 100 | 100 |
Reporting | 报告 | 10 | 10 |
Test Repor | 测试报告 | 10 | 10 |
Size Measurement | 计算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | - | - |
- | 合计 | 1200 | 1860 |
四、解题思路描述与设计实现说明
(1)网络接口的使用
用requests模板提供的get、post方法获取信息,这里以注册绑定为例
username = input() password = input() print("请绑定学号+密码:") student_number = input() student_password = input() url = "http://api.revth.com/auth/register2" headers = {"content-type": "application/json"} formdata = { "username": username, "password": password, "student_number": student_number, "student_password": student_password } response = requests.post(url,data=json.dumps(formdata),headers=headers,verify=False) print("注册情况:" + response.text)
(2)代码组织与内部实现设计(类图)
变量名称 | 变量含义 |
---|---|
wholePoker1, wholePoker2, wholePoker3 | 分堆的牌 |
currentBottomPoker, currentMiddlePoker, currentTopPoker | 最终的牌 |
bottomPoker, middlePoker, topPoker, lastPoker | 用于分堆的牌 |
currentscore1, currentscore2, currentscore3 | 最终答案 |
score1, score2, score3 | 结果牌的大小分数 |
currentscore1, currentscore2, currentscore3 | 当前牌的大小分数 |
shui1, shui2, shui3 | 保存最终设定赢的水数 |
只有一个类,方法关系如下
(3)说明算法关键与关键实现部分流程图
算法其实很简单,就是获取手牌后排序,然后从13张牌中选出5张,再从8张中选出5张,通过计算各墩大小来判断牌型是否合理,如果合理再赋予一定的权值来选定最后的牌。另外需要说明的就是特殊牌我们不用判断!!!
流程图如下
五、关键代码解释
当初构想的时候觉得判断这些牌型和大小比较应该会挺麻烦的,但是机智的我引入了数组完美解决了牌型判断和大小比较,我觉得这个方法很赞!代码如下
def typeOfPokerCard(x): """先处理同花顺,顺子和同花""" a = [] flag1, flag2 = 1, 1 for i in range(0, 4): a.append(x[i].number) if x[i].number != x[i+1].number-1: flag1 = 0 if x[i].color != x[i+1].color: flag2 = 0 a.append(x[4].number) if flag1 and flag2: score = 9+(a[4]/100)+(a[3]/100000)+(a[2]/10000000)+(a[1]/1000000000)+(a[0]/100000000000) return score elif flag1: score = 5+(a[4]/100)+(a[3]/100000)+(a[2]/10000000)+(a[1]/1000000000)+(a[0]/100000000000) return score elif flag2: score = 6+(a[4]/100)+(a[3]/100000)+(a[2]/10000000)+(a[1]/1000000000)+(a[0]/100000000000) return score '''炸弹情况''' if (a[0] == a[1] or a[3] == a[4]) and a[1] == a[2] and a[2] == a[3]: score = 8+((4*a[2])/100) return score '''葫芦情况''' if (a[0] == a[1] and a[1] == a[2] and a[3] == a[4]) or (a[0] == a[1] and a[2] == a[3] and a[3] == a[4]): score = 7+((3*a[2])/100) return score '''三条情况''' if a[0] == a[1] and a[1] == a[2] or a[1] == a[2] and a[2] == a[3] or a[2] == a[3] and a[3] == a[4]: score = 4+((3*a[2])/100) return score '''二对情况''' if (a[0] == a[1] and a[2] == a[3]) or (a[1] == a[2] and a[3] == a[4]) or (a[0] == a[1] and a[3] == a[4]): if a[3] == a[1] + 1: score = 3+((2*a[3])/100)+((2*a[1])/100)+0.15 else: score = 3+((2*a[3])/100)+((2*a[1])/100000) return score '''对子情况''' if a[0] == a[1]: score = 2+((2*a[0])/100)+(a[4]/100000)+(a[3]/10000000)+(a[2]/1000000000) return score elif a[1] == a[2]: score = 2+((2*a[1])/100)+(a[4]/100000)+(a[3]/10000000)+(a[0]/1000000000) return score elif a[2] == a[3]: score = 2+((2*a[2])/100)+(a[4]/100000)+(a[1]/10000000)+(a[0]/1000000000) return score elif a[3] == a[4]: score = 2+((2*a[3])/100)+(a[2]/100000)+(a[1]/10000000)+(a[0]/1000000000) return score '''散牌情况''' score = 1+(a[4]/100)+(a[3]/100000)+(a[2]/10000000)+(a[1]/1000000000)+(a[0]/100000000000) return score
六、性能分析与改进
不出所料的是requests模块占用了大量的时间,而选牌所占时间仅有百分五,故改进的办法就是众筹,改善服务器(滑稽)
其实一开始并没有这么简洁,刚写时候的递归是全排列方式,后来发现这方法重复的有点多就改成组合方式。而且对于特殊牌我从一开始就认为不用判断,按正常牌打出即可,所以这个地方省了挺多时间的
除去那些请求和其他必要的消耗时间,最大的函数消耗是检测是否是“最好”的牌,代码如下
def checkBestPoker(): global currentscore1, currentscore2, currentscore3 """计算头墩, 规则里面没说头墩有其他情况,当然选择不做其他判断!!。""" currentscore1 = getTopScore() '''计算中墩''' currentscore2 = getMiddleScore() '''计算底墩,只需在中墩基础上修改数值即可''' currentscore3 = getBottomScore() if currentscore1 <= currentscore2 <= currentscore3: ret = 0 global shui1, shui2, shui3, score1, score2, score3, currentshui1, currentshui2, currentshui3 global middlePoker, bottomPoker, topPoker, currentTopPoker, currentMiddlePoker, currentBottomPoker if currentshui1+currentshui2+currentshui3 > shui1+shui2+shui3: shui1 = currentshui1 shui2 = currentshui2 shui3 = currentshui3 for i in range(0, 5): middlePoker[i] = currentMiddlePoker[i] bottomPoker[i] = currentBottomPoker[i] for i in range(0, 3): topPoker[i] = currentTopPoker[i]
七、单元测试
class pokerTest(unittest.TestCase): def testTypeOfPoker(self): global wholePoker1 login() i = 10 while(i): initAll() wholePoker1 = startGame() wholePoker1.sort(key=getnumber) getPokerCardOne(0, 0) lastPoker = [] lastPoker = printPoker() resp = submitGame(lastPoker) i -= 1 ret = resp.json() self.assertEqual(ret['status'], 0) if __name__ == '__main__': unittest.main()
主要测试的函数是对三墩牌是否合理做出判断。
构造思路:通过无限从服务器获取牌然后再打牌,查看返回的值是否是2006,如果是,则说明函数出现错误。
八、代码签入记录
九、遇到的代码模块异常或结对困难及解决方法
(1)前端
- 问题描述:对前端的掌握度不够,对于http协议不了解,对于前端软件及语法规范不清楚。
- 做过的尝试:首先当然是百度,寻找合适的软件,再来就是看视频教程以及百度上的教程,如果遇到问题,首先当然还是百度,不行的话就请教他人了。
- 是否解决:虽然可能还有不足,但基本上满足需求了。
- 有何收获:进一步了解了HTTP协议的post与get等方法,大致了解了UI界面的制作流程。
(2)后端
- 问题描述:对接口调用没有概念,不会用
- 做过哪些尝试:不会就百度
- 是否解决:是的
- 有何收获:大致了解request模板的post,get用法
十、评价你的队友
- 值得学习的地方:很强,知识面很广,动手能力强。
- 需要改进的地方:太爱装逼。
十一、学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 3 | 3 | 学会用Axure做原型设计 |
2 | 400 | 400 | 12 | 15 | 学习python的使用和写出程序框架 |
3 | 300 | 700 | 12 | 27 | 学习python,以及学习http协议 |
4 | 500 | 1200 | 9 | 36 | 加深python的学习,学习http协议,以及学习pyqt5 |