1. 地址
2. 分工
童景霖:完成AI的实现
黄永福:完成UI的实现
3. PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
· Planning | · 计划 | 30 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 20 |
· Development | · 开发 | 240 | 300 |
· Analysis | · 需求分析 (包括学习新技术) | 200 | 600 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 | 20 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 60 | 80 |
· Coding | · 具体编码 | 200 | 240 |
· Code Review | · 代码复审 | 30 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 40 |
· Reporting | · 报告 | 40 | 60 |
· Test Repor | · 测试报告 | 20 | 15 |
· Size Measurement | · 计算工作量 | 20 | 25 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
· 合计 | 970 | 1510 |
4. 解题思路描述与设计实现说明
网络接口的使用
- 采用API文档中“注册与绑定”里的代码样例实现注册和绑定,其他功能也基本类似,将函数中的参数进行修改即可
将API返回的数据格式转换,利用json.load()转换成字典对象,再对字典进行处理获得所需要的数据
代码组织与内部实现设计(类图)
关键部分流程图
5. 关键代码解释
代码的关键部分
- AI_Part:
def find_card(c_list): s1 = 0 s0 = 0 for x0 in itertools.combinations(c_list, 5): list1 = c_list.copy() x0 = list(x0) a = gets_core(x0, 5) if a < 20 : continue for y0 in x0: list1.remove(y0) for x1 in itertools.combinations(list1, 5): list2 = list1.copy() x1 = list(x1) for y1 in x1: list2.remove(y1) x2 = list2 b = gets_core(x1,5) c = gets_core(x2,3) if (a >= b) and (b >= c): s1 = a + 1.5*b + 2*c if s1 > s0: s0 = s1 global card card.clear() # 3 x2 str2 = get_str(x2,3) # 5 x1 str1 = get_str(x1,5) # 5 x0 str0 = get_str(x0,5) card.append(str2) card.append(str1) card.append(str0)
利用itertools迭代器的combinations函数从13张牌中抽取5张作为后墩,判断后墩牌型,若为散牌则直接跳过;再从剩下的8张牌中抽取5张做为中墩,判断中墩牌型,若比后墩大,则直接跳过,重新搜索中墩;剩下的3张牌为前墩。
将各种牌型赋予一定的分数值,将前中后墩的牌型分数相加得到总分,总分最高的牌即为最终牌型,并返回。- UI_Part:
class IndexDetail(QtWidgets.QDialog, history_detail.Ui_Dialog): def __init__(self, parent=None, *args, **kwargs): super().__init__(parent, *args, **kwargs) self.setupUi(self) self.res = API.history(MainWindow.TokenMine, IndexHistory.pid) print(self.res['status']) if self.res['status'] == 0: self.res = self.res['data'] self.res = self.res['detail'] self.label_name.setText(str(self.res[0]['name'])) self.label_score.setText(str(self.res[0]['score'])) self.label_card.setText(str(self.res[0]['card'])) self.label_name_2.setText(str(self.res[1]['name'])) self.label_score_2.setText(str(self.res[1]['score'])) self.label_card_2.setText(str(self.res[1]['card'])) self.label_name_3.setText(str(self.res[2]['name'])) self.label_score_3.setText(str(self.res[2]['score'])) self.label_card_3.setText(str(self.res[2]['card'])) self.label_name_4.setText(str(self.res[3]['name'])) self.label_score_4.setText(str(self.res[3]['score'])) self.label_card_4.setText(str(self.res[3]['card'])) else: self.label_card.setText('status:'+str(self.res['status'])) def back(self): self.close() w = IndexHistory(window) w.show()
- 战局列表界面利用接口函数获取该局PID记录为类成员,在详情界面使用战局列表类成员PID来调用接口获取详情,并显示在GUI上,(如遇对局未完成等情况,显示返回的Status)
6. 性能分析与改进
性能分析图
程序中消耗最大的函数
改进思路
- 程序中消耗最大的函数是利用itertools迭代器,使用组合数列出13张牌能组成的所有牌型,再通过对每种情况的牌型进行评分,将分数最高的牌型输出。从13张牌中抽取5张,再从剩下的8张拍中抽取5张,最后剩下3张牌,这样组成牌的前、中、后墩。由于十三张牌能组成的牌型过多导致花费的时间很长。
- 由于每个人有13张牌,所以后墩必定不可能是散排(如果是散排则为一条龙),因此可以对后墩前进行判断,如果是散牌则可以直接跳过,考虑下一种情况;同样的也可以对中墩进行判断,如果中墩大于后墩,则跳过这种情况,但此时应保持后墩不变,改变中墩。其他的改进思路暂时还没想到。
7. 单元测试
def getnum(a): return a.num def tonghuashu(dun_b): lista = [] listb = [] listc = [] listd = [] #分类 for s in dun_b: if s.color == "#": lista.append(s) elif s.color == "$": listb.append(s) elif s.color == "&": listc.append(s) elif s.color == "*": listd.append(s) #排序 lista.sort(key=getnum) listb.sort(key=getnum) listc.sort(key=getnum) listd.sort(key=getnum) if len(lista) == 5: liste = lista elif len(listb) == 5: liste = listb elif len(listc) == 5: liste = listc elif len(listd) == 5: liste = listd else: liste = [] l = len(liste) i = 1 if l == 5: flag = True while i < l: if liste[i].num != liste[i-1].num+1: flag = False break i = i+1 else: flag =False if flag is True: return liste[0].num else: return 0 a = tonghuashu(list) print(a)
- 这是测试传入的中墩或者后墩是否为同花顺的代码
传入的牌事先经过处理以类的形式存放于列表s中,先将他们根据不同的花色进行分类,若某一种花色的数量达到5,再将其按牌的大小进行排序,检查是否是连续的牌型,是则为同花顺。
8. GitHub代码签入记录
9. 遇到的代码模块异常或结对困难及解决方法
问题描述
- AI_Part:
- 不会使用api
- 不懂得如何制作UI界面
- 数据类型直接的转换老是弄乱,对于一些函数的返回值类型不熟悉
- 使用迭代器模块时一直出现错乱
- UI_Part:
- QTDesigner网上教程资源过少(多为C++教程或者代码实现教程)
- .ui->.py 需要借助Pyuic工具,而我下的最新版的anaconda找不到Pyuic.exe的路径
- 右键.ui文件使用Pyuic进行.ui->.py时 点错成主模块即我的UI.py造成了整个UI.py代码丢失
调用显示继承来的窗口发生跳出
做过的尝试
- AI_Part:
- 百度查找相关资料以及到视频网站查找相应的教学视频
- 询问同学
- 不断测试,增加了很多测试点寻找问题
- UI.Part:
- 百度精确检索Pyqt5该关键词项
- 寻找原生的python文件里带该工具
- 发现有历史记录这个工具
英语水平过低未及时发现,经大佬提醒 发现继承来的窗口未定义自定义槽函数,一经调用,立马跳出!
是否解决
- AI_Part:
- 是
- UI_Part:
是
收获
- AI_Part:
- 对API的使用更加熟练了
- 能更加熟练的使用python,对python的了解也更多了
- 学习使用了python的itertools模块和time模块
- 简单掌握了pyqt5的使用,能用pyqt5做出一些简单的程序界面
- UI_Part:
- 熟悉API的使用,并能够根据所给的接口写模块
- 对python自带的工具栏更加熟悉
- 对python附加工具更加熟悉
- 对Pyqt5及QtDesigner熟练应用,并初步认识使用QtCreator
- 对GUI的Init有一定了解
10. 评价队友
值得学习的地方
- 有很高的学习热情
- 坚持不懈持之以恒
需要改进的地方
- 效率太高了!
快等等我!
11. 学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
6 | 0 | 0 | 8 | 8 | 学习并能简单使用墨刀、ps等软件 |
7 | 400 | 400 | 12 | 20 | 学习python |
8 | 800 | 900 | 12 | 32 | 学习python和pyqt5 |