您的位置:首页 > 编程语言 > C语言/C++

c语言之猜数字游戏

2012-09-28 15:44 302 查看
     很久之前我就先自己编写猜数字这个小游戏。这里先附上我从百度百科搜到对猜数字的规则。
游戏规则如下:
       通常由两个人玩,一方出数字,一方猜。出数字的人要想好一个没有重复数字的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键分开,只是是太麻烦。因为这几个数字都是一位数的。有时候我想输入1,2,3,4结果我输入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之后保存在数据里。如果输入的数字的过多或者过少,我都将返回相应的信息。至此,输入过程就完成了。



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

具体算法如下:

 

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

 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息