博客链接及github地址
分工
杨文:UI界面设计,网络接口使用
范文辉:AI算法的设计及修改bug
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 20 |
Estimate | ·估计这个任务需要多少时间 | 10 | 20 |
Development | 开发 | 3050 | 3480 |
Analysis | ·需求分析(包括学习新技术) | 1440 | 1800 |
Design Spec | ·生成设计文档 | 10 | 10 |
Design Review | ·设计复审 | 30 | 30 |
Coding Standard | ·代码规范(为目前的开发制定合适的规范) | 10 | 10 |
Design | ·具体设计(用伪代码,流程图等方法来设计具体模块) | 120 | 90 |
Coding | · 具体编码 | 480 | 600 |
Code Review | ·代码复审 | 240 | 240 |
Test | 测试(·自我测试,修改,提交修改) | 720 | 700 |
Reporting | 报告 | 55 | 45 |
Test Report | ·测试报告 | 0 | 0 |
Size Measurement | ·计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | ·事后总结并提出过程改进计划 | 45 | 35 |
合计 | 3115 | 3535 |
解题思路描述与设计实现说明
网络接口的使用
def register():#注册+绑定学号
url = 'http://api.revth.com/register2'
headers = {"Content-Type":"application/json"}
form_data = {"username": account["username"],
"password": account["password"],
"student_number":jwc["student_number"],
"student_password":jwc["student_password"]
}
response = requests.post(url=url, headers=headers, data=json.dumps(form_data))
return response
def login():#登录
url = 'http://api.revth.com/auth/login'
headers = {"Content-Type":"application/json"}
form_data = {"username": username, "password": password}
response = requests.post(url=url, headers=headers, data=json.dumps(form_data))
return response
def opengame():#开启战局
url = 'http://api.revth.com/game/open'
headers = {"X-Auth-Token":token}
response = requests.post(url=url, headers=headers)
return response
def cards_out():#出牌
url = 'http://api.revth.com/game/submit'
headers = {"X-Auth-Token":token, "Content-Type":"application/json"}
form_data = {"id": id,
"card": [
"*2 *3 *4",
"*5 *6 *7 *8 *9",
"*10 *J *Q *K *A"
]
}
response = requests.post(url=url, headers=headers, data=json.dumps(form_data))
return response
def rank():#查询排行榜
url = 'http://api.revth.com/rank'
response = requests.get(url=url)
return response
def history_battle():#查询某人历史战局
url = 'http://api.revth.com/history'
headers = {"X-Auth-Token":token}
form_data = {"player_id":id, "limit":limit, "page":page}
response = requests.get(url=url, headers=headers, data=json.dumps(form_data))
return response
def all_battle():#查询某一战局
url = 'http://api.revth.com/history/' + battle_id
headers = {" X-Auth-Token":token}
response = requests.get(url=url, headers=headers, data=json.dumps(form_data))
return response
代码组织与内部实现设计(类图)
UI:
说明算法的关键与关键实现部分流程图
算法主要是将13张牌存入列表中,再依次判断后墩和中墩。当后墩可以是葫芦时,为避免将中墩的同花拆除,会先判断中墩能否在不拆三条的情况下得到同花,若能,则让同花为后墩,否则葫芦为后墩。若是得到同花后还存在葫芦,则将中墩和后墩调换
- 流程图
关键代码解释
def put_list(card): #将牌存入list
for item in card:
pattern='[*#$&]|[0-9a-zA-Z]{1,2}'
string=re.findall(pattern,item) #将花色与数字拆开
if string[0]=='*': #根据牌将list对应位置的值加1
if string[1]=='A':
list[0][13]+=1
list[1][13]+=1
elif string[1]=='J':
list[0][10]+=1
list[1][10]+=1
elif string[1]=='Q':
list[0][11]+=1
list[1][11]+=1
elif string[1]=='K':
list[0][12]+=1
list[1][12]+=1
else:
list[0][int(string[1])-1]+=1
list[1][int(string[1])-1]+=1
list[1][0]+=1
if string[0]=='#': #根据牌将list对应位置的值加1
if string[1]=='A':
list[0][13]+=1
list[2][13]+=1
elif string[1]=='J':
list[0][10]+=1
list[2][10]+=1
elif string[1]=='Q':
list[0][11]+=1
list[2][11]+=1
elif string[1]=='K':
list[0][12]+=1
list[2][12]+=1
else:
list[0][int(string[1])-1]+=1
list[2][int(string[1])-1]+=1
list[2][0]+=1
if string[0]=='$': #根据牌将list对应位置的值加1
if string[1]=='A':
list[0][13]+=1
list[3][13]+=1
elif string[1]=='J':
list[0][10]+=1
list[3][10]+=1
elif string[1]=='Q':
list[0][11]+=1
list[3][11]+=1
elif string[1]=='K':
list[0][12]+=1
list[3][12]+=1
else:
list[0][int(string[1])-1]+=1
list[3][int(string[1])-1]+=1
list[3][0]+=1
if string[0]=='&': #根据牌将list对应位置的值加1
if string[1]=='A':
list[0][13]+=1
list[4][13]+=1
elif string[1]=='J':
list[0][10]+=1
list[4][10]+=1
elif string[1]=='Q':
list[0][11]+=1
list[4][11]+=1
elif string[1]=='K':
list[0][12]+=1
list[4][12]+=1
else:
list[0][int(string[1])-1]+=1
list[4][int(string[1])-1]+=1
list[4][0]+=1
这段代码将13张牌存入了5*14的列表中,其中第一行显示对应数字大小中的牌数,第一列显示对应花色的牌数,使之后判别牌型的算法更加简单
性能分析与改进
不足及改进
- 不足:算法中判断后墩葫芦需考虑中墩牌型,十分耗时
- 改进:后墩葫芦只提取3张,剩下的排好中墩后再补全,若出现中墩比后墩大情形,将两墩交换
性能分析图
消耗最大函数
消耗最大的函数为def Biography(s),部分代码如下
def Biography(s): # 传入传出数据
card = change(s)
put_list(card)
# for i in range(0,5):
# print(list[i])
ch = 0
str1 = put_back()
if len(str1) == 3:
ch = 1
str2 = put_middle(ch)
if len(str1)==5:
if len(str2)==3:
if 2 in list[0]:
st = str1
str1 = str2
str2 = st
if len(str2)==5:
st1 = ' '.join(str1)
st2 = ' '.join(str2)
patterns = '[0-9a-zA-Z]{1,2}'
st1=re.findall(patterns,st1)
st2 = re.findall(patterns, st2)
if st2.count(st2[0])==3 or st2.count(st2[4])==3:
if st1.count(st1[0])<3 and st1.count(st1[4])<3:
st = str1
str1 = str2
str2 = st
单元测试
测试函数为Biography(s),作用是将数据传入,进行分墩,然后传出
思路为:同样的牌比较AI与人工的出牌有什么不同
贴出Github的代码签入记录
遇到的代码模块异常或结对困难及解决方法
问题描述 | 尝试 | 是否解决 | 收获 |
---|---|---|---|
初学python,语法有许多错误 | 向同学请教或百度查找错误 | 已解决 | 逐步熟练掌握python用法 |
评价你的队友
值得学习的地方
零基础学习python,然后直接使用python进行界面设计。能够短时间内将将python的UI部分掌握
需要改进的地方
没什么需要改进的,不过队友间需要更多交流
学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 5 | 5 | 懂得怎么用Axure RP 8设计原型模型 |
2 | 0 | 0 | 8 | 13 | 初步学会python的用法 |
3 | 700 | 700 | 4 | 17 | 懂得使用python设计AI |