第二次结对编程作业

第二次结对编程作业

一、链接

  • 结对同学的博客链接
  • 本作业的博客链接
  • Github项目地址

二、具体分工

  • 吴之昊:前端和后端的代码
  • 杨雨丝:代码测试、性能分析与博客撰写

三、PSP表格

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

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

1. 网络接口的使用

  • 使用了python的requests库

例子:登录、开始牌局:

def login(username,password):
    global token,use
    url = "https://api.shisanshui.rtxux.xyz/auth/login"
    payload = "{\"username\":"+"\""+username+"\""+","+"\"password\":"+"\""+password+"\""+"}"
    headers = {'content-type': 'application/json'}
    response = requests.post(url, data=payload, headers=headers)
    message = response.json()  # 登录
    token = message["data"]["token"]
    use=message["data"]["user_id"]
    print (response.text)
    return message

def opengame():
    global token
    global id
    url = "https://api.shisanshui.rtxux.xyz/game/open"
    headers = {"X-Auth-Token": token}
    response = requests.post(url, headers=headers)
    message=response.json()
    id=message["data"]["id"]
    card=message["data"]["card"]
    print(response.text)
    return card


2. 代码组织与内部实现设计

  • 类图:
    第二次结对编程作业_第1张图片

Part1.前端

因为有之前画原型的经历,所以很早就开始思考前端的问题,因为没有接触过这方面,刚开始是考虑用html、js和css写,也为了学这三门语言熬夜两天,后来突然惊喜地发现了python有一个模块专门用来写游戏,也就是pygame,可以很方便地实现简单交互,同时python对后端封装函数的调用也非常方便,直接impot as就可了,所以在研究了一个小时以后就决定用pygame实现图形化,然而事情没有那么简单,我很快发现这玩意儿根本没有输入框这个模块(也可能是我没找到),还有一些奇奇怪怪的问题,好在最后还是写出了一个半吊子的前端

  • python的图形化界面
  • 添加人机交互控件(Button、Text_box等)并编写相应的函数。
  • 在主事件循环中等待用户触发事件响应。
  • 用pygame写界面

其中主要用的是pygame

  • 本次使用的pygame主要涉及模块与函数
函数模块 功能
pygame.cursors 加载光标
pygame.display 访问显示设备
pygame.draw 绘制形状、线和点
pygame.event 管理事件
pygame.font 使用字体
pygame.image 加载和存储图片
pygame.key 读取键盘按键
pygame.mixer 声音
pygame.mouse 鼠标
pygame.music 播放音频
pygame.overlay 访问高级视频叠加
pygame.rect 管理矩形区域
pygame.scrap 本地剪贴板访问
pygame.sprite 操作移动图像
pygame.surface 管理图像和屏幕
pygame.surfarray 管理点阵图像数据
pygame.time 管理时间和帧信息
pygame.transform 缩放和移动图像

Part2.后端

因为还要打互联网+的原因,时间非常少,一开始抱着只要不相公就行了的想法写后端,输赢随缘,所以一开始只打算写个贪心,但是在巨佬的点拨下,我含着泪写了第二种算法的后端,两种思路主要如下:

  1. 贪心算法:
    只需根据规则写一个选出5张最大牌型的函数,先跑一次从13张内挑出5张最大的作后墩,然后跑第二次将剩下8张中最大的5张作中墩,剩下的3张直接放在前墩,这样实现非常容易,但是经过一晚上测试,我发现这种算法跟我差不多菜,于是先写了一版保底,开始研究其他算法。
  2. 搜索、权值比对算法:
    主要是通过遍历所有情况并比对提前赋好的权值来判断出牌的方案。前中后墩总共13张牌,也就是有(C13 5 x C8 5 x C3 3)种组合,放在同一个list里面,跑一次遍历把所有的组合的情况,结合每种情况的三墩牌判断每墩牌的权值,可以得到一个总的权值,在接到服务器发牌的时候先将其分到三墩的数组中,搜索并赋权值,将所有情况进行比对,选出总权值最大的情况,返回结果。
  • 后端算法流程图:
    第二次结对编程作业_第2张图片

五、关键代码解释

分堆 : 13张牌,先搜出5张,嵌套再搜5张,剩下3张

def dfs_1(d, index_1): #/ * 枚举组合 * /

for i in range(d,13+1):

