第二次结对编程作业 1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分) 2、给出具体分工(2分) 3、给出PSP表格(2分) 4、解题思路描述与设计实现说明(15分) 5、关键代码解释(3分) 6、性能分析与改进(6分) 7、单元测试(5分) 8、贴出Github的代码签入记录(1分) 9、遇到的代码模块异常或结对困难及解决方法(8分) 10、评价你的队友(4分) 11、学习进度条(2分)

结对同学的博客链接:
031602603陈超星
031702146李昕晖
031702545王怀骋

本作业博客的链接
Github项目地址

2、给出具体分工(2分)

陈超星:负责编写UI部分的代码
李昕晖:负责编写AI部分的代码
王怀骋:负责写各种测试例子,用于测试AI的算法,以便于改进AI的算法

3、给出PSP表格(2分)

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 0 0
· Estimate · 估计这个任务需要多少时间 1500 1500
Development 开发 0 0
· Analysis · 需求分析 (包括学习新技术) 100 100
· Design Spec · 生成设计文档 0 0
· Design Review · 设计复审 0 0
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 0 0
· Design · 具体设计 0 0
· Coding · 具体编码 1200 1200
· Code Review · 代码复审 0 0
· Test · 测试(自我测试,修改代码,提交修改) 100 100
Reporting 报告 100 100
· Test Repor · 测试报告 0 0
· Size Measurement · 计算工作量 0 0
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 0 0

4、解题思路描述与设计实现说明(15分)

网络接口的使用(3分)

第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
2、给出具体分工(2分)
3、给出PSP表格(2分)
4、解题思路描述与设计实现说明(15分)
5、关键代码解释(3分)
6、性能分析与改进(6分)
7、单元测试(5分)
8、贴出Github的代码签入记录(1分)
9、遇到的代码模块异常或结对困难及解决方法(8分)
10、评价你的队友(4分)
11、学习进度条(2分)

代码组织与内部实现设计(类图)(6分)

第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
2、给出具体分工(2分)
3、给出PSP表格(2分)
4、解题思路描述与设计实现说明(15分)
5、关键代码解释(3分)
6、性能分析与改进(6分)
7、单元测试(5分)
8、贴出Github的代码签入记录(1分)
9、遇到的代码模块异常或结对困难及解决方法(8分)
10、评价你的队友(4分)
11、学习进度条(2分)

说明算法的关键与关键实现部分流程图(6分)

UI:

第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
2、给出具体分工(2分)
3、给出PSP表格(2分)
4、解题思路描述与设计实现说明(15分)
5、关键代码解释(3分)
6、性能分析与改进(6分)
7、单元测试(5分)
8、贴出Github的代码签入记录(1分)
9、遇到的代码模块异常或结对困难及解决方法(8分)
10、评价你的队友(4分)
11、学习进度条(2分)

AI:

第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
2、给出具体分工(2分)
3、给出PSP表格(2分)
4、解题思路描述与设计实现说明(15分)
5、关键代码解释(3分)
6、性能分析与改进(6分)
7、单元测试(5分)
8、贴出Github的代码签入记录(1分)
9、遇到的代码模块异常或结对困难及解决方法(8分)
10、评价你的队友(4分)
11、学习进度条(2分)

5、关键代码解释(3分)

