很久之前我就先自己编写猜数字这个小游戏。这里先附上我从百度百科搜到对猜数字的规则。
游戏规则如下:
通常由两个人玩,一方出数字,一方猜。出数字的人要想好一个没有重复数字的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