1.结对同学博客链接
2.具体分工
- 明镇:AI代码
- 志荣:UI代码
- 共同完成:博客撰写
3.PSP表格
PSP2.1 | PersonalSoftware Process Stages | 预估耗时(分钟 | 实际耗时(分钟 |
---|---|---|---|
Planning | . 计划 | 30 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 1380 | 2540 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 240 |
· Design Spec | · 生成设计文档 | 60 | 400 |
· Design Review | · 设计复审 | 100 | 100 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
· Design | · 具体设计 | 150 | 300 |
· Coding | · 具体编码 | 800 | 1200 |
· Code Review | · 代码复审 | 60 | 120 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 120 |
Reporting | 报告 | 100 | 100 |
· Test Repor | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 60 |
· 合计 | 1510 | 2670 |
4.解题思路描述与设计实现说明
- 网络接口的使用
import re import requests url = "https://api.shisanshui.rtxux.xyz/auth/login" headers = { 'content-type': 'application/json' } payload = "{\"username\":\"shisan\",\"password\":\"123456\"}" response = requests.request("POST", url, data=payload, headers=headers) print(response.text) aaa = str(response.text) print(aaa) p = re.compile(r'token":"(.+?)"') token = p.findall(aaa)[0] header = { "x-auth-token": token } print(token) def openn(header): url = 'https://api.shisanshui.rtxux.xyz/game/open' header = str(header) headers = {'x-auth-token': header} data = {} response = requests.request("POST", url, headers=headers) return response tok = openn(token) tok1 = str(tok.text) p1 = re.compile(r'card":"(.+?)"') str0 = p1.findall(tok1)[0] print("receive origin card:", end=' ') print(str0) p2 = re.compile(r'id":(.+?),') idd = p2.findall(tok1)[0] print("number of game:", end=' ') print(idd) def submit(idd,listt): url = "https://api.shisanshui.rtxux.xyz/game/submit" headers = { 'content-type': "application/json", 'x-auth-token': token } payload = "{\"id\":" payload = payload + str(idd) payload = payload + ",\"card\":[\"" if len(listt) == 1: payload = payload + str(listt[0]) else: payload = payload + str(listt[0]) payload = payload + "\",\"" payload = payload + str(listt[1]) payload = payload + "\",\"" payload = payload + str(listt[2]) payload = payload + "\"]}" response = requests.request("POST", url, data=payload, headers=headers) print(response.text)
代码组织与内部实现设计(类图)
说明算法的关键与关键实现部分流程图
(1)算法关键:首先判断特殊牌型,如果不是特殊牌型,则采用组合数算法:先从13张牌中选出5张,再从8张中选出5张,还剩下3张作为前墩,给每一墩及每一种牌型赋予一定的分值,遍历每一种情况选出得分最高的一种作为最后的结果。
(2)流程图:
graph TB; 判断牌型-->|特殊牌型|结束; 判断牌型-->|普通牌型|比较i与m12大小; 比较i与m12大小-->|等于|结束; 比较i与m12大小-->|小于|13张牌随机抽取5张并计算cout1; 13张牌随机抽取5张并计算cout1-->|抽牌|剩余8张牌随机抽取5张并计算cout2; 剩余8张牌随机抽取5张并计算cout2-->|抽牌|最后3张牌作为前墩并计算cout3; 最后3张牌作为前墩并计算cout3-->|比较|cout1+cout2+cout3与ma做比较; cout1+cout2+cout3与max做比较-->|大于|ma=cout1+cout2+cout3并记录3墩; ma=cout1+cout2+cout3并记录3墩-->|返回|13张牌随机抽取5张并计算cout1;
5.关键代码解释
def comb(a, n5): m1 = creat(13) m11 = list(combinations(m1, 5)) m12 = len(m11) m2 = creat(8) m21 = list(combinations(m2, 5)) m22 = len(m21) lss4 = [] lss5 = [] lss6 = [[], [], []] lss7 = [] lss8 = [] lt1=[] lt2=[] lt3=['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] lt4=[] w1=1 r2=1 cout1 = 0 cout2 = 0 cout3 = 0 ma = -10 for i in range(m12): # 后墩 n6 = n5.copy() lss4.clear() for j in range(5): lss4.append(n5[m11[i][j]]) t = n6.index(n5[m11[i][j]]) del n6[t] if tonghuas(5, lss4): cout1 = 5 elif samee(4, 5, lss4) == 1: cout1 = 4 elif samee(3, 5, lss4) == 1 and samee(2, 5, lss4) == 1: cout1 = 3 elif huase(5, lss4): cout1 = 2 elif dians(5, lss4): cout1 = 1 elif samee(3, 5, lss4) == 1: cout1 = -1 elif samee(2, 5, lss4) == 2: cout1 = -2 elif samee(2, 5, lss4) == 1: cout1 = -4 else: cout1 = -5 for k in range(m22): # 中墩 n7 = n6.copy() lss5.clear() for p in range(5): lss5.append(n6[m21[k][p]]) t = n7.index(n6[m21[k][p]]) del n7[t] lss8 = n7.copy() if tonghuas(5, lss5): cout2 = 8 elif samee(4, 5, lss5) == 1: cout2 = 7 elif samee(3, 5, lss5) == 1 and samee(2, 5, lss5) == 1: cout2 = 6 elif huase(5, lss5): cout2 = 5 elif dians(5, lss5): cout2 = 4 elif samee(3, 5, lss5) == 1: cout2 = 2 elif samee(2, 5, lss5) == 2: cout2 = 1 elif samee(2, 5, lss5) == 1: cout2 = -1 else: cout2 = -2 if tonghuas(3, lss8): # 前墩 cout3 = 11 elif samee(4, 3, lss8) == 1: cout3 = 10 elif samee(3, 3, lss8) == 1 and samee(2, 3, lss8) == 1: cout3 = 9 elif huase(3, lss8): cout3 = 8 elif dians(3, lss8): cout3 = 7 elif samee(3, 3, lss8) == 1: cout3 = 5 elif samee(2, 3, lss8) == 2: cout3 = 4 elif samee(2, 3, lss8) == 1: cout3 = 2 else: cout3 = 1 if cout1 == 5 and cout2 == 8 and cout3 == 11: #print("三同花顺牌") return lss7 if cout1 == 1 and cout2 == 4 and cout3 == 7: #print("三顺子") return lss7 if cout1 + cout2 + cout3 > ma: if cout1 >= cout2 - 3 and cout2 >= cout3 - 3: ma = cout1 + cout2 + cout3 lss6[0] = lss4.copy() lss6[1] = lss5.copy() lss6[2] = n7.copy() if cout1 == cout2 - 3: #避免相同牌型下出现相公 for u in range(5): a = lt3.index(lss6[0][u].num) lt1.append(a) b = lt3.index(lss6[1][u].num) lt2.append(b) lt1.sort(reverse=True) lt2.sort(reverse=True) for w in range(2): if lt1[w] == lt1[w + 1] and lt1[w + 2] == lt1[w + 3]: if lt1[w + 1] == lt1[w + 2] + 1: w1=2 break for r in range(2): if lt2[r] == lt2[r + 1] and lt2[r + 2] == lt2[r + 3]: if lt2[r + 1] == lt2[r + 2] + 1: r2 = 2 break if r2 > w1: lt4 = lss6[0] lss6[0] = lss6[1] lss6[1] = lt4 elif r2 == w1: for m in range(5): if lt2[m] > lt1[m]: lt4 = lss6[0] lss6[0] = lss6[1] lss6[1] = lt4 break lt1.clear() lt2.clear() return lss6
- 这是我实现分墩的代码,采用组合数算法:先从13张牌中选出5张,再从8张中选出5张,还剩下3张作为前墩,给每一墩及每一种牌型赋予一定的分值,遍历每一种情况选出得分最高的一种作为最后的结果,其中lss6[0]记录后墩,lss6[1]记录中墩,lss6[2]记录前墩,记录的内容是qipqi()的对象
6.性能分析与改进
改进:刚开始没有头绪就想着用贪心来写,后来同学给提示说用组合数算法,就改用了组合数算法
7.单元测试
huase(),dians(),samee()函数的测试: huase():同种花色返回True,否则返回False dians():牌面大小连续返回True,否则返回False samee():返回相同大小牌的数量,tag指定要几张牌相同大小 try: print(huase(13,n)) except: print("huase判断出错") try: print(dians(13,n)) except: print("dians判断出错") try: d=samee(2,13,n) print(d) except: print("samee函数出错") (1)*6 $A &9 *2 $Q $9 $10 #J #3 #K *7 #2 *Q False False 3 (2)$4 &K #4 #8 *J *5 *7 &5 $K $10 *K *9 $6 False False 2
完整代码测试: (1)receive origin card: #6 $K $8 *8 #Q #A &10 &8 *2 #5 *6 &J $Q number of game: 13338 -------------------------------- *2 #5 $Q $K #Q #A &10 &J #6 $8 *8 &8 *6 (2)receive origin card: *8 *Q *J #3 #Q $A &10 $3 #10 *9 #A *7 $5 number of game: 13456 -------------------------------- &10 #10 $5 #3 #Q $A $3 #A *8 *Q *J *9 *7
8.UI部分界面展示
游戏登入界面
游戏菜单界面
游戏对战界面
游戏排行界面
9.Github的代码签入记录
10.遇到的代码模块异常或结对困难及解决方法
问题描述
- tkinter中在frame组件中插入背景一直无法实现
- python水平不够
- 算法不懂
做过哪些尝试
- 尝试过调用函数、引入库等方法及使用其他组件插入背景图
- 学习算法
- 观看网上教程
- 百度搜索
- 咨询同学
是否解决
- 通过了解tkinter的工作原理,将image定义在主函数再调用,成功解决了问题
- 学习了组合数算法,进一步了解了python,成功解决了问题
有何收获
- 现在已经可以熟练使用tkinter,可以在多个窗口中调用多个图片,美化UI界面的能力得到了提高
- python的列表真的好用
- 学会了组合数算法
11.评价队友
值得学习的地方
- 志荣:思路清晰,刻苦专研,很好的完成自己分工的任务,互帮互助
- 明镇:努力好学,学东西快,通过这次结对作业,我们相互学习了很多
需要改进的地方
- 志荣:因为都是初学者,对开发工具都是现学现用,能够互相帮助,共同进步,所以暂时没有需要改进的地方
- 明镇:我们两个都是小白,什么都靠现学,我觉得已经很好了,暂时没有什么需要改进的地方
12.学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要收获 |
---|---|---|---|---|---|
1 | 300 | 300 | 8 | 8 | 学习python语言,进一步熟悉十三水 |
2 | 500 | 800 | 12 | 20 | 学习算法 |
3 | 1000 | 1800 | 25 | 45 | 代码实现十三水 |