`
tianshi_kco
  • 浏览: 21397 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

c语言之猜数字游戏

 
阅读更多

很久之前我就先自己编写猜数字这个小游戏。这里先附上我从百度百科搜到对猜数字的规则。

游戏规则如下:

通常由两个人玩,一方出数字,一方猜。出数字的人要想好一个没有重复数字的4位数,不能让猜的人知道。猜的人就可以开始猜。每猜一个数字,出数者就要根据这个数字给出几A几B,其中A前面的数字表示位置正确的数的个数,而B前的数字表示数字正确而位置不对的数的个数。

  如正确答案为 5234,而猜的人猜 5346,则是 1A2B,其中有一个5的位置对了,记为1A,而3和4这两个数字对了,而位置没对,因此记为 2B,合起来就是 1A2B。

  接着猜的人再根据出题者的几A几B继续猜,直到猜中(即 4A0B)为止。

百度百科链接如下http://baike.baidu.com/view/358630.htm

规则明白之后,其实我们要做的事情就很明确了。

第一步:我们就是要让计算机随机产生一个0-9不重复的4位数

第二步:我们要输入自己所猜的4个0-9不重复的数字

第三步:判断我们所猜的数字和计算机随机的数字是否吻合,如果不为4A0B,返回第二步

思路明确之后,就是尝试这这些思路转化为c语言,用c语言的方式表达出来。

现在我们来完成第一步,第一步比较简单。我们可以使用rand()来产生一个随机数,不过由于这个函数产生的随机数为一个伪随机数,所以我们必须在一句srand(time(NULL));具体为什么,百度上有很多,我就不再阐述了。不过读者可以下载我的程序,试试把这句话去掉有什么不一样,一试便知。在生产随机数时,我们还要确保所生成的随机数,不能用重复数字,具体实现代码如下。

void getTheGuessNum()
{
	int i,j;
	int flag = 0;		//是否有数字重复标记位。
	srand(time(NULL));
	for (i = 0;i < 4;)
	{
		guess_num[i] = rand() % 10;	//产生0-9的随机数
		for (j = 0;j < i;j ++)
		{
			if (guess_num[j] == guess_num[i])	//四个数字有重复,退出内嵌for
			{
				flag = 1;
				break;
			}
			flag = 0;
		}
		if (flag == 0)	//如果没有重复值,i++,生成下一个随机数
		{
			i++;
		}
	}
}
【注】guess_num为一个全局数组变量。

第一步实现了,我们就要进行我自认为最难得一步了。那就是输入四个数字。也许有朋友会笑我,不就是输入4个数字而已吗?使用scanf函数不就完事了吗?被你的那么难,你是唬人的吧!对于那些初学者来说,他们很有可能编写如下的程序:

int num1,num2,num3,num4;
scanf("%d%d%d%d",&num1,&num2,&num3,&num3);


对于学过数组的朋友来说,他们可能会这样写


int num[4],i;
for(i = 0;i < 4;i ++)
  scanf("%d",&num[i]);


你说以上代码有问题。确实,以上代码没有什么问题,不过那是在对于完完全全输入正确的基础上而言的。不理解我这句话的意思。那我就写一个小程序给你们瞧瞧(其实我也是菜鸟,高手看到请不要喷我)

#include <stdio.h>

void main()
{
	int a;
	printf("请输入一个数字:");
	scanf("%d",&a);
	printf("a = %d\n",a);
}

以上这么一个程序,大家看看有没有错误。其实我可以很负责的告诉大家,这段代码完全没有任何错误的。如果在输入一个数字的情况下,完全可以打印出a的值。那如果就是有人存心搞怪,输入一个非数字的情况下会这么样呢?不要认为这是不可能的事。假如,我输入hgj,那么a的值会为多少呢?截图如下:

至此,大家明白我要表达的意思了没有?不明白的话,请从头看。哈哈。。。。如果明白了,则请继续看下去。

如果大家明白了问题所在,那么这个问题要如何解决了?如果我告诉大家我在输入4个数字压根没有使用scanf()函数,大家会相信吗?其实我使用的函数为getchar()。大家看到这个函数的时候,应该会感到很奇怪,这个函数不是用于输入一个字符的吗?怎么可以用来输入4个数字呢?其实我在写第一个程序的时候确实是使用scanf()函数,代码如下

int inputTheNum()
{
	int i,j;
	for(i = 0;i < 4;)
	{
	//	printf("请输入第%d个数字:",i);
		if(scanf("%d",&input_num[i]) == 1)		//输入正确
		{
			i ++;
		}
		else					//输入错误
		{
			fflush(stdin);		//清除输入内容
			return 3;
		}
	}
	for(i = 0;i<4;i ++)
	{
		if(input_num[i] < 0 || input_num[i] > 9)
			return 2;
		for(j = 0;j < i; j ++)
		{
			if(input_num[j] == input_num[i])
			{
				return 1;
			}
		}
	}
	return 0;
}

scanf()是有返回值的,具体可以查看百度百科http://baike.baidu.com/view/1390039.htm,这里我也不想说太多了。我刚刚开始这样写有一个坏处,那就是我输出4个数字的时候必须用空格或者回车或者tab键分开,只是是太麻烦。因为这几个数字都是一位数的。有时候我想输入1234结果我输入1234之后回车,但是函数inputTheNum()就只把1234保存在input_num的第一个元素里。这时候我又不得不输入另外3个数字。虽然我知道我这是在做无用功,不过我没办法。因为我就想改近一下这个函数,最后我使用如下的方法:

typedef enum
{
	SUCCESS,
	ILLEFAL_CHAR,
	NUMBER_REPEATED,
	NUMBER_BEYOND,
	NUMBER_WITHIN
}return_type;
int inputTheNum()
{
	int temp;
	int count = 0;
	int i,j;
	while(1)
	{
		temp = getchar();
		if (temp == '\n')
		{
			break;
		}
		else if (temp >= '0' && temp <= '9')
		{
			if (count < 4)
			{
				input_num[count] = temp - 0x30;
				count ++;
			}
			else
			{
				while(getchar() != '\n');
				return NUMBER_BEYOND;
			}
		}
		else if(temp == ' ' || temp == '\t')
		{
			continue;
		}
		else 
		{
			while(getchar() != '\n');
			return ILLEFAL_CHAR;
		}
	}
	if (count != 4)
	{
		return NUMBER_WITHIN;
	}
	for(i = 0;i<4;i ++)
	{
		for(j = 0;j < i; j ++)
		{
			if(input_num[j] == input_num[i])
			{
				return NUMBER_REPEATED;
			}
		}
	}
	return SUCCESS;
}


如果我输入的是回车键,那么我就结束这次输入。如果我输入的空格或者tab键,我将忽略这次输入。如果我输入的字母或者符号,我则返回一个错误信息。如果我输入的是一个字符'0'-'9',我就将其转为为数字0-9之后保存在数据里。如果输入的数字的过多或者过少,我都将返回相应的信息。至此,输入过程就完成了。

接下来的一步,比较简单,那就是比较输入的数字和计算机所给的数字。看看答案是几AB

具体算法如下:


void comparisonTheNum()
{
	int i,j;
	for(i = 0; i < 4; i ++)
	{
		for(j = 0;j < 4; j ++)
		{
			if(input_num[j] == guess_num[i] && i == j)
			{
				A_num ++;
			}
			else	if(input_num[j] == guess_num[i])
			{
				B_num ++;
			}
		}
	}
}


这个算法很简单,不再说明。

整个猜数字的主要三个子函数已经实现,那么主函数,也就清晰明了。这里也不再讲述。实在不知道怎么写的人,可以参考我的资料。http://download.csdn.net/detail/tianshi_kco/4605873


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics