第二次结对编程作业

1.相关链接和地址

我的本次作业链接:https://www.cnblogs.com/ambition-hhn/p/11736917.html
搭档(李欣凯)作业链接:https://www.cnblogs.com/wersat/p/11768851.html
github仓库链接:https://github.com/South1999/ShisanshuiGame

2.具体分工

我负责本次作业的AI部分,写出牌的算法,我的队友负责UI部分功能实现。

3.PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20(sum) 20(sum)
·Estimate ·估计这个任务需要多少时间 20 20
Development 开发 790(sum) 1200(sum)
·Analysis ·需求分析 (包括学习新技术) 180 200
·Design Spec ·生成设计文档 70 90
·Design Review ·设计复审 30 30
·Coding Standard ·代码规范 30 60
·Design ·具体设计 60 80
·Coding ·具体编码 200 280
·Code Review ·代码复审 40 60
·Test ·测试 180 400
Reporting 报告 130(sum) 170(sum)
·Test Repor ·测试报告 40 60
·Test Repor ·计算工作量 30 30
·Postmortem & Process Improvement Plan ·事后总结, 并提出过程改进计划 60 80
· 合计 940 1390

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

  • 网络接口的使用
    • 通过使用javascript中的ajax使用接口
  • 代码组织与内部实现设计
    注册(很稀松平常的ajax使用......):

    • 前端拿到牌后把牌传给后端调度算法

    • 类图
  • 说明算法的关键与关键实现部分流程图
    • 算法的关键在于把十三张牌全组合,分成5,5,3三墩,给每个不同的牌型赋权值,同时记录假设当前牌全胜赢得水数,水数大的牌优先值高,其次是权值大的牌。组合用到了itertools库的combinations函数。流程图如下。

5.关键代码解释

  poker = poker.split(' ')
  change1 = {'$': 1, '&': 2, '*': 3, '#': 4}
  change2 = ['', '$', '&', '*', '#']
  newpoker = []
  for x in poker:
    num = change1[x[0]]
    if x[1] == 'A':
      num += 14 * 10
    elif x[1] == 'J':
      num += 11 * 10
    elif x[1] == 'Q':
      num += 12 * 10
    elif x[1] == 'K':
      num += 13 * 10
    else:
      num += int(x[1:]) * 10
    newpoker.append(num)
  newpoker.sort()
  for TOP in combinations(newpoker, 3):
    tmp = list(newpoker[:])
    for i in range(3):
      tmp.remove(TOP[i])

    for MID in combinations(tmp, 5):
      BOT = list(tmp[:])
      for j in range(5):
        BOT.remove(MID[j])

这一段代码是处理拿到的十三张牌,首先用一个split函数将十三张牌分开,每张牌是一个字符串,然后把黑红梅方四种花色转化为个位数,牌的大小乘十,再加起来,这样就可以把牌转化为纯粹的数字,方便之后的处理。拿到处理过的牌后,将其排序,然后通过combinations函数进行组合,每次选出牌后,将已经选出来的牌从原来的牌集中去掉,再重复一次上述操作,最终可遍历所有牌型。

6.性能分析与改进

  • 改进思路
    • 因为本次从十三张牌中按5,5,3分墩,其实就是一个组合的问题,最开始我的组合是自己手写的,速度比较慢,之后我从网上查到python有求组合的函数,用了之后速度提升不少。还有排序问题,最初我是分完墩后,把每墩再分别排序,改进之后是我直接在分墩前就把牌排好序,根据combinations函数特性,得到的每墩顺序是已经排好的,省了每次每墩排序的时间。
  • 性能分析图和消耗最大的函数
