0 Comments

综合运用--猜数字游戏

发布于:2012-12-20  |   作者:广州网站建设  |   已聚集:人围观

   猜数字(又称 Bulls and Cows )是一种大概于20世纪中期兴起于英国的益智类小游戏。一般由两个人玩,也可以由一个人和电脑玩,在纸上、在网上都可以玩。这种游戏规则简单,但可以考验人的严谨和耐心,而这也正是程序员所需要的优秀品质。

标准规则如下:

    通常由两个人玩,一方出数字,一方猜。出数字的人要想好一个没有重复数字的4位数,不能让猜的人知道。猜的人就可以开始猜。每猜一个数字,出数者就要根据这个数字给出几A几B,其中A前面的数字表示位置正确的数的个数,而B前的数字表示数字正确而位置不对的数的个数。如正确答案为 5234,而猜的人猜 5346,则是 1A2B,其中有一个5的位置对了,记为1A,而3和4这两个数字对了,而位置没对,因此记为 2B,合起来就是 1A2B。接着猜的人再根据出题者的几A几B继续猜,直到猜中(即 4A0B)为止。

    我们发现,整个游戏的过程,实际上是一个逐个数字进行判断的过程,判断数字是否在正确的位置上;判断数字是否正确。而这些判断,正是条件结构的用武之地。根据游戏的规则,我们将这个游戏实现如下。其中可能有某些函数我们还不太熟悉,没关系,我们只要清楚这些函数的作用,在稍后的章节中,我们会做更加详细的介绍。广州网站建设


  1. #include <stdio.h> 
  2. // 引入随机函数srand()、rand()所在的头文件  
  3. #include <stdlib.h> 
  4. // 引入时间函数time()所在的头文件  
  5. #include <time.h> 
  6. // 引入字符查找函数strchr()所在的头文件  
  7. #include <string.h>    
  8.  
  9. int main()  
  10. {  
  11.     // 定义保存目标数字的字符数组  
  12.     char bull[5] = "";  
  13.     srand((int)time(NULL));  
  14.     // 利用rand()函数产生一个四位随机数,  
  15.     // 并利用sprintf()函数将其转换成字符串,保存在bull字符数组中  
  16.     sprintf(bull,  
  17.         "%d", rand()%10000);  
  18.       
  19.     // 定义表示猜测数字的字符数组  
  20.     char cow[5] = "";  
  21.     // 定义表示猜测状况的A和B  
  22.     int A = 0;  
  23.     int B = 0;  
  24.     // 猜测次数,最开始是第一次  
  25.     int count = 1;  
  26.       
  27.     // 构造一个循环结构,只要没有完全猜对,  
  28.     // 就继续下一次猜测  
  29.     while(4!=A)  
  30.     {  
  31.         // 判断是否超过次数限制  
  32.         // 最多猜测10次  
  33.         if(count > 10)     
  34.         {  
  35.             puts("sorry,you lost. :-(");  
  36.             // 跳出猜测循环,结束游戏  
  37.             break;  
  38.         }  
  39.         // 输出当前次数  
  40.         printf("%d :",count);  
  41.  
  42.         // 获取用户输入的猜测数字  
  43.         // 因为需要与目标数字进行比对,  
  44.         // 所以将输入作为字符串(%s),而不是作为一个整数(%d)  
  45.         scanf("%s",cow);  
  46.         // 采用循环结构,逐个字符比对输入数字(cow)和目标数字(bull)  
  47.         for(int i = 0; i<4; ++i)  
  48.         {  
  49.             // 判断当前字符是否相同  
  50.             if(bull[i] == cow[i] )  
  51.             {  
  52.                 // 如果相同,则表示数字正确且位置正确,  
  53.                 // A的值增加1  
  54.                 ++A;  
  55.             }  
  56.             else  // 否则,判断当前数字是否是正确数字  
  57.             {  
  58.                 // 在目标字符串中查找当前字符  
  59.                 char* p = strchr( bull, cow[i]);  
  60.                 // 如果p不是一个空指针(C语言中用NULL或者0表示),  
  61.                 // 则表示目标字符串中有这个字符,当前字符是正确数字,  
  62.                 // B的值增加1  
  63.                 if(0 != p)  
  64.                     ++B;  
  65.             }  
  66.         }  
  67.         // 输出此次猜测的结果  
  68.         printf("%s : %dA%dB\n",cow,A,B);  
  69.         // 如果完全猜测正确,则输出最终结果,结束游戏  
  70.         if(4 == A)  
  71.         {  
  72.             printf("you win! the bull is %s.",bull);  
  73.             break;  
  74.         }  
  75.         // 否则,开始下一次猜测,次数增加1,A和B数据归零  
  76.         ++count;  
  77.         A = 0;  
  78.         B = 0;  
  79.     }  
  80.        
  81.     return 0;  
  82. }  

    在这个例子中,我们多次用到了条件结构,在不同的场景下,条件结构发挥着不同的作用。首先是在while语句中的一个简单条件判断(if(count > 10) ),它会根据当前次数(count)是否小于最大次数限制而决定是否结束整个游戏;其次就是for语句中的一个嵌套的条件结构,它会首先判断当前字符是否与目标字符相同,如果相同则让A的值增加1,反之,则利用嵌套的条件结构开始第二次判断,看当前字符是否在目标数字字符串中,如果在(0 != p),则表示当前字符是一个正确数字,B的值相应地增加1;最后,我们还会用条件结构判断此次猜测是否完全正确(if(4 == A)),如果完全正确,就输出结果,结束游戏循环,反之,则数据归零并开始下一次循环。这个例子,综合地展示了条件结构对程序执行流程的控制,我们可以用条件结构来判断循环是否需要提前结束;可以判断是否满足某个条件而执行某些动作(如果猜测完全正确,就输出最终结果);也可以将条件结构与for语句组合使用,对某一个序列的数据(数组)进行逐个判断;我们更可以将条件结构嵌套,实现多个条件的逐级多个判断。

     实际上,我们这里利用随机数产生一个四位数的方法是存在缺陷的,例如,它无法保证所有产生的数字都是四位数,即使是四位数,它也无法保证这个四位数的所有数字都不相同。这样,就要求我们使用条件结构对数字的合法性进行验证。这个问题,就留给大家自己去动手解决了,相信大家一定可以利用条件结构解决这个问题,从中体会到编程的乐趣。

   总之,条件结构在C语言中的应用方式是灵活多样的,我们应该在实践中合理地加以选用,以达到对程序流程的灵活控制。

飞机