第二次结对编程作业
2.具体分工
- 林银河:完成AI的实现
- 王耀鑫:完成UI的实现
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 40 |
Estimate | 估计这个任务需要多少时间 | 30 | 40 |
Development | 开发 | 1060 | 1150 |
Analysis | 需求分析 (包括学习新技术) | 240 | 260 |
Design Spec | 生成设计文档 | 60 | 40 |
Design Review | 设计复审 | 10 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 40 | 20 |
Design | 具体设计 | 80 | 120 |
Coding | 具体编码 | 650 | 1615 |
Code Review | 代码复审 | 20 | 25 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 50 |
Reporting | 报告 | 60 | 100 |
Test Repor | 测试报告 | 20 | 30 |
Size Measurement | 计算工作量 | 10 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 50 |
合计 | 1150 | 2290 |
4.解题思路描述与设计实现说明
- 网络接口的使用
- 按照所给的网络接口进行连接
- 将接收到的数据,使用正则表达式,转化成合适自己代码的数据
- 将自己代码运行后得到的数据,转换成合适的形式,使用网络接口,传回
- 代码组织与内部实现设计(类图)
- 说明算法的关键与关键实现部分流程图
- 算法的关键是进行组合和筛选
- 关键实现部分流程图
5.关键代码解释
def cmb(list0):
list1 = list0.copy()
iter1 = itertools.combinations(list1, 5)
for tup0 in iter1:
listc = list(tup0)
list1 = list0.copy()
for i in range(5):
list1.remove(listc[i])
iter2 = itertools.combinations(list1, 5)
for tup1 in iter2:
liste = list(tup1)
list2 = list0.copy()
for i in range(5):
list2.remove(listc[i])
for i in range(5):
list2.remove(liste[i])
a = score(listc, 5)
b = score(liste, 5)
c = score(list2, 3)
if (a >= b) and (b >= c):
s[1] = a + 2 * b + 3 * c
if s[1] > s[0]:
s[0] = s[1]
global result
result.clear()
for k in range(3):
result.append(list2[k])
for k in range(5):
result.append(liste[k])
for k in range(5):
result.append(listc[k])
我这一段代码采用组合的方法,即先从13张牌中随机选出5张,再从剩下的8张牌中选出5张,最后剩下3张。找出所有的情况,再进行判断,选出符合规则的组合方式,给从从选出比较好的方式。
6.性能分析与改进
- 在刚开始设计AI的实现方法时,我想过使用贪心算法,先找到5张组合在一起最大的牌,放在底墩,再找5张第二大的牌,放在中墩,最后三张放在头墩。这样就符合规则了,但是这种情况下选出的牌,赢得概率不大,就放弃了这种思路,改用组合的方法。
- 性能分析图
- 其中消耗最大的函数是我用来进行组合操作和筛选操作的cmb()函数(在上面我已经展示了),而且消耗第二大的函数score()函数和它相差不大,因此我就展示一下我的score()函数,这个函数是来为每一种组合中的每一墩给分的
def score(list, m):
if m == 5:
f = tonghuashun(list)
if f:
return 100000+f*700
f = zhadan(list)
if f:
return 90000+f*700
f = hulu(list)
if f:
return 80000+f*700
f = tonghua(list)
if f:
return 70000+f*0.000007
f = shunzi(list)
if f:
return 60000+f*700
f = santiao(list)
if f:
return 50000+f*700
f = liandui(list)
if f:
return 40000+f*7
f = erdui(list)
if f:
return 30000+f*7
f = duizi(list)
if f:
return 20000+f*700
f = sanpai(list)
if f:
return 10000+f*0.000007
elif m == 3:
f = tonghuashun(list)
if f:
return 100000+f*0.07
f = tonghua(list)
if f:
return 70000+f*0.07
f = shunzi(list)
if f:
return 60000+f*700
f = santiao(list)
if f:
return 50000+f*700
f = duizi(list)
if f:
return 20000+f*700
f = sanpai(list)
if f:
return 10000+f*0.07
7.单元测试
import unittest
import shisanshui
class MyTestCase(unittest.TestCase):
def test_sanshunzi(self):
list0 = shisanshui.list0
result = shisanshui.sanshunzi(list0)
self.assertEqual(result, 1)
if __name__ == '__main__':
unittest.main()
- 这是用来测试是否是三顺子这种特殊牌型的测试代码,
- 测试数据的构造思路
- 选择了5顺子和3顺子有交叉部分,另一个5顺子则与它们没有交叉,其中三顺子在前和在后这两种情况都有,
- 选择了两个5顺子有交叉部分,3顺子与它们没有交叉部分
- 选择三个顺子都有交叉部分的各种情况
8.贴出Github的代码签入记录
9.UI展示
-
登录界面
-
注册界面
-
主页
-
出牌界面
-
历史对局
-
排行榜
-
对局详情
10.遇到的代码模块异常或结对困难及解决方法
- 问题描述
- 在使用组合方法的时候使用递归的方法,经常出现有一些牌被吃掉了
- 使用http请求时经常报错
- 在联网测试时,有时会出现上局的牌被保留到本局中
- 做过哪些尝试
- 重新写组合算法,使用迭代器和itertools中的函数combinations()
- 百度查找资料,向大佬请教
- 通读整篇代码,查找是否是变量问题,是否没有删掉该删的数据
- 是否解决
- 在大佬和百度的帮助下,已经解决了
- 有何收获
- 加深了对python的理解,使自己可以更好的运用python编程
- 体验到了python的便利,在python中有许多可以直接调用的函数,不用自己在写一个函数,提高了编程的效率,减少了代码量
- 懂得了网上查找资料的重要性,网上有许多方法可以参考,也有一些教程可以供我们学习
- 在编程是要注意变量的使用,尤其是全局变量的使用,避免因一时的疏忽,导致编程的错误,到那时想要发现错误就难了(我就是前车之鉴)
11.评价你的队友
- 值得学习的地方
- 强大的组织能力
- 优秀的自学能力
- 需要改进的地方
- 效率有待提高
- 编程能力和我一样有待提高
12.学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 5 | 5 | 学会了简单的java和墨刀的使用 | ||
2 | 400 | 400 | 10 | 15 | 再次学习了python的使用 |
3 | 500 | 900 | 12 | 27 | 继续学习python,开始学习HTML |
4 | 800 | 1700 | 8 | 35 | 加深对python的学习 |