2.具体分工
- 林兴源:完成AI的实现
- 卞永亨:完成UI的实现
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 25 |
Estimate | 估计这个任务需要多少时间 | 30 | 25 |
Development | 开发 | 1040 | 1210 |
Analysis | 需求分析 (包括学习新技术) | 240 | 280 |
Design Spec | 生成设计文档 | 60 | 30 |
Design Review | 设计复审 | 10 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 40 | 30 |
Design | 具体设计 | 20 | 35 |
Coding | 具体编码 | 600 | 720 |
Code Review | 代码复审 | 20 | 35 |
Test | 测试(自我测试,修改代码,提交修改) | 50 | 60 |
Reporting | 报告 | 45 | 45 |
Test Repor | 测试报告 | 15 | 10 |
Size Measurement | 计算工作量 | 10 | 15 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 | 1115 | 1280 |
4.解题思路描述与设计实现说明
- 网络接口的使用
- login用所给的示例代码,修改username和password后即可使用,其他同理,一般修改username、password、id、token等即可
- 将login返回到的数据,使用正则匹配,即可得到id和token
- 修改submit示例代码的提交字符串、id和token,即可完成提交
- 代码组织与内部实现设计(类图)
- 说明算法的关键与关键实现部分流程图
- 算法的关键是进行组合和筛选
- 关键实现部分流程图
5.关键代码解释
import itertools
def cmb(list0):
list1 = list0.copy()
iter1 = itertools.combinations(list1, 5)
while 1:
try:
tup0 = next(iter1)
listc = list(tup0)
list1 = list0.copy()
for i in range(5):
list1.remove(listc[i])
iter2 = itertools.combinations(list1, 5)
while 1:
try:
tup1 = next(iter2)
liste = list(tup1)
listf = list0.copy()
for i in range(5):
listf.remove(listc[i])
for i in range(5):
listf.remove(liste[i])
a = getscore(listc, 5)
b = getscore(liste, 5)
c = getscore(listf, 3)
if a > b and b > c:
listsum[1] = a + 2 * b + 3 * c
if listsum[1] > listsum[0]:
listsum[0] = listsum[1]
global lians
lians.clear()
for k in range(3):
lians.append(listf[k])
for k in range(5):
lians.append(liste[k])
for k in range(5):
lians.append(listc[k])
except StopIteration:
break
except StopIteration:
return
这段代码采用组合数的方法,即先从13张牌中随机选出5张一堆,再从剩下的8张牌中选出5张一堆,剩下3张一堆。遍历c(13,5)c(8,5)c(3,3)种所有可能的情况,再用getscore函数进行判断,选出符合规则且得分最高的组合方式。
6.性能分析与改进
-
在刚开始设计AI的实现方法时,我想过使用递归的贪心算法:(1)底墩先贪心的选能够组合最大的牌型的5张牌,再递归调用自身从剩下的8张中选贪心5张最大牌型,最后剩三张。(2)然后底墩贪心选能够组合次大的牌型的5张牌,再递归调用自身从剩下的8张中选贪心5张最大牌型,最后剩三张。(3)底墩再选第三大...以此类推,直到底端是对子。(4)剩余8张选5张也类似,贪心选最大,然后次大,直到散牌。(5)最终用getscore函数给每堆打分,判断出三墩牌是否符合规则,最终分数最高的三墩牌即是要求的牌。但是这种情况下选出的牌,牌型判断变得很复杂,存在较多不确定性,对写代码实现不友好,就放弃了这种思路,改用组合数遍历所有可能的方法。即每次从13张中随机挑5张,再从剩下8张中挑5张,最后三张一堆,然后每种组合都用getscore函数给每堆打分,判断出三墩牌是否符合规则,最终分数最高的三墩牌即是要求的牌。
-
性能分析图
-
其中消耗最大的函数是组合数遍历所有可能的comb()函数(在上面关键代码处已经展示过),而消耗第二大的getscore()函数与其相差不大,因此我就展示一下getscore()函数,这个函数是用于给每一墩牌打分的。
def getscore(li, m):
listb = li.copy()
f=0
f = tonghuashun(listb)
if f > 0:
return 100 + f * 0.01
f = zhadan(listb)
if f > 0:
return 90 + f * 0.01
f = hulu(listb)
if f > 0:
return 80 + f * 0.01
f = tonghua(listb, m)
if f > 0:
return 70 + f * 0.01
f = shunzi(listb, m)
if f > 0:
return 60 + f * 0.01
f = santiao(listb)
if f > 0:
return 50 + f * 0.01
f = liandui(listb)
if f > 0:
return 40 + f * 0.01
f = liangdui(listb)
if f > 0:
return 30 + f * 0.01
f = duizi(listb, m)
if f > 0:
return 20 + f * 0.01
else:
dict1 = {}
for x in range(2, 15):
dict1[x] = 0
for r in listb:
dict1[r.num] = dict1[r.num] + 1
f = 0.1
t = 0
for i in range(14,1,-1):
if dict1[i]>0:
t =t+ i * f
f =f*0.1
return 10+t
7.单元测试
import unittest
import shisanshui
class MyTestCase(unittest.TestCase):
def test_santonghua(self):
result = shisanshui.santonghua()
self.assertEqual(result, 1)
if __name__ == '__main__':
unittest.main()
- 这是用来测试三同花的测试代码,
- 测试数据的构造思路
- 满足三同花,
- 有两个同花
- 有一个同花
- 没有同花
8.贴出Github的代码签入记录
9.遇到的代码模块异常或结对困难及解决方法(8分)
- 问题描述
- 在写递归组合算法时,会出现跳过执行的情况,导致与预期不符
- http请求api运行时一堆报错
- 在api联网测试时,有时会出现提交的牌与预期不符,比如牌型跳过处理提交,提交上局牌型等
- 写三顺子时,当三张顺子和五张的顺子有重叠时,用第一次写的算法运行会判断错误
- 做过哪些尝试
- 发现问题在于局部变量在递归时会随函数死亡消解而不被保存,但用全局变量替换局部变量后还是不行,于是重新写组合算法,使用迭代器和itertools中的函数combinations()
- 问同班同学和api接口维护的同学以及度娘
- 不断测试,发现是变量问题,把部分关键变量修改成全局变量就解决了
- 重写三顺子判断函数,从有重叠处先选出顺子即可
- 是否解决
- 在同学和搜索引擎的帮助下,都解决了
- 有何收获
- 更熟悉了python语言的使用
- 短时间内从0开始学python语法、http请求等,锻炼了快速学习的能力
- 要注意变量的生存周期!特别是函数体内的局部变量
10.评价你的队友
- 值得学习的地方
- 较高的执行力
- 较强的自学能力
- 需要改进的地方
- 对美学的追求应该加强
- 代码能力有待加强(me too)
11.学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 3 | 3 | 学会用墨刀做原型设计 |
2 | 400 | 400 | 12 | 15 | 学习python的使用和写出程序框架 |
3 | 300 | 700 | 12 | 27 | 学习python,以及学习JS |
4 | 500 | 1200 | 9 | 36 | 加深python的学习,学习http请求,以及学习JS |