第二次结对编程作业
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 | 代码实现十三水 |