def Play(ID,Token,poker):

  # 个位数为1是黑桃,2是红桃,3是梅花,4是方块
  poker = poker.split(' ')
  change1 = {'$': 1, '&': 2, '*': 3, '#': 4}
  change2 = ['', '$', '&', '*', '#']
  newpoker = []
  for x in poker:
    num = change1[x[0]]
    if x[1] == 'A':
      num += 14 * 10
    elif x[1] == 'J':
      num += 11 * 10
    elif x[1] == 'Q':
      num += 12 * 10
    elif x[1] == 'K':
      num += 13 * 10
    else:
      num += int(x[1:]) * 10
    newpoker.append(num)

  newpoker.sort()

  save = []
  MAX = 0       #记录最优且最理想情况全赢能获得多少水
  Mscore1 = 0   #记录目前最优底墩权值分数
  Mscore2 = 0   #中墩
  Mscore3 = 0   #顶墩
  SUM=0
  for TOP in combinations(newpoker, 3):
    tmp = list(newpoker[:])
    for i in range(3):
      tmp.remove(TOP[i])

    for MID in combinations(tmp, 5):
      BOT = list(tmp[:])
      for j in range(5):
        BOT.remove(MID[j])
      score1 = 0  # 底部
      val1 = 1
      score2 = 0  # 钟部
      val2 = 1
      score3 = 0  # 顶部
      val3 = 1
      if Tonghuashun(BOT):
        score1 = 512
        val1 = 5
      elif Zhadan(BOT):
        score1 = 256
        val = 4
      elif Hulu(BOT):
        score1 = 128
      elif Tonghua(BOT):
        score1 = 64
      elif Shunzi(BOT):
        score1 = 32
      elif Santiao(BOT, 5):
        score1 = 16
      elif Liandui(BOT):
        score1 = 8
      elif Erdui(BOT):
        score1 = 4
      elif Yidui(BOT, 5):
        score1 = 2
      else:
        score1 = 1

      if Tonghuashun(MID):
        score2 = 512
        val2 = 10
      elif Zhadan(MID):
        score2 = 256
        val2 = 8
      elif Hulu(MID):
        score2 = 128
        val2 = 2
      elif Tonghua(MID):
        score2 = 64
      elif Shunzi(MID):
        score2 = 32
      elif Santiao(MID, 5):
        score2 = 16
      elif Liandui(MID):
        score2 = 8
      elif Erdui(MID):
        score2 = 4
      elif Yidui(MID, 5):
        score2 = 2
      else:
        score2 = 1

      if Santiao(TOP, 3):
        score3 = 16
      elif Yidui(TOP, 3):
        score3 = 2
      else:
        score3 = 1

      if score1 >= score2 and score2 >= score3 and (val1 + val2 + val3 > MAX or (val1 + val2 + val3 == MAX and score1+score2+score3 >= SUM and score1>score2 and score2>score3) ):
        save = []
        temp = ''
        pai = ''
        for i in range(3):
          temp += change2[TOP[i] % 10]
          pai= str(TOP[i] // 10)
          if(pai=='11'):
              pai='J'
          elif(pai=='12'):
              pai='Q'
          elif(pai=='13'):
              pai='K'
          elif(pai=='14'):
              pai='A'
          temp+=pai
          if i != 2:
            temp += ' '
        save.append(temp)
        temp = ""
        for i in range(5):
          temp += change2[MID[i] % 10]
          pai   = str(MID[i] // 10)
          if(pai=='11'):
              pai='J'
          elif(pai=='12'):
              pai='Q'
          elif(pai=='13'):
              pai='K'
          elif(pai=='14'):
              pai='A'
          temp+=pai
          if i != 4:
            temp += ' '
        save.append(temp)
        temp = ""
        for i in range(5):
          temp += change2[BOT[i] % 10]
          pai   = str(BOT[i] // 10)
          if(pai=='11'):
              pai='J'
          elif(pai=='12'):
              pai='Q'
          elif(pai=='13'):
              pai='K'
          elif(pai=='14'):
              pai='A'
          temp+=pai
          if i != 4:
            temp += ' '
        save.append(temp)
        MAX = val1 + val2 + val3
        SUM=score1+score2+score3
        Mscore1 = score1
        Mscore2 = score2
        Mscore3 = score3

  header={
    'content-type':'application/json',
    'x-auth-token':str(Token)
          }
  data={
    'id':int(ID),
    'card':save
  }
  print(save)
  response=requests.post('http://api.revth.com/game/submit',json=data,headers=header)
  return response.json()

7.单元测试

测试的就是上述的Play函数,测试数据是调用api获得

拿到的牌
'&5 #3 $8 #Q *6 #5 #9 $Q #8 $5 #J #6 *10'
'&Q $6 $J #J *4 $K $2 #Q *9 *K #6 #4 #9'
'#J *7 *Q &10 #5 #8 &K &9 *A #2 #3 $7 &J'
'$9 *2 &5 &A *6 $3 *A &8 &6 #7 &10 &K *K'
'*7 *4 #6 &8 $8 $10 *5 $2 #9 #2 *3 #A *J'
打出去的牌
['$8 *10 $Q', '#3 #8 #9 #J #Q', '$5 &5 #5 *6 #6']
['*9 $J &Q', '$2 *4 $6 $K *K', '#4 #6 #9 #J #Q']
['$7 *7 *A', '&9 &10 &J *Q &K', '#2 #3 #5 #8 #J']
['$9 *K *A', '*2 $3 &6 *6 #7', '&5 &8 &10 &K &A']
['#9 $10 #A', '$2 #2 #6 $8 &8', '*3 *4 *5 *7 *J']

8.Github的代码签入记录

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

  • 问题描述
    • 最开始使用requests库中的request和get函数一直显示失败,并且不知道为什么会出错
  • 做过哪些尝试
    • 最开始我检查url是否填写正确,然后去网上搜索request库中的request和get详细用法,后来发现我在传参数的时候,参数格式错误,最后改成正确的
  • 是否解决
  • 有何收获
    • 之前没有接触过网络接口这方面的知识,这一次亲自写了程序利用网络接口来获取信息,对网络接口这方面的知识有了更深的了解

10.评价你的队友

  • 值得学习的地方
    • 我的队友非常努力,他是负责前端的内容,我知道他的工作量应该比我大,而且每天都有在学习新的内容。他善于为队友考虑,他已经把一些数据处理好,我就少了一些工作量
  • 需要改进的地方
    • 希望他和我可以更多的沟通,这次作业因为前端和后端用的语言不一样,导致连起来有些困难,有一些原因我觉得可能是沟通有点少,不过这方面我也需要改进。

11.学习进度条

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
1 0 0 3 3 对原型设计工具有一个初步了解
2 200 200 5 8 学习有关网络接口方面内容
3 350 550 5 13 尝试初步写十三水的算法
4 200 750 6 19 改进代码,改进算法
原文地址:https://www.cnblogs.com/ambition-hhn/p/11736917.html