帮朋友解决个java编程问题。
问题描述:Mastermind Game,就是一个博弈游戏,靠猜测来取胜的娱乐游戏。
简单描述就是:系统先随机生成四个数字,然后用户输入有效范围内的四个数字,程序对两组数字作对比:如果用户输入的四个数字中,某个数字的位置和大小都正确,那么就算一个黑球;如果数字正确位置不正确,算一个白球;否则,不给球。结果显示有几个黑球几个白球。
用户每一局有三次输错的机会,若有一次输对了,就输出“congratulation!” 跳出这一局;如果三次都没输入正确,那么三次之后,输入ja再继续(ja就是ok的意思),然后写出代码逻辑吧:
do
{
产生随机数;
while(m<3)
{
用户输入四个数字;
if(有一个数字和系统的不对应)
{
for(循环)
{
for(循环)
{
做判断,打印出哪个数字正确对应了;
}
}
}
if(四个数字全都正确对应)
{
打印congratulation! du benutzt nur,跳出while循环;
}
if(有一个数字和系统的不对应)
{
打印Sorry,verloren;
}
系统打印noch einmal,ja oder nein?,等待用户输入,再判断
}
}while(输入ja)
刚开始是检测出了一点bug,比如:
用来循环三次的m再次进入while循环时候,没有做初始化操作导致进入死循环;
do_while循环的while放错了地方导致的奇怪的输入;
其实,这个小程序最最核心的问题也就是在那两层for循环上。
刚开始的代码是:
for(int k=0;k<arry1.length;k++)
{
for(int j=0;j<arry.length;j++)
{
if(arry1[k]==arry[j])
{
System.out.println(+arry[j]+"\t");
}
}
}/*输出相同的数*/
其中array1 表示自己输入的数组;array 表示系统生成数的数组。
这样只对数值做判断,就没有顾及到顺序性。很明显bug。
期间联想到过冒泡法快排一类的算法,想启发点思路,可是这是两个有序数组比较,不是单数组排序。
如果严格按顺序要求,那么只需要一个for循环就可以:
int j = 0; //j表示匹配的个数
for(int k=0;k<arry1.length;k++)
{
if(arry1[k]==arry[k])
{
System.out.println("the right data is:"+arry[k]+"\t"); //这一句打印绝对匹配的数字
j++;
}
}
可是按游戏规则,数值匹配但位置不匹配的,要发一个白球的。
【比如,系统生成5124,我输入2152,那么应该输出一个黑球一个白球。注意这里是输出一个白球而不是两个,因为在5124中只有一个数字2,在第一次匹配时候已经用掉了,第四次匹配就不能再用了。】
改一下程序:
for(int k=0;k<arry1.length;k++)
{
for(int j=0;j<arry.length;j++)
{
if(arry1[k]==arry[j] && k == j)
{
System.out.printf("big match: k = %d ,j = %d \n",k,j);
System.out.printf("black ball.......,the number is %d \n\n",arry1[k]);
break;
}
if(arry1[k]==arry[j] && k != j)
{
System.out.printf("little match: k = %d ,j = %d \n",k,j);
System.out.printf("write ball******,the number is %d \n\n",arry1[k]);
break;
}
}
}/*输出相同的数*/
这样的话,就既判断了数值,有判断了位置。
可还是有bug:有时会把应该是黑球的数字,判断成白球输出。
比如系统输出1314,我输入2215,那么我输入的2215中的1,会与系统中1314的第一个1匹配,输出白球然后退出内层循环。而实际上应该与1314中第二个1匹配输出黑球后再退出才符合逻辑的。
这个程序就到这里吧,有兴趣的朋友可以参考:
http://blog.csdn.net/foxkiller/article/details/6127764
这篇文章中博主把结果分为三类(摘):
“一是 O ,表示位置和颜色都对;一是 P ,表示颜色对,但位置不对;一是 X ,表示位置和颜色都不对。
从算法上来讲,比较的过程是要有优先级的。即,先比较 O ,再比较 P ,最后一种剩余的情况就是 X 。
比如正确答案是 1112 ,用户猜测的数据是 1212 ,如果是平行比较的话,会得出结果是 OPOO ,但实际的结果应该是 OXOO ,因为猜测的第二个数字“ 2 ”在答案中已经没有可以匹配的数据了。因而应该是 X ,但是因为没有优先比较 O ,而是顺序比较每人个数字,就会出现 X 这样的情况。
而优先比较完 O 之后,需要把比较过的数据删除。”
“用一个讨巧的方法,把比较过的数据变成“ -1 ”,这样在下一轮比较的时候加一个条件限制一下 -1 的情况就可以实现把比较过的数据删除了。”
这里重点要提及的就是***优先级思想***。
这个思想类似于做一个flag标记。没有讨巧的感觉,倒是觉得很有效。排除法的一个有效思想就是:对无效数据做flag标记,再用限制条件来排除。
好了就写到这里了,这个方法已经很有效了,再写就是抄袭别人思维了,就没意思了。不过学习一下倒很值得的。