第二次结对编程作业
链接及地址
具体分工
- AI部分由我负责
- UI部分由我的队友沈鸿骁负责
PSP表格
PSP2.1 | Personal Software Process Stages | Estimated time(minutes) | The actual time consuming(minutes) |
---|---|---|---|
Planning | 计划 | 80 | 80 |
·Estimate | ·估计这个任务需要多少时间 | 80 | 80 |
Development | 开发 | 3080 | 3495 |
· Analysis | · 需求分析 (包括学习新技术) | 850 | 800 |
· Design Spec | · 生成设计文档 | 50 | 60 |
· Design Review | · 设计复审 | 20 | 15 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 60 | 55 |
· Design | · 具体设计 | 990 | 1100 |
· Coding | · 具体编码 | 1000 | 1350 |
· Code Review | · 代码复审 | 50 | 50 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 65 |
Reporting | 报告 | 90 | 75 |
· Test Repor | · 测试报告 | 40 | 30 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 25 |
· 合计 | 430 | 455 |
解题思路描述与设计实现说明
网络接口的使用
API的使用是通过调用 requests库中的get/post函数实现get/post请求
下面以登录和登出为例:
def login(usename,password): # 登录
global token,use
url = "https://api.shisanshui.rtxux.xyz/auth/login"
payload = "{\"username\":"+"\""+usename+"\""+","+"\"password\":"+"\""+password+"\""+"}"
headers = {'content-type': 'application/json'}
response = requests.post(url, data=payload, headers=headers)
try:
message = response.json()
token = message["data"]["token"]
use=message["data"]["user_id"]
print (response.text)
return message
except :
time().sleep(5)
def logout(): # 登出
global token
url = "https://api.shisanshui.rtxux.xyz/auth/logout"
headers = {"X-Auth-Token":token}
response = requests.post(url,headers=headers)
print(response.text)
代码组织与内部实现设计(类图)
AI部分
-
代码组织
首先前中后三墩牌:poker
临时排列答案存放:ans
完整排列答案存放:temp
最终答案:result
标记:lable
花色:flower
牌号:num -
这是我们的内部设计(类图)
说明算法的关键与关键实现部分流程图
算法的关键
普通牌型判断算法:对手上的牌进行组合,遍历所有情况,按照一定的比牌规则,选取牌型较优者作为当前最佳组合,循环往复,直至遍历完所有的情况,最后得到当前比牌策略下的最优选择。所以算法的关键是对牌型合法的判断和判牌的策略,经过多次测试验证,当前所选择的判牌策略在大多情况下能够实现最优。
关键实现部分流程图
流程图如下:
关键代码解释
贴出你认为重要的/有价值的代码片段,并解释
- 搜索
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 == 5 :
if pddi()>=30.0:
init_1()
dfs_2(1, 1)
else:
dfs_1(i + 1, index_1 + 1)
s1[i] = 0
def dfs_2(d,index_2) :#/*枚举组合*/
for i in range(d,9):
temp_2[index_2] = poker_2[i]
s2[i] = 1
if index_2 == 5 :
init_2()
contrast_ans()
else :
dfs_2(i + 1, index_2 + 1)
s2[i] = 0
解释:通过暴力搜索从13张牌中选出5张,然后把剩下的8张牌返回组合搜索函数中进行搜索。
- 权值判断
for i in range(5, 0, -1):
if number[pddun[i].num] == 1:
x = pddun[i].num
if number[pddun[i].num] == 2:
k = (20.0 + 1.0 / (130 + 13) * ((pddun[i].num - 1) * 10 + x - 1)) * 1.0
return k
k = 10.0+(1.0 / (130000 + 13000 + 1300 + 130 + 13) * ((pddun[5].num - 1) * 10000 + (pddun[4].num - 1) * 1000 + (pddun[3].num - 1) * 100 + (pddun[2].num - 1) * 10 + pddun[1].num - 1)) * 1.0
return k
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
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
解释:总权值=细化级别*细化权值
性能分析与改进
展示性能分析图和程序中消耗最大的函数
性能分析图如下:
从图中可见消耗最大的函数是_pase(),该函数作用主要是用于解析出前中后三墩牌。
描述你改进的思路
因这一块解析代码是程序中核心代码,代码量大,调用关系复杂,进一步改进可能会影响到其他模块,导致其他模块也需要更改,工程量略大,而且改进空间也不是很大。权衡之下,不进行进一步改进。
单元测试
项目部分单元测试代码
这里选择得到前、中、后三墩的代码进行测试。
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的代码签入记录
遇到的代码模块异常或结对困难及解决方法
问题描述
- 对十三水游戏规则的不熟悉
- 不知道如何调用接口
- 不知道前端后端是如何部署的
- 不知道如何使用git提交代码
- 对后端AI算法毫无头绪
做过哪些尝试
首先对于十三水游戏的熟悉,我们是通过在网站上搜索了一个在线十三水游戏进行实操,经过了几十把的对局,逐步掌握游戏规则。其次接口调用也是很令人头疼的,什么是“接口”,怎么”调用“,”我是谁“,”我怎么这么菜“,经过一番番的灵魂拷问,我们通过网课学习,终于了解了这个东西及其使用。git的使用也是通过网上查阅博客再次拾了起来,毕竟没有经常用,一段时间就忘光了。最后后端的AI算法可谓是”搞死人“,经过千辛万苦,在死皮赖脸抱大佬腿,我们勉勉强强搞了出来。
是否解决
解决。
有何收获
收获颇丰,学习到了许多新的知识,锻炼了编程能力,更多的是学会了如何与队友进行有效沟通,完成项目。
评价你的队友
评价人:沈鸿骁
值得学习的地方
翁同学在本次作业中负责后端,虽然也是第一次做这种项目,没什么经验,但是态度积极端正,还专门跑去图书馆借了项目开发实战的书来看。基本总是熬到很晚,前端有些问题也是在队友的启发下找到了突破点,为其努力钻研的精神点赞
需要改进的地方
无,真的挺好的了
评价人:翁正凯
值得学习的地方
鸿骁在本次作业中主动承担前端的开发设计,花了大量时间地去学习前端开发工具,每天晚上都搞得很晚,我都不知道他几点睡觉的,有点担心他的头发。最后做出来的效果很不错,其乐于探知与刻苦钻研的精神值得学习
需要改进的地方
没有,我觉得沈同学很ok。
学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 15 | 15 | 学习python游戏开发流程 |
2 | 400 | 400 | 20 | 35 | 学习如何设计后端函数调用 |
3 | 600 | 1000 | 25 | 60 | 学习前端部署,API调用 |