zoukankan      html  css  js  c++  java
  • 第二次结对编程作业

    1、博客链接

    2、具体分工

    • 张逸杰:负责前端Ui的设计实现
    • 吴智勇:负责后端的算法
    • 刘汪洋:负责网络接口的实现及博客撰写

    3、PSP表格

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 30 60
    Estimate 估计这个任务需要多少时间 20 30
    Development 开发 360 480
    Analysis 需求分析 (包括学习新技术) 100 120
    Design Spec 生成设计文档 10 20
    Design Review 设计复审 15 20
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 60 60
    Design 具体设计 180 200
    Coding 具体编码 2500 3000
    Code Review 代码复审 60 60
    Test 测试(自我测试,修改代码,提交修改) 80 100
    Reporting 报告 120 180
    Test Repor 测试报告 30 45
    Size Measurement 计算工作量 30 45
    Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 40 60
    合计 3635 4480

    4、解题思路描述与设计实现说明

    网络接口的使用

       调用 Pycharm自带的requests库中的get/post函数实现get/post请求,把登录、注册、出牌、排行榜等操作所需要的请求直接写在了窗口变换的主函数中,使用时直接运行主函数"十三水"即可。
    

    具体代码示例:

    • 登录接口:
    global token,user_id
    url = "http://api.revth.com/auth/login"
    headers = {'content-type': "application/json"}
    data = {
        "username": username,
        "password": password
    }
    res = requests.post(url, data=json.dumps(data), headers=headers)
    info = res.json()
    if info['status'] == 0:
        token = info['data']['token']
        user_id = info['data']['user_id']
    else:
        print('登录失败,请检查你的密码是否正确!')
    
    • 发牌接口:
    def dzjm_fp():#对战界面发牌功能
        global cards
        url = 'http://api.revth.com/game/open'
        headers = {'x-auth-token': n}
        res = requests.post(url, headers=headers)
        info = res.json()
        print('开启战局')
        id = info['data']['id']
        print(id)
        cards = info['data']['card']
        print('当前手牌:', cards)
    

    代码组织与内部实现设计

    前端代码组织与内部实现设计

       利用Qt designer将设计好的界面自动转化为py文件,再自己编写界面的转换,运行及连接服务器的接口代码。
    

    后端代码组织与内部实现设计

      1.首先先判断是否是特殊牌型,如果是的话,直接分成三墩输出。
      2.不是特殊牌型的话,把这十三张牌随机先取出五张做底墩,再取出五张牌做中墩,剩下三张做前墩,之后判断是否会出现倒水的情况,如果会,则舍弃,如果不会,如果是第一个,则直接记录为最大牌型,如果不会是第一个,则与之前的最大牌型进行比较,胜出则取代其成为最大牌型。
      3.遍历所有情况,找出最大牌型,就是所出的牌。
    

    算法的关键与关键实现部分流程图

    算法的关键

       算法关键应该是对牌型合法的判断和判牌的策略,经过多次测试验证,我当前所选择的判牌策略在大多情况下能够实现最优,但还是不免有翻车的情况,这说明我这个策略并不是最优的。
    

    关键实现部分流程图

    5、关键代码解释

    前端:

    • 通过信号与信号槽达到通过按钮连接及跳转页面。
    url='http://api.revth.com/auth/register2'
    form_data={
           "username":ui5.lineEdit.text(),
           "password":ui5.lineEdit_2.text(),
           "student_number":ui5.lineEdit_3.text(),
           "student_password":ui5.lineEdit_4.text()
    }
    headers = {
           "Content-Type": "application/json"
    }
    response = requests.post(url=url, headers=headers, data=json.dumps(form_data), verify=False)
    print(response.text)
    res = response.json()
    if res['status']== 0:
            widget1.show()
            widget4.hide()
    ui5.pushButton.clicked.connect(lambda:zcjm_enter_yhjm())
    

    后端:

    • 特殊牌型与普通牌型的判断分类
    def pickcard(string):
        card = find(string)
        if special.zzql(card)!=0 or special.ytl(card)!=0 or special.sftx(card)!=0 or special.sth(card)!=0 or special.sths(card)!=0 \
            or special.ssz(card)!=0 or special.wdst(card)!=0 or special.qd(card)!=0 or special.qx(card)!=0 or special.ldb(card)!=0 \
            or special.cys(card)!=0 or special.sehz(card)!=0 or special.sgcs(card)!=0 or special.stst(card)!=0:
            list = specialcard(string)
            return list
        else:
            list = string.split()
            list1 = [' ', ' ', ' ']
            front = ' '
            middle = ' '
            bottom = ' '
            temp1 = [-1, -1]
            temp2 = [-1, -1]
            temp3 = [-1, -1]
            for i in itertools.combinations(list,5):
                xxx = copy.deepcopy(list)
                for y in i:
                    xxx.remove(y)
                for j in itertools.combinations(xxx,5):
                    p = copy.deepcopy(xxx)
                    for t in j:
                        p.remove(t)
                    string1 = ' '.join(i)
                    string2 = ' '.join(j)
                    string3 = ' '.join(p)
                    frontvalue = check1(string1)
                    middlevalue = check1(string2)
                    bottomvalue = check2(string3)
                    if frontvalue[0] > middlevalue[0] or (frontvalue[0] == middlevalue[0] and frontvalue[1] >= middlevalue[1]):
                        if middlevalue[0] > bottomvalue[0] or (middlevalue[0] == bottomvalue[0] and middlevalue[1] >= bottomvalue[1]):
                            if front == ' ':
                                front = string1
                                middle = string2
                                bottom = string3
                                temp1 = frontvalue
                                temp2 = middlevalue
                                temp3 = bottomvalue
                            else:
                                win1 = 0
                                win2 = 0
                                win3 = 0
                                if frontvalue[0] > temp1[0]:
                                    win1 = 1
                                elif frontvalue[0] == temp1[0]:
                                    if frontvalue[1] > temp1[1]:
                                        win1 = 1
                                    elif frontvalue[1] == temp1[1]:
                                        win1 = 0
                                    elif frontvalue[1] < temp1[1]:
                                        win1 = -1
                                elif frontvalue[0] < temp1[0]:
                                    win1 = -1
                                if middlevalue[0] > temp2[0]:
                                    win2 = 1
                                elif middlevalue[0] == temp2[0]:
                                    if middlevalue[1] > temp2[1]:
                                        win2 = 1
                                    elif middlevalue[1] == temp2[1]:
                                        win2 = 0
                                    elif middlevalue[1] < temp2[1]:
                                        win2 = -1
                                elif middlevalue[0] < temp2[0]:
                                    win2 = -1
                                if bottomvalue[0] > temp3[0] :
                                    win3 = 1
                                elif bottomvalue[0] == temp3[0]:
                                    if bottomvalue[1] > temp3[1]:
                                        win3 = 1
                                    elif bottomvalue[1] == temp3[1]:
                                        win3 = 0
                                    elif bottomvalue[1] < temp3[1]:
                                        win3 = -1
                                elif bottomvalue[0] < temp3[0]:
                                    win3 = -1
                                if win1 + win2 + win3 > 0:
                                    front = string1
                                    middle = string2
                                    bottom = string3
                                    temp1 = frontvalue
                                    temp2 = middlevalue
                                    temp3 = bottomvalue
            list1[0] = bottom
            list1[1] = middle
            list1[2] = front
            return list1
    
    • 三张牌的牌型的判断拆分(前墩)
    def check2(string):#三张牌的判断牌型
        num = findd(string)
        if num[0] == num[1] == num[2]:
            temp = [4,num[0]]
            return temp
        elif num[0] == num[1]:
            temp = [2,num[0]]
            return temp
        elif num[0] == num[2]:
            temp = [2,num[0]]
            return temp
        elif num[1] == num[2]:
            temp = [2,num[1]]
            return temp
        elif num[0] != num[1] and num[0] != num[2] and num[1] != num[2]:
            temp = [1,max(num[0],num[1],num[2])]
            return temp
    
    • 五张牌的牌型的判断拆分(中墩,后墩)
    def check1(string):#五张牌的判断牌型
        num = findd(string)
        changenum = sorted(num)
        color = findcolor(string)
        if color[0] == color[1] == color[2] == color[3] == color[4] and changenum[4] == changenum[3]+1 == changenum[2]+2 ==\
            changenum[1]+3 == changenum[0]+4:
            temp = [9,changenum[4]]
            return temp
        if changenum[0] == changenum[1] == changenum[2] == changenum[3] or changenum[1] == changenum[2] == changenum[3] == \
            changenum[4]:
            temp = [8,changenum[2]]
            return temp
        if (changenum[0] == changenum[1] and changenum[2] == changenum[3] == changenum[4]) \
            or (changenum[0] == changenum[1] == changenum[2] and changenum[3] == changenum[4]):
            temp = [7,changenum[2]]
            return temp
        if color[0] == color[1] == color[2] == color[3] == color[4]:
            temp = [6,changenum[4]]
            return temp
        if changenum[4] == changenum[3]+1 == changenum[2]+2 == changenum[1]+3 == changenum[0]+4:
            temp = [5,changenum[4]]
            return temp
        if (changenum[0] == changenum[1] == changenum[2] ) or (changenum[1] == changenum[2] == changenum[3]) or \
                changenum[2] == changenum[3] == changenum[4]:
            temp = [4,changenum[2]]
            return temp
        if changenum[0] == changenum[1] and changenum[2] == changenum[3]:
            if changenum[1]+1 == changenum[3]:
                temp = [2.5,changenum[3]]
            else:
                temp = [2,changenum[3]]
            return temp
        if changenum[0] == changenum[1] and changenum[3] == changenum[4]:
            if changenum[1] + 1 == changenum[3]:
                temp = [2.5, changenum[3]]
            else:
                temp = [2, changenum[3]]
            return temp
        if changenum[1] == changenum[2] and changenum[3] == changenum[4]:
            if changenum[1]+1 == changenum[3]:
                temp = [2.5,changenum[3]]
            else:
                temp = [2,changenum[3]]
            return temp
        if changenum[0] == changenum[1]:
            temp = [2,changenum[0]]
            return temp
        if changenum[1] == changenum[2]:
            temp = [2, changenum[1]]
            return temp
        if changenum[2] == changenum[3]:
            temp = [2, changenum[2]]
            return temp
        if changenum[3] == changenum[4]:
            temp = [2, changenum[3]]
            return temp
        temp = [1,changenum[4]]
        return temp
    

    6、性能分析与改进

    改进的思路

       一开始是打算从底墩开始写出各种牌型所应对的情况,如底墩是同花顺,那么应当取哪些牌作为这个同花顺合适。后来发现即使写了4,5百行也是刚开始,而且量大且不重复,极容易出bug,所以换了一种遍历所有出牌情况的方法,比较简单而且不容易出bug。
    

    性能分析图

      使用visual studio 2019自带的Python性能分析工具得到
    

    程序中消耗最大的函数

      消耗最大的函数是主函数十三水.py
    

    7、单元测试

    项目部分单元测试代码

    • 下图是测试用到的函数,代码比较长,限于篇幅不全展开

      测试数据:随机生成,不特意构造。
      测试思路:利用随机生成的数据对各个函数进行测试,可完成对其实用性和可靠性检测。
      

    8、Github的代码签入记录

    9、遇到的代码模块异常及解决方法

    • 问题描述一:

      在编程过程中,遇到了变量的赋值问题,在函数中,会对传来的变量进行改变。
      

    做过的尝试

      需要进行深复制。
    

    是否解决

      已解决
    

    收获

      对python的传参数有了更好的理解。
    
    • 问题描述二:

      在运行过程中,发现zeros赋值函数运行时间极长。
      

    做过的尝试

      采用手动赋值的方法,极大的改善了运行时间。
    

    是否解决

      已解决
    

    收获

      有时候手动赋值会更加快运行时间。
    
    • 问题描述三:

      用Qt designer做Ui设计时,不知道怎么实现界面转换。
      

    做过的尝试

      通过百度教程和动手不断尝试。
    

    是否解决

      已解决
    

    收获

      学会了如何用Qt designer做页面设计。
    
    • 问题描述四:

      在编写网络接口代码时,不知道如何将得到的返回值显示在窗口或界面上。
      

    做过的尝试

      想用标签或者文本框来实现。
    

    是否解决

      尚未完全解决。
    

    收获

      学会了简单的网络接口实现,有了基本的了解,但还不够熟悉。
    

    10、评价队友

    • 评价逸杰:

    • 值得学习的地方

      逸杰学习新知识很投入,是最早开始着手做十三水的,也在督促我们要抓紧时间,事实也证明他是对的。
      
    • 需要改进的地方

      空闲时间可以多去学习新知识提升自己。
      
    • 评价智勇:

    • 值得学习的地方

      算法能力很强,学习新知识很快,很多天都在熬夜。
      
    • 需要改进的地方

      希望合理分配时间,全都挤在最后时间会很赶,很累。
      

    11、学习进度条

    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 10 10 学习原型设计工具和简单的Python实现图形界面
    2 500 500 20 30 学习pyqt5,着手设计界面,尝试从服务器获取数据,编写代码
    3 1200 1700 50 80 学习python,实现特殊牌型和普通的判断算法,并逐步优化
  • 相关阅读:
    php使用cookie来保存用户登录信息
    Linux下进程操作
    TortoiseSVN无法编辑日志信息的解决方法
    用DIV布局制作公告板
    HashMap的遍历
    实现文本滚动
    子DIV块中设置margintop时影响父DIV块位置的解决办法
    php使用session来保存用户登录信息
    javascript jquery ajax动态提交多个参数 api测试 拂晓风起
    javascript 处理返回json中的\u中文乱码问题(也不是乱码了,就是\u编码) 拂晓风起
  • 原文地址:https://www.cnblogs.com/LWYWD/p/11746766.html
Copyright © 2011-2022 走看看