第二次结对编程作业
1.
• 结对同学博客链接
• 本作业博客的链接
2.具体分工
叶梦晴:网页前端html、与服务器交互
赵镇:网页后端python、写博客
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 50 | 60 |
Development | 开发 | 800 | 850 |
Analysis | 需求分析 (包括学习新技术) | 500 | 560 |
Design Spec | 生成设计文档 | 90 | 60 |
Design Review | 设计复审 | 90 | 60 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
Design | 具体设计 | 60 | 120 |
Coding | 具体编码 | 600 | 650 |
Code Review | 代码复审 | 60 | 90 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 190 |
Reporting Standard | 报告 | 60 | 40 |
Test Repor | 测试报告 | 60 | 40 |
Size Measurement | 计算工作量 | 20 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 40 |
合计 | 2570 | 2860 |
4.解题思路描述与设计实现说明
4.1网络接口的使用
-
注册:post 数据到:http://api.revth.com/register2,通过返回状态码判断是否注册成功,处理用户已存在
-
登录 post 数据到:http://api.revth.com/auth/login,通过返回状态码判断是否登录成功,得到token存在localStorage;
-
排行榜:get json:http://api.revth.com/rank, 为了美观只显示了前五名
-
出牌 post 数据到 http://api.revth.com/game/submit
-
开局 token放响应头 post 数据到http://api.revth.com/game/open
4.2代码组织与内部实现设计(类图)
函数名称 | 功能 |
---|---|
init() | 初始化所有排列组合 |
doit() | 初始化后 每次开始工作 |
inputt() | 输入牌 开始计算 |
outputt() | 输出分牌方案 |
comp_() | 选出最优方案 |
4.3算法思路:
-
生成所有排列,遍历判断合法性;
-
对于合法的,算出出牌方案的总价值
-
保存最大的摆牌方案,取最大的输出。
5.关键代码解释
- init:
int flag[15];
void init(){
for(int i=1;i<=13;i++)
for(int j=i+1;j<=13;j++)
for(int k=j+1;k<=13;k++)
for(int l=k+1;l<=13;l++)
for(int m=l+1;m<=13;m++){
mm(flag, 0);
flag[i]=flag[j]=flag[k]=flag[l]=flag[m]=1;
for(int x=1;x<=13;x++){
if(!flag[x]){
for(int y=x+1;y<=13;y++){
if(!flag[y]){
for(int z=y+1;z<=13;z++){
if(!flag[z]) {
flag[x]=1,flag[y]=1,flag[z]=1;
_data[num].a[1]=x,_data[num].a[2]=y,_data[num].a[3]=z,_data[num].a[4]=i,_data[num].a[5]=j,_data[num].a[6]=k,_data[num].a[7]=l,_data[num].a[8]=m;
int ppos=9;
for(int fl=1;fl<=13;fl++){
if(!flag[fl]) _data[num].a[ppos++]=fl;
}
flag[x]=0,flag[y]=0,flag[z]=0;
num++;
}
}
}
}
}
}
}
}
预处理 枚举所有牌型组合 方便后续判断 保存在_data结构体中
- deal_qian
int deal_qian()
{
int aa[4];
for(int i=1;i<=3;i++)
aa[i]=temp.head[i]%100;
sort(aa+1, aa+4);
if(aa[1]==aa[2]&&aa[2]==aa[3])
temp.kind[1]=4,temp.val[1]=aa[1];
else if(aa[1]!=aa[2]&&aa[2]!=aa[3]){
temp.kind[1]=0, temp.val[1]=aa[3];
}
else{
temp.kind[1]=1, temp.val[1]=aa[2];
}
}
以前墩为例 用最朴素的方式判断特殊牌型
6.性能分析
从cpu使用率图来看 init()生成所有排列组合 只花费3%
大部分花费在judge()特别是solve_zhong() 判断中墩牌型上
优化:应该还能加一点剪枝(我是真的剪不动了)
7.单元测试
针对特殊牌型(目的是测试能否识别特殊牌型)
输入: *6 *5 *9 &K &2 *3 $8 $9 &A &J *2 &7 $5
输出:
$5 $8 $9
*2 *3 *5 *6 *9
&2 &7 &J &K &A
常见牌型(目的是测试能否排序普通牌型)
输入:
#8 &3 *A $5 #10 *8 &5 #2 $K #4 #Q #J *10
输出:
$5 &5 #2
#8 &3 #10 *8 #4
*A $K #Q #J *10
8.Github的代码签入记录
//完成以后上传的(手下留情//龇牙)
9.遇到的代码模块异常或结对困难及解决方法
1、问题描述:
(1)算法部分开始做的时候感觉不能过于贪心的安排三墩,可以类比田忌赛马的策略适当降低一些后墩的权值来使得前墩和中墩的权值变大,在某些情况下是可以获得更高的分数。
(2)由于之前都没有接触过这些,对于服务器的连接实在是弄不清楚。
2、做过的尝试:
(1)模拟了很多种情况,发现这是一个博弈的过程,由于无法知道对手的牌,是无法利用一些策略来保证自身最优的,只能去冒一些风险,就变的有利有弊,所以最后还是采用贪心来做决策。
(2)请教大佬+上网查教程+自己摸索,在不断的探索中得益于助教的API文档,再问了问别人也算是搞定了
3、是否解决:
都解决了
4、有何收获:
面对一些自己思路也要有批判性的思维,多想一点:真的吗???没问题吗???是否是最优???
对于很多没接触过的东西,不应该去抵触逃避,多问多学才可以解决一个又一个的问题
10.评价你的队友
值得学习的地方: 队友那还用说,浑身上下都是要学习的地方。刻苦认真,很能熬夜,感觉好多东西都会,显然一个大佬模样。不像我这个除了算法几乎啥也不会的憨憨,所以后面退役了要像队友多多学习,啥东西都得会一些,变成一个靠谱的人。
需要改进的地方: 毕竟男女搭配交流会少一些,其他的没得挑。
11.学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 350 | 350 | 900 | 900 | 了解十三水的规则,实现了初步的前端页面代码 与算法思考 |
2 | 300 | 650 | 900 | 1800 | 增加了之前代码尚未考虑到状态,完工代码。更美化了十三水前端页面 |