Mastermind游戏

帮朋友解决个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标记,再用限制条件来排除。

好了就写到这里了,这个方法已经很有效了,再写就是抄袭别人思维了,就没意思了。不过学习一下倒很值得的。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值