s1[i] = 1#标记,防止重复拿取

temp_1[index_1] = poker_1[i]#挑选

if index_1 == r1 :#r1=5,挑选够5张进入下一个dfs_2()函数,架构与dfs_1一样

init_1()#初始化dfs_2()函数,清空等操作

dfs_2(1, 1)

else:

dfs_1(i + 1, index_1 + 1)

s1[i] = 0

统计牌型用桶排序:

    for i in range(1,3+1):
        hua[ans_3[i].flower] +=1
        number[ans_3[i].num] +=1

权值判断与细化:

for i in range(1,4+1):

if hua[i] == 3:

if shunzi3(ans_3[1].num) == 1:

k=(9.0+0.9 / 11.0 * (ans_3[1].num - 1))

score += k

return k # 3张同花顺

for i in range(3,0,-1):

if number[ans_3[i].num] == 1:

x = ans_3[i].num

if number[ans_3[i].num] == 2:

k=(1.0 + 0.9/(130+13)((ans_3[i].num - 1)10+x-1)1.0)

score += k

return k#单对

k=0.9 / (1300.0 + 130.0 + 13.0)((ans_3[3].num - 1) * 100 + (ans_3[2].num - 1) * 10 + (ans_3[1].num - 1))

score += k

return k #散牌

六、性能分析与改进

经过性能分析,发现运行速度较慢

  • 改进:优化了排序dict_init()以及判断函数constrast()

  • 性能分析图:

第二次结对编程作业_第3张图片

  • 消耗最大的函数:mid 即分配中墩的函数,因为在规则中中墩需要考虑的比较多

七、单元测试

  • 单元测试数据来自现有的福建十三水app(各种出牌和对战),为了提高代码的覆盖,我们尽可能的挑选不同的数据进行测试(对各种函数覆盖率高),但是根据写的函数,还是需要手动删除前墩的数据测试中墩,同理测试后墩。
  • 设计的数据主要对三个函数进行测试。这三个函数分别是得到前墩、中墩、后墩的三个函数,基于这三个函数的相似性我们只展示其中一个。
class MyTestCase(unittest.TestCase):
def testqian(self):
    weig0 = 10
    weig1 = 7
    weig2 = 6
    self.assertEqual(shisanshui.qian(str0), weig0)
    self.assertEqual(shisanshui.qian(str1), weig1)
    self.assertEqual(shisanshui.qian(str2), weig2)
def testzhong(self):
    weig0 = 10
    weig1 = 9
    weig2 = 8
    self.assertEqual(shisanshui.zhong(str0), weig0)
    self.assertEqual(shisanshui.zhong(str1), weig1)
    self.assertEqual(shisanshui.zhong(str2), weig2)
def testhou(self):
    weig0 = 10
    weig1 = 9
    weig2 = 8
    self.assertEqual(shisanshui.zhong(str0), weig0)
    self.assertEqual(shisanshui.zhong(str1), weig1)
    self.assertEqual(shisanshui.zhong(str2), weig2)
    

八、贴出Github的代码签入记录

第二次结对编程作业_第4张图片

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

  • 问题描述

    • 问题1:队友沟通问题
    • 问题2:后端算法十分难完善
    • 问题3:对python的运用程度突如其来完成这个项目难度大
    • 问题4:用python写前端的经验少
  • 做过哪些尝试

    • 通过各种聊天软件与队友沟通,了解队友进度
    • 对权值的细分以及判读如何出牌只能慢慢写,理清逻辑,在细节上不断完善
    • 不停使用搜索引擎,疯狂看博,现学现卖
    • 对各种混乱加以命名上的改善,这样能减少错误
  • 是否解决

  • 有何收获

    在短时间内完成一个没做过的事情固然很难,但是知道了如何在不会的情况下极限运用搜索引擎,更加知道了高效的学习方式,而不是像平时应付考试。和队友的沟通很重要,如果进度不一样,那一方等另一方的后果很严重,所以要及时沟通解决问题,步调一致,才能共同前行。

十、评价你的队友

值得学习的地方:非常乐观
需要改进的地方:希望能多花点心思在学习代码上

十一、学习进度条

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时)
1 93 93 20 20
2 178 271 15 35
3 182 453 45 80
4 125 578 20 100

你可能感兴趣的:(第二次结对编程作业)