贴出你认为重要的/有价值的代码片段,并解释(3分)

		String s=u2s2("http://api.revth.com/game/open"),u[];
        Matcher m=Pattern.compile("id":(.*?),"card":"(.*?)"").matcher(s);
        if(m.find())
        {
            u=ai.f(m.group(2));
            s=u2s("http://api.revth.com/game/submit","{"id":"+m.group(1)
            +","card":[""+u[0]+"",""+u[1]+"",""+u[2]+""]}");
            l3.setText(s="<html>"+u[0]+"<br>"+u[1]+"<br>"+u[2]+"<br>"+s+"</html>");
            if(!s.matches(".*status":0.*"))System.out.println(s);
        }
        else if(s.matches(".*status":2001.*"))
        {
            l3.setText("<html>"+s+"<br>未结束战局过多,所以等下再自动开始</html>");
            Thread.sleep(2000);
        }
        else
        {
            m=Pattern.compile("token":"(.*)?"").matcher(u2s(a));
            t=m.group(1);
        }

自动开启战局,每局都用AI算法计算3墩,然后用这3墩出牌并将结果显示到UI,如果出现异常,则把异常输出到控制台,以便于后面进行调试解决bug,如果未结束战局过多,则每隔2s尝试一次是否可开新的战局,如果登录状态已超时,则重新获取token再自动开启战局

6、性能分析与改进(6分)

描述你改进的思路(5分)

起初判断牌型时,是每次都遍历13张牌,特别浪费时间,后来想到了可以先分别按花色和牌的大小排序,这样子的话,判断同花顺只需要从相同花色且>=5张的牌中判断是否有大小连续的5张牌,判断炸弹只需要找相同点数且==4张的牌,判断同花只需要从相同花色且>=5张的牌中选出最大的5张牌,其他同理,不需要每次都遍历全部的13张牌,所以大大节省了时间

展示性能分析图和程序中消耗最大的函数(1分)

第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
2、给出具体分工(2分)
3、给出PSP表格(2分)
4、解题思路描述与设计实现说明(15分)
5、关键代码解释(3分)
6、性能分析与改进(6分)
7、单元测试(5分)
8、贴出Github的代码签入记录(1分)
9、遇到的代码模块异常或结对困难及解决方法(8分)
10、评价你的队友(4分)
11、学习进度条(2分)

7、单元测试(5分)

展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路

int i;String[]a={"*5 *3 *2 *4 *6 *9 *K *10 *7 *J *8 *Q *A"
		,"*7 *8 *9 *10 *J *Q *2 $3 *4 *5 #6 &K &A"
		,"&Q *Q #K $K &K *2 &J *J #Q $Q *K #A $A"
		,"#7 $7 #8 $8 &8 $9 &9 $5 #6 $6 &10 &J &Q"
		,"*2 *9 #Q $Q &Q *Q #K $K &K *K #9 $9 &9"
		,"*Q #K $K &K *8 #8 $9 &9 *9 #Q $Q &Q *K"
		,"#2 *2 $5 &6 *6 $3 &3 *3 #4 #7 $8 &8 *8"
		,"#2 *2 #3 *3 #4 #6 *6 #7 *4 *5 #8 *8 *9"
		,"#2 *2 #8 &8 *8 #9 #3 $3 *3 *4 $9 &A *A"
		,"#2 #9 $9 $2 *2 $3 &3 *3 #8 &8 *8 &9 *A"
		,"#2 $2 $5 &8 *8 *2 $3 &3 #5 #9 $9 &A *A"
		,"#2 $2 *6 &8 *8 #9 $9 $3 &3 #5 $5 &A *A"
		,"*5 #6 $6 &10 #7 $7 #8 $8 &8 $9 &9 &J &Q"
		,"$4 $6 #7 $7 #8 #6 $8 &8 $9 &9 &10 &J &Q"
		,"*2 *3 #4 #5 #J $J #K $7 &8 *8 *9 $A &A"
		,"#J $J &J $8 *2 *3 &4 #5 #6 #7 *9 *Q *A"
		,"*5 #8 *A $3 *8 *9 &8 #A $A &A *10 *J *Q"
		,"*2 *3 #4 #5 $5 $J #K $A &8 *8 *9 #J &A"
		,"#8 $8 *8 #3 #5 $5 &5 &3 $2 *2 $Q &Q *Q"
		,"*5 #6 &6 $Q #A $A &A #8 $9 &10 *J *A $3"
		,"#3 *9 *10 *J *5 &9 $6 *6 #7 $7 &Q *8 *Q"
		,"$4 $5 #7 *2 *3 *6 *K *A &2 &3 &4 &10 &K"
		,"$2 $9 &K #10 $10 &10 $7 &7 &3 #4 #5 #6 *7"
		,"$2 $5 #10 *2 *4 *10 *Q *A &3 &5 &6 &J &A"
		,"$Q #K $8 #2 $A &2 $3 #7 &7 *3 *5 *A &4"
		,"*2 $J $Q &6 $7 *9 &K #J #K &A #7 #8 #A"
		,"$8 &10 #Q *8 *9 *10 #J &Q #4 $4 *4 #6 *6"}
		,j,d[]={{"*2 *3 *4","*5 *6 *7 *8 *9","*10 *J *Q *K *A","*2 *3 *4 *5 *6 *7 *8 *9 *10 *J *Q *K *A","至尊清龙"}
		,{"*2 $3 *4","*5 #6 *7 *8 *9","*10 *J *Q &K &A","*2 $3 *4 *5 #6 *7 *8 *9 *10 *J *Q &K &A","一条龙"}
		,{"*2 &J *J","#Q $Q &Q *Q #K","$K &K *K #A $A","*2 &J *J #Q $Q &Q *Q #K $K &K *K #A $A","十二皇族"}
		,{"$5 #6 $6","#7 $7 #8 $8 &8","$9 &9 &10 &J &Q","$5 #6 $6 #7 $7 #8 $8 &8 $9 &9 &10 &J &Q","三同花顺"}
		,{"*2 #9 $9","&9 *9 #Q $Q &Q","*Q #K $K &K *K","*2 #9 $9 &9 *9 #Q $Q &Q *Q #K $K &K *K","三分天下"}
		,{"#8 *8 $9","&9 *9 #Q $Q &Q","*Q #K $K &K *K","#8 *8 $9 &9 *9 #Q $Q &Q *Q #K $K &K *K","全大"}
		,{"#2 *2 $3","&3 *3 #4 $5 &6","*6 #7 $8 &8 *8","#2 *2 $3 &3 *3 #4 $5 &6 *6 #7 $8 &8 *8","全小"}
		,{"#2 *2 #3","*3 #4 *4 *5 #6","*6 #7 #8 *8 *9","#2 *2 #3 *3 #4 *4 *5 #6 *6 #7 #8 *8 *9","凑一色"}
		,{"#2 *2 #3","$3 *3 *4 #8 &8","*8 #9 $9 &A *A","#2 *2 #3 $3 *3 *4 #8 &8 *8 #9 $9 &A *A","双怪冲三"}
		,{"#2 $2 *2","$3 &3 *3 #8 &8","*8 #9 $9 &9 *A","#2 $2 *2 $3 &3 *3 #8 &8 *8 #9 $9 &9 *A","四套三条"}
		,{"#2 $2 *2","$3 &3 #5 $5 &8","*8 #9 $9 &A *A","#2 $2 *2 $3 &3 #5 $5 &8 *8 #9 $9 &A *A","五对三条"}
		,{"#2 $2 $3","&3 #5 $5 *6 &8","*8 #9 $9 &A *A","#2 $2 $3 &3 #5 $5 *6 &8 *8 #9 $9 &A *A","六对半"}
		,{"*5 #6 $6","#7 $7 #8 $8 &8","$9 &9 &10 &J &Q","*5 #6 $6 #7 $7 #8 $8 &8 $9 &9 &10 &J &Q","三顺子"}
		,{"$4 #6 $6","#7 $7 #8 $8 &8","$9 &9 &10 &J &Q","$4 #6 $6 #7 $7 #8 $8 &8 $9 &9 &10 &J &Q","三同花"}
		,{"#4 *3 *2","&8 *8 *9 $7 #5","$A &A #J $J #K","散牌","对子","二对"}
		,{"#J $J &J","$8 #7 #6 #5 &4","*A *Q *9 *3 *2","三条","顺子","同花"}
		,{"#8 &8 *5","#A $A &A *A $3","*Q *J *10 *9 *8","对子","炸弹","同花顺"}
		,{"#4 *3 *2","&8 *8 #5 $5 *9","$A &A #J $J #K","散牌","二对","二对"}
		,{"#5 $5 &5","#8 $8 *8 #3 &3","$Q &Q *Q $2 *2","三条","葫芦","葫芦"}
		,{"#6 &6 *5","$Q *J &10 $9 #8","#A $A &A *A $3","对子","顺子","炸弹"}
		,{"&9 *5 #3","#7 $7 $6 *6 &Q","*Q *J *10 *9 *8","散牌","连对","同花顺"}
		,{"#7 $5 $4","&K &10 &4 &3 &2","*A *K *6 *3 *2","散牌","同花","同花"}
		,{"&K $9 $2","*7 #6 #5 #4 &3","#10 $10 &10 $7 &7","散牌","顺子","葫芦"}
		,{"#10 $5 $2","&A &J &6 &5 &3","*A *Q *10 *4 *2","散牌","同花","同花"}
		,{"$8 *5 &4","$A *A #7 &7 $Q","$3 *3 #2 &2 #K","散牌","二对","连对"}
		,{"$7 &6 *2","&A &K $Q $J *9","#A #K #J #8 #7","散牌","散牌","同花"}
		,{"#Q &10 $8","&Q #J *10 *9 *8","#4 $4 *4 #6 *6","散牌","顺子","葫芦"}};
		for(i=0;i<d.length;i++)if(!Arrays.equals(d[i],j=f(a[i])))
		{
			System.out.println(i+1+":
正解:");
			for(String s:d[i])System.out.println(s);
			System.out.println("
错解:");
			for(String s:j)System.out.println(s);
			System.out.println("

");
		}
		System.out.println("测试结束,以上几个没通过测试");

测试的函数:

测试的函数就是AI算法

构造测试数据的思路:

先按照所有种类的牌型分别构造几种测试数据,然后再从实际用网络接口开启战局后获得的牌中,随机选几个用于测试

8、贴出Github的代码签入记录(1分)

请合理记录commit信息
第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
2、给出具体分工(2分)
3、给出PSP表格(2分)
4、解题思路描述与设计实现说明(15分)
5、关键代码解释(3分)
6、性能分析与改进(6分)
7、单元测试(5分)
8、贴出Github的代码签入记录(1分)
9、遇到的代码模块异常或结对困难及解决方法(8分)
10、评价你的队友(4分)
11、学习进度条(2分)

9、遇到的代码模块异常或结对困难及解决方法(8分)

问题描述(2分)

第一次写ai的时候,寻找同花时,是从相同花色且>=5张的牌中选出最大的5张牌当作同花,然而在用网络接口开启战局几次后,发现了“不合法墩牌”的错误

做过哪些尝试(2分)

经过调试,发现了原来是中墩比后墩大的错误,如:中墩:"*A *Q *10 *4 *2",后墩:"&A &J &6 &5 &3",这是因为我一找到同花就直接把该花色的最大的5张牌当成了最大的同花,但实际上别的花色还可能有更大的同花,所以我修改了ai代码,找到同花后,还要再判断其余花色是否有更大的同花,直到找到最大的同花

是否解决(2分)

解决了

有何收获(2分)

自己构造的测试数据再多也不可能把所有情况都考虑周到,所以一定要不断用网络接口开启战局进行测试,这样才能发现问题并完善代码

10、评价你的队友(4分)

值得学习的地方(2分)

队友都很勤奋,值得我学习
队友对于没接触过的东西都抱有好奇心,我也要保持这种求知的欲望

需要改进的地方(2分)

我们都有很多东西目前不会或者不熟悉,所以每次碰到问题都得百度半天
团队合作方面还需加强

11、学习进度条(2分)

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
1 600 600 25 25
学会了用JFrame等UI,学会了用网络接口,学习了Java