一、相关链接
二、具体分工
郑志强:后端(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.assertNotEqual(ret['status'], 2003)
if __name__ == '__main__':
unittest.main()
主要测试的函数是对三墩牌是否合理做出判断。
构造思路:通过无限从服务器获取牌然后再打牌,查看返回的值是否是2003,如果是,则说明函数出现错误。
八、代码签入记录
九、遇到的代码模块异常或结对困难及解决方法
(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 |