第二次结对编程作业

第二次结对编程作业

一、链接

二、具体分工

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

三、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. 代码组织与内部实现设计

  • 类图:

Part1.前端

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

以下是UI界面的GIF,由于太大传不了,所以录得很短(每个界面一个gif),而且由于抽帧严重有些细节的交互看不清。。。正在想办法

登录界面:

AI出牌界面:

历史游戏界面:

历史游戏详情界面:

排行榜界面:

  • python的图形化界面
  • 添加人机交互控件(Button、Text_box等)并编写相应的函数。
  • 在主事件循环中等待用户触发事件响应。
  • 用pygame.bilt()刷新内容
  • 本次使用的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里面,跑一次遍历把所有的组合的情况,结合每种情况的三墩牌判断每墩牌的权值,可以得到一个总的权值,在接到服务器发牌的时候先将其分到三墩的数组中,搜索并赋权值,将所有情况进行比对,选出总权值最大的情况,返回结果。
  • 后端算法流程图:

五、关键代码解释

分堆 : 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()

  • 性能分析图:

  • 消耗最大的函数: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的代码签入记录

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

  • 问题描述
  • 问题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 |

posted @ 2019-10-15 19:50  _明夜  阅读(260)  评论(3编辑  收藏  举报