第二次结对编程作业

1.结对同学博客链接

本作业博客链接

Github项目地址

UI视频链接

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 代码实现十三水
原文地址:https://www.cnblogs.com/linmzAa/p/11664440.html