网页链接
结对同学博客链接
本作业博客的链接
仓库链接
UI视频链接
分工
前端:沈梓耀
后端:黄恒杰
此次结对作业的PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 1200 | 1800 |
Development | 开发 | 800 | 800 |
· Analysis | · 需求分析 (包括学习新技术) | 900 | 1000 |
· Design Spec | · 生成设计文档 | 10 | 5 |
· Design Review | · 设计复审 | 10 | 5 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 0 |
· Design | · 具体设计 | 400 | 400 |
· Coding | · 具体编码 | 60 | 100 |
· Code Review | · 代码复审 | - | - |
· Test | · 测试(自我测试,修改代码,提交修改) | 100 | 100 |
Reporting | 报告 | 10 | 10 |
· Test Repor | · 测试报告 | 10 | 10 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | - | - |
- | 合计 | 1200 | 1860 |
解题思路描述与设计实现说明
-
网络接口的使用
Java的http包里面自带有HttpUrlConnection的类可以发送http的get请求和post。只是问题的关键在于其很难设置数据包的内容body(首部行还可以,body设置一直不成功),然后只好尝试运用样例里的Unirest类的接口应用,显然更简洁方便。
-
代码组织与内部实现设计(类图)
Http调用接口类:
>###ThirteenWater工作类:
>###Poker手牌类:
>###Pai牌类:
-
说明算法的关键与关键实现部分流程图
在于先判断特殊牌型,然后在对普通牌型进行递归遍历所有情况,对每种情况进行判断,得到“最好牌”。
关键代码解释
难度的关键在于13张牌分出5 5 3所有情况的遍历,这要求需要使用到组合数的算法,即需要使用递归,同时在组合数递归时还需要“分裂”1次,即在分出5张之后,再递归使用分5张的递归。其中在每次分5张的时候,在递归中不再使用之前拿到的牌,只在“分裂”时才把之前的牌传到下一次(很难说明清楚,就是在分相同组的牌时,尽量避免出现重复)。
private void getzuhe(Vector<pai> vv,int x,int start) { if(x>8) { for(int i=start;i<=vv.size();i++) { if(vv.size()-i+1<x-8) return; Enumeration<pai> element=vv.elements(); element=vv.elements(); for(int j=1;j<i;j++) element.nextElement(); pai a=element.nextElement(); v1.add(a); if(x==9) { Vector<pai> vx=new Vector<pai>(); element=vv.elements(); while(element.hasMoreElements()) vx.add(element.nextElement()); element=v1.elements(); while(element.hasMoreElements()) vx.remove(element.nextElement()); getzuhe(vx,x-1,1); } else getzuhe(vv,x-1,i+1); v1.remove(v1.size()-1); } } else if(x>3) { for(int i=start;i<=vv.size();i++) { if(vv.size()-i+1<x-3) return; Enumeration<pai> element=vv.elements(); element=vv.elements(); for(int j=1;j<i;j++) element.nextElement(); pai a=element.nextElement(); v2.add(a); if(x==4) { Vector<pai> vx=new Vector<pai>(); element=vv.elements(); while(element.hasMoreElements()) vx.add(element.nextElement()); element=v2.elements(); while(element.hasMoreElements()) vx.remove(element.nextElement()); getzuhe(vx,x-1,1); } else getzuhe(vv,x-1,i+1); v2.remove(v2.size()-1); } } else { Enumeration<pai> element=vv.elements(); while(element.hasMoreElements()) v3.add(element.nextElement()); // double fen1,fen2,fen3; Vector<pai> nowv=new Vector<pai>(); element=v1.elements(); while(element.hasMoreElements()) nowv.add(element.nextElement()); Comparator<pai> ct=new MyComparator(); Collections.sort(nowv,ct); fen1=getscore(nowv); nowv.removeAllElements(); element=v2.elements(); while(element.hasMoreElements()) nowv.add(element.nextElement()); ct=new MyComparator(); Collections.sort(nowv,ct); fen2=getscore(nowv); if(fen2>fen1) { v3.removeAllElements(); return; } nowv.removeAllElements(); element=v3.elements(); while(element.hasMoreElements()) nowv.add(element.nextElement()); ct=new MyComparator(); Collections.sort(nowv,ct); fen3=getscore(nowv); if(fen3>fen2) { v3.removeAllElements(); return; } //到这里fen1>fen2>fen3 if(fen1+fen2+fen3>allscore) { allscore=fen1+fen2+fen3; getv1.removeAllElements(); getv2.removeAllElements(); getv3.removeAllElements(); element=v1.elements(); while(element.hasMoreElements()) getv1.add(element.nextElement()); element=v2.elements(); while(element.hasMoreElements()) getv2.add(element.nextElement()); element=v3.elements(); while(element.hasMoreElements()) getv3.add(element.nextElement()); } // v3.removeAllElements(); } }
性能分析与改进
-
描述你改进的思路
显然在前几个消耗里面出现了dasda.pocker&MyComparator和Vector类的,从分析可以得到,我对于手牌553的所有遍历(将近3W多种情况)都存入3组Vector临时变量,然后这些递归出来的Vector都需要调用sort函数与Comparator类。
-
展示性能分析图和程序中消耗最大的函数
最大消耗函数:
单元测试
比较蠢的没法,只用文件输入多个样例(自己想的样例,自己去抽牌然后人工比对),样例多为普通牌判断
跑的样例,这样子虽然没法随机生成次数少,但在人工拼牌然后比对之后,其实已经很能解决问题了,以下是结果片段
贴出Github的代码签入记录
遇到的代码模块异常或结对困难及解决方法
-
问题描述
AI的设计思路难点显然在于如上所说的组合数递归,熬了两个夜才搞出来的循环递归代码(网上教程多为单次递归样例)
-
做过哪些尝试
我先尝试写的第一串循环递归没有在循环后给出Vector的开始位置参数,直接每次拿出一张剩下的全给下一次的递归。
发现跑的时间太久,原因是其实质是排列,情况多达上亿
加入开始位置参数,在每个循环的递归中不拿之前拿过牌, 往后拿
-
是否解决
已解决
-
有何收获
写出这个递归,更加理解其实质,头脑风暴的同时头发也被风暴吹走了
递归的情况次数正好是C(13)(5) *C(13)(5) ,成就满满
评价你的队友
-
值得学习的地方
工作完成良好,能力表现很不错(能做好前端的男生都是好姐妹)
-
需要改进的地方
有拖延症,需要改正(me too)
学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 4 | 4 | 初步入门了Axure RP8 |
2 | 200 | 200 | 10 | 10 | 完成牌型设计和基础代码 |
3 | 800 | 1000 | 20 | 20 | 完成AI编码和接口对接 |
- | - | - | - | - | - |
来源:https://www.cnblogs.com/jay-home/p/11681680.html