第二次结对编程作业

岁酱吖の 提交于 2019-12-01 10:17:06

结对同学博客链接

本博客链接

github地址

1. 具体分工

西西西瓜萌:UI设计、前端实现、初版算法的实现、博客撰写

雨霖铃0000:提供算法思路、改进算法的实现、算法分析测试、博客撰写

2. PSP表格

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

3. 解题思路与设计实现

  • 解题思路
    首先,通过接口进行注册登录获取token,战局开始后取得13张扑克,通过遍历的方式找出最大的牌型,并赋予其特定的分值,当牌型一样时,分值更大的那一种排法优先,赋牌顺序为后墩、中墩、前墩。
  • 网络接口的使用
    • 注册
      • AI
        url = "https://api.shisanshui.rtxux.xyz/auth/register"
        payload = "{\"username\":\"un\",\"password\":\"pw\"}"
        headers = {'content-type': 'application/json'}
        response = requests.request("POST", url, data=payload, headers=headers)
        print(response.text)
      • UI
        url: "https://api.shisanshui.rtxux.xyz/auth/register",
        method: "POST",
        header: {
        'Content-Type': 'application/json'
        },
        data: JSON.stringify({
        "username": this.data.username,
        "password": this.data.password
        }),
    • 登陆
      • AI
        url = "https://api.shisanshui.rtxux.xyz/auth/login"
        payload = "{\"username\":\"un\",\"password\":\"pw\"}"
        headers = {'content-type': 'application/json'}
        response = requests.request("POST", url, data=payload, headers=headers)
        print(response.text)
      • UI
        url: "https://api.shisanshui.rtxux.xyz/auth/login",
        method: "POST", 
        header: {
        'Content-Type': 'application/json'
        },
        data: JSON.stringify({
        "username": this.data.username,
        "password": this.data.password
        }),
    • 开启战局
      • AI
        url = "https://api.shisanshui.rtxux.xyz/game/open"
        headers = {'x-auth-token': tkk}
        response = requests.request("POST", url, headers=headers)
        print(response.text)
      • UI
        url: "https://api.shisanshui.rtxux.xyz/game/open",
        method: "POST",
        header: {
        'X-Auth-Token': app.globalData.token
        },
    • 出牌
      • AI
        url = "https://api.shisanshui.rtxux.xyz/game/submit"
        payload = "{\"id\":" + idd + ",\"card\":[\"" + qian +"\",\""+ zhong +"\",\""+ hou +"\"]}"
        print(payload)
        headers = {
        'content-type': "application/json",
        'x-auth-token': tkk
        }
        response = requests.request("POST", url, data=payload, headers=headers)
        print(response.text)
    • 历史战局详情
      • UI
        url: "https://api.shisanshui.rtxux.xyz/history",
        data: {
        "player_id": this.data.id,
        "limit": this.data.n1,
        "page": this.data.n2
        },
        method: "GET",
        header: {
        'content-type': 'application/json',
        'X-Auth-Token': app.globalData.token
        },
    • 历史战局列表
      • UI
        url: 'https://api.shisanshui.rtxux.xyz/history/'+this.data.id,
        data: {
        "id": this.data.id,
        },
        method: "GET",
        header: {
        'content-type': 'application/json',
        'X-Auth-Token': app.globalData.token
        },
    • 排行榜
      • UI
        url: "https://api.shisanshui.rtxux.xyz/rank",
        method: "GET",
  • 代码组织与内部实现设计(类图)


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

4. 关键代码解释

就拿取出后墩的函数third()来说

def third():
    global score
    init_cnt()
    bubble_sort(ans_1, 1, 5)
    x = 1
    for i in range(1, 6):
        hua[ans_1[i].flower] = hua[ans_1[i].flower] + 1
        number[ans_1[i].num] = number[ans_1[i].num] + 1
    x = 1
    for i in range(1, 6):
        if hua[i] == 5:
            if ShunZi5(ans_1[1].num) == 1:
                k = (9.0 + 0.9 / 9 * (ans_1[1].num - 1)) * 1.0  # 14 13 12 11 10
                score += k
                return k  # 同花顺
    x = 1
    for i in range(5, 0, -1):
        if number[ans_1[i].num] == 4:
            x = ans_1[i].num
        if number[ans_1[i].num] == 4:
            k = (8.0 + 0.9 / (130 + 13) * ((ans_1[i].num - 1) * 10)) * 1.0
            score += k
            return k  # 炸弹
    x = 1
    for i in range(5, 0, -1):
        if number[ans_1[i].num] == 3:
            x = ans_1[i].num
            for j in range(5, 0, -1):
                if number[ans_1[j].num] == 2:
                    k = (7.0 + 0.9 / (130 + 13) * ((x - 1) * 10 + ans_1[j].num - 1)) * 1.0
                    score += k
                    return k  # 葫芦
    x = 1
    for i in range(1, 6):
        if hua[i] == 5:
            k = (6.0 + 0.9 / (130000 + 13000 + 1300 + 130 + 13) * (
                        (ans_1[5].num - 1) * 10000 + (ans_1[4].num - 1) * 1000 + (ans_1[3].num - 1) * 100 + (
                            ans_1[2].num - 1) * 10 + (ans_1[1].num - 1))) * 1.0
            score += k
            return k  # 同花
    x = 1
    if ShunZi5(ans_1[1].num) == 1:
        k = (5.0 + 0.9 / 9 * (ans_1[1].num - 1) * 1.0)
        score += k
        return k  # 5张顺子
    x = 1
    for i in range(5, 0, -1):
        if number[ans_1[i].num] == 3:
            x = ans_1[i].num
            for j in range(5, 0, -1):
                if number[ans_1[j].num] == 1:
                    k = (4.0 + 0.9 / (1300 + 130 + 13) * ((x - 1) * 100))
                    score += k
                    return k  # 三条
    x = 1
    for i in range(5, 0, -1):
        if number[ans_1[i].num] == 2:
            for j in range(5, 0, -1):
                if (ans_1[i].num != ans_1[j].num) and \
                        number[ans_1[j].num] == 2 and abs(ans_1[i].num - ans_1[j].num) == 1:
                    k = (3.0 + 0.9 / 10 * (ans_1[j].num - 1 - 1)) * 1.0
                    score += k
                    return k  # 连对2对
    x = 1
    for i in range(5, 0, -1):
        if number[ans_1[i].num] == 2:
            for j in range(5, 0, -1):
                if (ans_1[i].num != ans_1[j].num) and number[ans_1[j].num] == 2:
                    k = (2.0 + 0.9 / (130 + 13) * ((ans_1[i].num - 1) * 10 + ans_1[j].num - 1)) * 1.0
                    score += k
                    return k  # 普通2对
    x = 1
    for i in range(5, 0, -1):
        if number[ans_1[i].num] == 1:
            x = ans_1[i].num
        if number[ans_1[i].num] == 2:
            k = (1.0 + 0.9 / (130 + 13) * ((ans_1[i].num - 1) * 10 + x - 1)) * 1.0
            score += k
            return k  # 单对+3张散

    k = (0.9 / (130000 + 13000 + 1300 + 130 + 13) * (
                (ans_1[5].num - 1) * 10000 + (ans_1[4].num - 1) * 1000 + (ans_1[3].num - 1) * 100 + (
                    ans_1[2].num - 1) * 10 + ans_1[1].num - 1)) * 1.0
    score += k
    return k

