1.相关链接和地址
2.具体分工
我负责本次作业的AI部分,写出牌的算法,我的队友负责UI部分功能实现。
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20(sum) | 20(sum) |
·Estimate | ·估计这个任务需要多少时间 | 20 | 20 |
Development | 开发 | 790(sum) | 1200(sum) |
·Analysis | ·需求分析 (包括学习新技术) | 180 | 200 |
·Design Spec | ·生成设计文档 | 70 | 90 |
·Design Review | ·设计复审 | 30 | 30 |
·Coding Standard | ·代码规范 | 30 | 60 |
·Design | ·具体设计 | 60 | 80 |
·Coding | ·具体编码 | 200 | 280 |
·Code Review | ·代码复审 | 40 | 60 |
·Test | ·测试 | 180 | 400 |
Reporting | 报告 | 130(sum) | 170(sum) |
·Test Repor | ·测试报告 | 40 | 60 |
·Test Repor | ·计算工作量 | 30 | 30 |
·Postmortem & Process Improvement Plan | ·事后总结, 并提出过程改进计划 | 60 | 80 |
· 合计 | 940 | 1390 |
4.解题思路描述与设计实现说明
- 网络接口的使用
- 通过使用pyhthon中的request库中的requests.post(url,json,headers)和requests.get(url,json,headers)函数来使用接口
- 代码组织与内部实现设计
- 说明算法的关键与关键实现部分流程图
- 算法的关键在于把十三张牌全组合,分成5,5,3三墩,给每个不同的牌型赋权值,同时记录假设当前牌全胜赢得水数,水数大的牌优先值高,其次是权值大的牌。组合用到了itertools库的combinations函数。流程图如下。
5.关键代码解释
poker = poker.split(' ') change1 = {'$': 1, '&': 2, '*': 3, '#': 4} change2 = ['', '$', '&', '*', '#'] newpoker = [] for x in poker: num = change1[x[0]] if x[1] == 'A': num += 14 * 10 elif x[1] == 'J': num += 11 * 10 elif x[1] == 'Q': num += 12 * 10 elif x[1] == 'K': num += 13 * 10 else: num += int(x[1:]) * 10 newpoker.append(num) newpoker.sort() for TOP in combinations(newpoker, 3): tmp = list(newpoker[:]) for i in range(3): tmp.remove(TOP[i]) for MID in combinations(tmp, 5): BOT = list(tmp[:]) for j in range(5): BOT.remove(MID[j])
这一段代码是处理拿到的十三张牌,首先用一个split函数将十三张牌分开,每张牌是一个字符串,然后把黑红梅方四种花色转化为个位数,牌的大小乘十,再加起来,这样就可以把牌转化为纯粹的数字,方便之后的处理。拿到处理过的牌后,将其排序,然后通过combinations函数进行组合,每次选出牌后,将已经选出来的牌从原来的牌集中去掉,再重复一次上述操作,最终可遍历所有牌型。
6.性能分析与改进
- 改进思路
- 因为本次从十三张牌中按5,5,3分墩,其实就是一个组合的问题,最开始我的组合是自己手写的,速度比较慢,之后我从网上查到python有求组合的函数,用了之后速度提升不少。还有排序问题,最初我是分完墩后,把每墩再分别排序,改进之后是我直接在分墩前就把牌排好序,根据combinations函数特性,得到的每墩顺序是已经排好的,省了每次每墩排序的时间。
- 性能分析图和消耗最大的函数
def Play(ID,Token,poker): # 个位数为1是黑桃,2是红桃,3是梅花,4是方块 poker = poker.split(' ') change1 = {'$': 1, '&': 2, '*': 3, '#': 4} change2 = ['', '$', '&', '*', '#'] newpoker = [] for x in poker: num = change1[x[0]] if x[1] == 'A': num += 14 * 10 elif x[1] == 'J': num += 11 * 10 elif x[1] == 'Q': num += 12 * 10 elif x[1] == 'K': num += 13 * 10 else: num += int(x[1:]) * 10 newpoker.append(num) newpoker.sort() save = [] MAX = 0 #记录最优且最理想情况全赢能获得多少水 Mscore1 = 0 #记录目前最优底墩权值分数 Mscore2 = 0 #中墩 Mscore3 = 0 #顶墩 SUM=0 for TOP in combinations(newpoker, 3): tmp = list(newpoker[:]) for i in range(3): tmp.remove(TOP[i]) for MID in combinations(tmp, 5): BOT = list(tmp[:]) for j in range(5): BOT.remove(MID[j]) score1 = 0 # 底部 val1 = 1 score2 = 0 # 钟部 val2 = 1 score3 = 0 # 顶部 val3 = 1 if Tonghuashun(BOT): score1 = 512 val1 = 5 elif Zhadan(BOT): score1 = 256 val = 4 elif Hulu(BOT): score1 = 128 elif Tonghua(BOT): score1 = 64 elif Shunzi(BOT): score1 = 32 elif Santiao(BOT, 5): score1 = 16 elif Liandui(BOT): score1 = 8 elif Erdui(BOT): score1 = 4 elif Yidui(BOT, 5): score1 = 2 else: score1 = 1 if Tonghuashun(MID): score2 = 512 val2 = 10 elif Zhadan(MID): score2 = 256 val2 = 8 elif Hulu(MID): score2 = 128 val2 = 2 elif Tonghua(MID): score2 = 64 elif Shunzi(MID): score2 = 32 elif Santiao(MID, 5): score2 = 16 elif Liandui(MID): score2 = 8 elif Erdui(MID): score2 = 4 elif Yidui(MID, 5): score2 = 2 else: score2 = 1 if Santiao(TOP, 3): score3 = 16 elif Yidui(TOP, 3): score3 = 2 else: score3 = 1 if score1 >= score2 and score2 >= score3 and (val1 + val2 + val3 > MAX or (val1 + val2 + val3 == MAX and score1+score2+score3 >= SUM and score1>score2 and score2>score3) ): save = [] temp = '' pai = '' for i in range(3): temp += change2[TOP[i] % 10] pai= str(TOP[i] // 10) if(pai=='11'): pai='J' elif(pai=='12'): pai='Q' elif(pai=='13'): pai='K' elif(pai=='14'): pai='A' temp+=pai if i != 2: temp += ' ' save.append(temp) temp = "" for i in range(5): temp += change2[MID[i] % 10] pai = str(MID[i] // 10) if(pai=='11'): pai='J' elif(pai=='12'): pai='Q' elif(pai=='13'): pai='K' elif(pai=='14'): pai='A' temp+=pai if i != 4: temp += ' ' save.append(temp) temp = "" for i in range(5): temp += change2[BOT[i] % 10] pai = str(BOT[i] // 10) if(pai=='11'): pai='J' elif(pai=='12'): pai='Q' elif(pai=='13'): pai='K' elif(pai=='14'): pai='A' temp+=pai if i != 4: temp += ' ' save.append(temp) MAX = val1 + val2 + val3 SUM=score1+score2+score3 Mscore1 = score1 Mscore2 = score2 Mscore3 = score3 header={ 'content-type':'application/json', 'x-auth-token':str(Token) } data={ 'id':int(ID), 'card':save } print(save) response=requests.post('http://api.revth.com/game/submit',json=data,headers=header) return response.json()
7.单元测试
测试的就是上述的Play函数,测试数据是调用api获得
拿到的牌 '&5 #3 $8 #Q *6 #5 #9 $Q #8 $5 #J #6 *10' '&Q $6 $J #J *4 $K $2 #Q *9 *K #6 #4 #9' '#J *7 *Q &10 #5 #8 &K &9 *A #2 #3 $7 &J' '$9 *2 &5 &A *6 $3 *A &8 &6 #7 &10 &K *K' '*7 *4 #6 &8 $8 $10 *5 $2 #9 #2 *3 #A *J'
打出去的牌 ['$8 *10 $Q', '#3 #8 #9 #J #Q', '$5 &5 #5 *6 #6'] ['*9 $J &Q', '$2 *4 $6 $K *K', '#4 #6 #9 #J #Q'] ['$7 *7 *A', '&9 &10 &J *Q &K', '#2 #3 #5 #8 #J'] ['$9 *K *A', '*2 $3 &6 *6 #7', '&5 &8 &10 &K &A'] ['#9 $10 #A', '$2 #2 #6 $8 &8', '*3 *4 *5 *7 *J']
8.Github的代码签入记录
9.遇到的代码模块异常或结对困难及解决方法
- 问题描述
- 最开始使用requests库中的request和get函数一直显示失败,并且不知道为什么会出错
- 做过哪些尝试
- 最开始我检查url是否填写正确,然后去网上搜索request库中的request和get详细用法,后来发现我在传参数的时候,参数格式错误,最后改成正确的
- 是否解决
- 是
- 有何收获
- 之前没有接触过网络接口这方面的知识,这一次亲自写了程序利用网络接口来获取信息,对网络接口这方面的知识有了更深的了解
10.评价你的队友
- 值得学习的地方
- 我的队友非常努力,他是负责前端的内容,我知道他的工作量应该比我大,而且每天都有在学习新的内容。他善于为队友考虑,他已经把一些数据处理好,我就少了一些工作量
- 需要改进的地方
- 希望他和我可以更多的沟通,这次作业因为前端和后端用的语言不一样,导致连起来有些困难,有一些原因我觉得可能是沟通有点少,不过这方面我也需要改进。
11.学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 3 | 3 | 对原型设计工具有一个初步了解 |
2 | 200 | 200 | 5 | 8 | 学习有关网络接口方面内容 |
3 | 350 | 550 | 5 | 13 | 尝试初步写十三水的算法 |
4 | 200 | 750 | 6 | 19 | 改进代码,改进算法 |