第二次结对编程作业
一、链接
二、具体分工
- 吴之昊:代码的编码部分
- 杨雨丝:代码的测试、博客撰写
三、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. 网络接口的使用
api请求使用的是python里的request库
以开起牌局post和验证get token为例
def opengame(): global token,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 def login_check(): global token url = "https://api.shisanshui.rtxux.xyz/auth/validate" headers = {"X-Auth-Token": token} response = requests.get(url,headers=headers) print(response.text)
2. 代码组织与内部实现设计(类图)
Part1.前端
前端主要难点在联动问题,用pygame和python后端联动可以直接封装调用,会舒服一点
python的图形化界面
使用的pygame主要涉及模块与函数
函数模块 | 功能 |
pygame.cdrom | 访问光驱 |
pygame.cursors | 加载光标 |
pygame.display | 访问显示设备 |
pygame.draw | 绘制形状、线和点 |
pygame.event | 管理事件 |
pygame.font | 使用字体 |
pygame.image | 加载和存储图片 |
pygame.joystick | 使用游戏手柄或者类似的东西 |
pygame.key | 读取键盘按键 |
pygame.mixer | 声音 |
pygame.mouse | 鼠标 |
pygame.movie | 播放视频 |
pygame.music | 播放音频 |
pygame.overlay | 访问高级视频叠加 |
pygame.rect | 管理矩形区域 |
pygame.scrap | 本地剪贴板访问 |
pygame.sndarray | 操作声音数据 |
pygame.sprite | 操作移动图像 |
pygame.surface | 管理图像和屏幕 |
pygame.surfarray | 管理点阵图像数据 |
pygame.time | 管理时间和帧信息 |
pygame.transform | 缩放和移动图像 |
Part2.后端
五、关键代码解释
暴力搜索:
13张牌,挑出5张,然后把剩下的8张牌再放入组合搜索函数嵌套搜索,最后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
统计花色与牌号:
统计牌型用桶排序,dict用于统计花色和牌号,list用于储存牌组结构体
for i in range(1,3+1): hua[ans_3[i].flower] +=1 number[ans_3[i].num]+=1
权值判断与细化:
以前墩部分牌型为例,总细化权值=细化权值 x 细化级别
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 #散牌
六、性能分析与改进
- 改进的思路:
一开始的时候由于用python写速度会比较慢一些,运行时间到了10几秒
经过性能分析,发现在每次抓组合数时候的桶排dict_init()还有constrast()判断函数消>耗了很大一部分的时间,于是进行了优化,
最后成功让算法的性能有所提高,达到了5-6秒钟作业。
- 展示性能分析图和程序中消耗最大的函数(1分)
消耗最大的函数是Second,就是计算中墩的函数。
改进后,发现在判断连对和炸弹等嵌套情况可以暂时储存数据,
同时按牌数循环,将原有的O(n^3)复杂度降到了O(n^2),大大减少了中墩和后墩消耗的时间
七、单元测试
单元测试这部分我们测试主要对三个函数进行测试,其他函数因为功能十分简单,所以就没有进行测试。测试的三个函数分别是得到前墩、中墩、后墩的三个函数,由于结构基本一样,只有变量的改变,所以只给出一部分的代码。各测试数据都是在手机app“大头十三水”读出的数据,然后为了提高一些代码的覆盖,我们尽可能的挑选了不同的数据进行测试,尽可能的覆盖更多的代码分支。而且由于前墩中墩后墩的结果会互相影响,即前墩挑出后要先把前墩的牌剔除再放入中墩函数进行计算,所以中墩的测试数据是在手动剔除前墩的基础上得到的,后墩同理。最后得出的结果与我们设计的算法的思路是一致的。
class MyTestCase(unittest.TestCase): def testfirst(self): weig0 = 10 weig1 = 7 weig2 = 6 self.assertEqual(shisanshui.first(str0), weig0) self.assertEqual(shisanshui.first(str1), weig1) self.assertEqual(shisanshui.first(str2), weig2) def testsecond(self): weig0 = 10 weig1 = 9 weig2 = 8 self.assertEqual(shisanshui.second(str0), weig0) self.assertEqual(shisanshui.second(str1), weig1) self.assertEqual(shisanshui.second(str2), weig2) def testthird(self): weig0 = 10 weig1 = 9 weig2 = 8 self.assertEqual(shisanshui.second(str0), weig0) self.assertEqual(shisanshui.second(str1), weig1) self.assertEqual(shisanshui.second(str2), weig2)
八、贴出Github的代码签入记录
请合理记录commit信息
九、遇到的代码模块异常或结对困难及解决方法
- 问题描述(2分)
- 做过哪些尝试(2分)
- 是否解决(2分)
- 有何收获(2分)
十、评价你的队友
值得学习的地方(2分)
需要改进的地方(2分)
十一、学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
1 | 100 | 100 | 20 | 20 | 学习了正则公式 |
2 | 100 | 200 | 15 | 35 | :-- |
3 | 300 | 600 | 30 | 65 | :-- |
4 | 200 | 800 | 20 | 85 | :-- |