先将未使用过的牌进行排序,在排好的序列中循环依次判断有无同花顺、 炸弹 、葫芦、 同花、顺子、三条、二对连对、普通二对、一对、散牌的牌型,牌型从大到小为:同花顺 > 炸弹 > 葫芦 > 同花 > 顺子 > 三条 > 二对连对 > 普通二对 > 一对 > 散牌,k为此牌型得到的分值,牌的大小越大,k值越大,从而得到最优的后墩牌型。

5. 性能分析与改进

  • 展示性能分析图

  • 程序中消耗最大的函数

    由profile分析图可以看出消耗最大的函数是排序函数bubble_sort(),用于提取中墩和后墩的second()和third()中用到了冒泡排序函数,并且要在全局进行循环遍历,所以消耗也比较大。

  • 改进的思路
    将second()和third()两个函数中不必要的循环用if加以判断,减少排序消耗。

6. 单元测试

  • 使用python的unittest模块,构建专门的单元测试类,进行部分单元测试代码
import unittest
from 13water import Card
from 13water import bubble_sort
import 13water

class Testbubble(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    poker_1 = [Card(0, 0) for i in range(14)]

    poker_1[1] = Card(2, 2)
    poker_1[2] = Card(3, 2)
    poker_1[3] = Card(4, 2)
    poker_1[4] = Card(1, 3)
    poker_1[5] = Card(1, 4)
    poker_1[6] = Card(4, 5)
    poker_1[7] = Card(1, 6)
    poker_1[8] = Card(1, 7)
    poker_1[9] = Card(2, 9)
    poker_1[10] = Card(3, 8)
    poker_1[11] = Card(4, 4)
    poker_1[12] = Card(4, 8)
    poker_1[13] = Card(3, 5)

    bubble_sort(poker_1,1,14)

    for i in range(1,14):
        print(poker_1[i].num,end=" ")

if __name__ == "__main__":
    unittest.main()

  • 测试的函数
    排序函数bubble_sort()

  • 构造测试数据的思路
    给出13张可能遇到的牌,令bubble_sort()将其排序,只有排序正确后面才能进行正确的牌型比较。

7. Github的代码签入记录

8. 遇到的代码模块异常或结对困难及解决方法

  • 遇到的代码模块异常
    • 问题描述
      一开始算法赋予牌型的分值和牌本身大小并无联系,导致中墩和后墩出现同种牌型时(比如都是葫芦),有可能出现中墩比后墩大的情况即“相公”。

    • 做过哪些尝试
      改进了分值计算的算法,使分值计算和牌面大小有关,并加入和中墩和后墩大小的比较,若中墩分值大于后墩,则中墩和后墩交换。

    • 是否解决
      是。

    • 有何收获
      在考虑墩的大小比较时要考虑全面,不仅要考虑牌型不同时的情况,也要考虑相同牌型的情况。

  • 结对困难及解决方法
    • 问题描述
      一开始两人都没有非常擅长的领域,所以在UI和AI的任务分配时我们不知道怎么协调。

    • 做过哪些尝试
      两人都尝试着去学习和制做AI和UI部分,各取自己擅长或感兴趣的部分。

    • 是否解决
      是。

    • 有何收获
      分工搭配,干活不累!

9. 评价你的队友

  • 值得学习的地方

    基础比较好,各方面知识涉猎的都比较多一些。认真刻苦,也更善于请求他人的帮助。

  • 需要改进的地方

    要注意身体,熬夜到五点,七点又起来上课真的厉害了,但是对头发不好啊。

10. 学习进度条

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累积学习耗时(小时) 重要成长
1 99 99 18 18 熟悉Axure RP用法,了解Java的trycatch语句
2 524 623 20 38 了解wx.javascript,写了一部分前端的框架
3 1072 1695 20 58 完成UI制作和算法逻辑
4 553 2248 28 86 实现接口和部分bug的修复

11.心得体会

奶茶一喝,把夜熬起来,死都做不出来的最后也都能做出来的。(再次开始考虑转行了)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!