一、给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址
二、具体分工
吴长星:UI
陈振旺:AI
三、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 20 | 25 |
Estimate | 估计这个任务需要多少时间 | 20 | 25 |
Development | 开发 | 2000 | 2500 |
Analysis | 需求分析 (包括学习新技术) | 30 | 35 |
Design Spec | 生成设计文档 | 25 | 30 |
Design Review | 设计复审 | 20 | 25 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 15 |
Design | 具体设计 | 60 | 65 |
Coding | 具体编码 | 10 | 15 |
Code Review | 代码复审 | 100 | 120 |
Test | 测试(自我测试,修改代码,提交修改) | 200 | 240 |
Reporting | 报告 | 100 | 120 |
Test Repor | 测试报告 | 100 | 110 |
Size Measurement | 计算工作量 | 50 | 55 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 15 | 20 |
合计 | 2760 | 3500 |
四、解题思路描述与设计实现说明
1.网络接口的使用
目前UI和AI是分开的海没做交互
AI部分使用后JAVA编写,调用的接口:
- .登陆:
- .开始游戏
- .提交牌
- .对局详情
2.类图:
3.算法的关键与关键实现部分流程图
算法的关键在于如何将牌分为三墩
五、关键代码解释
- 代码:
public void set_after()//设置后墩的牌
{
ArrayListl=new ArrayList ();
if(isTHS()!=null)
{
after=isTHS();
a_level=1;
delete(after,arr);
}
else if(isZD()!=null)
{
after=isZD();
a_level=2;
delete(after,arr);
}
else if(isST()!=null)
{
after=isST();
copy(arr,l);
delete(after,arr);
if(is_minDZ()!=null)
{
a_level=3;
}
else
{
a_level=6;
}
}
if(a_level6)
{
while(!arr.isEmpty())
{
arr.remove(0);
}
copy(l,arr);
if(isTH()!=null)
{
after=isTH();
delete(after,arr);
a_level=4;
}
else if(isSZ()!=null)
{
after=isSZ();
delete(after,arr);
a_level=5;
}
else
{
delete(isST(),arr);
}
}
else if(a_level0)
{
if(isTH()!=null)
{
after=isTH();
delete(after,arr);
a_level=4;
}
else if(isSZ()!=null)
{
after=isSZ();
delete(after,arr);
a_level=5;
}
else//只剩对子了,至少一个对子,好像是两个吧,还要处理连对
{
while(is_maxDZ()!=null)
{
after.addAll(is_maxDZ());
delete(is_maxDZ(),arr);
if(after.size()4)
{
a_level=8;
break;
}
}
if(after.size()4)//有两个对子以上
{
if(after.get(0).point(after.get(2).point-1))
{
a_level=7;
}
else//处理连对
{
ArrayListl1=new ArrayList tes.get(i-2).point+1)//有连对();
ArrayListtes=new ArrayList ();//装对子
arr.add(after.get(3));
arr.add(after.get(2));
arr.add(after.get(1));
arr.add(after.get(0));
copy(arr,l1);
while(is_minDZ()!=null)
{
tes.addAll(is_minDZ());
delete(is_minDZ(),arr);
}
copy(l1,arr);
int p=0;
while(!after.isEmpty())
{
after.remove(0);
}
for(int i=tes.size()-1;i>=3;i=i-2)
{
p=tes.get(i).point;
if(p
{
after.add(tes.get(i));
after.add(tes.get(i-1));
after.add(tes.get(i-2));
after.add(tes.get(i-3));
delete(after,arr);
a_level=7;
break;
}
}
if(after.size()0)//无连对
{
after.addAll(is_maxDZ());
delete(is_maxDZ(),arr);
after.addAll(is_minDZ());
delete(is_minDZ(),arr);
if(after.size()4)
{
a_level=8;
}
}
}
}
else if(after.size()==2)//后边处理在 set_front
{
a_level=9;
after.add(arr.get(0));
after.add(arr.get(1));
after.add(arr.get(2));
arr.remove(0);
arr.remove(0);
arr.remove(0);
}
else//这种不可能存在,但还是写一下吧
{
a_level=10;
for(int i=0;i<5;i++)
{
mid.add(arr.get(0));
arr.remove(0);
}
}
}//
}
}
- 解释:以上代码是设置后墩的牌,按照流程图那样子逐步判断牌型,其中最复杂的是有三条的时候,如果有三条要判断是葫芦还是三条,还要判断同花和顺子是否存在
如果是同花顺则先弄出5张牌,如果是炸弹先弄出四张牌,其他的同理,最后缺失的牌到后面再补上。但是这个算法执行起来并不能得到最优解
六、性能分析与改进
- 刚开始是做的是从牌里抽出绝对大的五张牌做后墩,但是这样可能会拆掉中墩一些好牌,比如原本有顺子被拆成散排,所以葫芦的对子炸弹的单张,三条的两张单张,二对的最小对以及单张,都最后再拿,这样出牌策略会更好。但是还是有欠缺,还不够好,应该可以适当降低后墩的大小使得中墩更大(都是同样等级时)。但是这样好复杂,不想改了。
可以看出开始战局这个函数占了最多时间。
七、单元测试
- 1.测试的函数是分墩函数SETPOKE,
- 2.因为特殊牌与我无瓜所以只考虑普遍性的分法,所以只需要测试规则里那些牌看能不能分满意就好了。所以只拿了几组牌,但是已经足够了,已经囊括所有的情况了,输出检查也没什么问题
八、贴出Github的代码签入记录
九、遇到的代码模块异常或结对困难及解决方法
- 太多了太多了
- 1.调用接口不成功
- 百度还有问别人
- 解决了一些,但是表格参数哪里不太想看
- 知道怎么调用接口了
- 2.前端不会要肝肝肝
- 菜鸟教程
- 有点认识了
- 会HTML和CSS了
十、评价你的队友
- 值得学习的地方:特别有耐心,打代码从容不迫
- 需要改进的地方:智商不够,不能熬夜
十一、学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
1 | 0 | 0 | 9 | 9 | 学习axure rp的使用方法 |
2 | 600 | 600 | 40 | 49 | 无 |
3 | 1500 | 2100 | 60 | 109 | 了解如何调用接口 |