猜数游戏

游戏规则

玩家先输入四个数字,与系统产生的四个1-9之间的不重复的且从小到大排序随机数进行比较,如果错误,根据显示的结果再次进行猜测,直至正确。

游戏原理

1.产生四个1-9之间的不重复的随机数。
2.将其从小到大排序。
3.与玩家输入的数字进行比较。
4.如果有n个数字正确且位置正确的数,则输出nA,如果有m个数字正确,位置不正确的数,则输出mB。
若玩家第一次猜错,则可以根据nAmB这个结果进行合理分析并再次猜测。

实现

先写好头文件
/#include <stdio.h>
/#include <stdlib.h>
/#include <time.h>

生成随机数

步骤

1生成数组
2产生随机数的同时去比较是否重复
3如果重复就重新再产生一个随机数
4如果不重复就保存
5每次i的值正好可以用来判断已经有几个了

首先定义一个数组并初始化,再生成随机数
注:有关生成随机数的内容在‘C语言基础练习-随机数’里面详细介绍过,这里便不再复述。
代码如下

int array[4] = {};
    srand(time(NULL));
    for (int i = 0; i < 4; i++){
        int temp = rand() % 9 + 1;
        
        if (i == 0){//第一个 直接保存 
            array[i] = temp;
        }else{
            //判断前面是否已经存在了
            int j = 0; 
            for(; j <i; j++){
                //比较j对应的值和temp是否相同 
                if(array[j] == temp){
                    //重复了
                //  printf("重复了:%d\n",temp); 
                    break; 
                } 
            }
            //判断是怎么出来的
            if (j == i){
                //将i前面的比较一遍都没发现重复的
                //保存temp值
                array[i] = temp; 
            }else{
                //重复了
                //重新回到当前这一次 
                i--; 
            }
        } 
    }

  • 虽然说随机数在前面的笔记中有介绍过,但是这里有一个新的要求,就是四个数中不能有相同的数字
  • 所以在保存生成的这个数之前,要先判断这个数与之前的数是否相同,若相同,就不能保存,然后重新生成再进行判断,直至生成的数与前面的不同,再保存到数组中。
  • 由代码可知,首先判断这个数是否是第一个生成的数,因为第一个生成的数前面没有数字。所以直接保存即可。
  • 从第二个数字起,就要进行是否相同的判断。
    这里假设已经生成了第四个数字,现在要将其与前三个数进行对比。定义一个整型j,且j = 0,此时i = 3,要将第四个数从第一个数开始进行判断,就用一个for循环,进行次数控制并连续判断,只要进行了i -1次判断且判断数字都不相同,生成的这个数即可保存到数组,如若顺序判断中一旦相同,即停止判断,退出当前for循环。
  • 当退出当前for循环后,若数字有相同的,会再次进行最外层的for循环中的i++从而,而此时i=3,再次生成一个随机数后,i就等于4了,就不会再生成随机数,所以我们在内层for循环执行完或break出来之后,若要再次生成随机数就要进行一下i - -
     if (j == i){
        array[i] = temp; 
        }else{
        i--; 
        }


将数组排序

排序的方法有很多,在这里我们使用冒泡排序将数组按从小到大排好序
(由于在上一篇笔记中介绍过冒泡排序,这里就直接放上代码)
代码如下

    int i,j,t;          //从小到大排序 ;冒泡排序 
    for(i = 0;i < 3;i++){  //控制遍历次数 有N个数,遍历N-1次; 
        for(j =0;j < 4 -i -1;j++){
            if(array[j] > array[j + 1]){
                t = array[j];
                array[j] = array[j + 1];
                array[j + 1] = t;
            }
        }   
    } 

由于这个游戏是让玩家猜数,所以并不需要输出生成的数组,但是在边写代码的时候,可以输出这个数组以便检查是否存在bug。
输出的代码如下

    //输出  
    for (int i = 0; i< 4; i++){
        printf("%d ", array[i]);
    }
    printf("\n");

用户输入,游戏“开始”

用户输入

int input[4],shu;
    printf("请输入四个数字\n");
    for(int a = 0;a < 4;a++){  //用另外一个数组储存输入的数字 
        scanf("%d",&shu);
        input[a] = shu;
    }

这里需要注意的是,要用另一个数组来储存用户输入的数字。即代码中的input。

计算n、m

即在nAmB中的n、m。并判断是否全对,若不对,则告知玩家nAmB,并再次进行猜测,直至猜对。

由上述可得,整个输入及计算过程要放在while(1)的循环里。

计算过程有两种方法。

方法一

分别计算A,B的值
代码如下
首先计算A的值

int num = 0,space1 = 0,a = 0,space2;
    for(int i = 0;i < 4;i++){   //算出数字和位置都正确的个数 
        if(input[a] == array[i]){
            num++;
        }
            a++;
    }

再计算数字正确的个数

    a = 0; 
    while(a < 4){              //算出数字正确的个数 
        for(i = 0;i < 4;i++){
            if(input[a] == array[i]){
            space1++;
            }
        }
        a++;
    } 

在计算B之前,应将a重新变为0,因为在计算A的值之后,a 变成了3。

计算B的值

 space2 = space1 - num;//算出数字正确,位置不正确的个数 ,即B的值
    printf("%dA%dB\n",num,space2);
    if(num == 4){
        printf("猜测正确!");
        break;
    }

用一个if语句,使猜对后跳出while循环。


方法二

A,B一起计算.
代码如下

 while(1){
        //提示输入
        printf("请输入猜测的数字:");
        for (int i = 0; i < 4; i++) {
            scanf("%d", &input[i]);
        }
//
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (org[i] == input[j]) {
                    //数字存在 判断位置
                    if (i == j){
                        aCount++;
                    }else{
                        bCount++;
                    }
                }
            }
        }
        
        //提示用户结果
        printf("%dA%dB\n", aCount, bCount);
        
        //判断是否正确
        if( aCount == 4){
            printf("全对!!!!\n");
            break;
        }else{
            aCount = 0;
            bCount = 0;
        }
    }
  • 玩家输入后,首先判断是否有相同的数字存在。
  • 若存在,则判断位置。
  • 若判断位置正确,就意味着这个数位置,数字都正确,则aCount++。
  • 若判断位置不正确,就意味着这个数位置不正确但数字正确,就bCount++。
  • 最后如果aCount != 4。玩家再次进行猜测,而此时aCount, bCount都要进行清零才能重新正常地进行下一次猜测。

由上述可得,方法二相当于是方法一的优化版,因为方法二的计算过程更加直观,简洁。

将方法一改为函数版

#include <stdio.h>
#include <stdlib.h> 
#include <time.h>

int main(){
    int array[4] = {};
    srand(time(NULL));
    for (int i = 0; i < 4; i++){
        int temp = rand() % 9 + 1;
        
        if (i == 0){//第一个 直接保存 
            array[i] = temp;
        }else{
            //判断前面是否已经存在了
            int j = 0; 
            for(; j <i; j++){
                //比较j对应的值和temp是否相同 
                if(array[j] == temp){
                    //重复了
                //  printf("重复了:%d\n",temp); 
                    break; 
                } 
            }
            //判断是怎么出来的
            if (j == i){
                //将i前面的比较一遍都没发现重复的
                //保存temp值
                array[i] = temp; 
            }else{
                //重复了
                //重新回到当前这一次 
                i--; 
            }
        } 
    }
    
    int i,j,t;          //从小到大排序 ;冒泡排序 
    for(i = 0;i < 3;i++){  //控制遍历次数 有N个数,遍历N-1次; 
        for(j =0;j < 4 -i -1;j++){
            if(array[j] > array[j + 1]){
                t = array[j];
                array[j] = array[j + 1];
                array[j + 1] = t;
            }
        }   
    } 

    
    while(1){
    
    
    int input[4],shu;
    printf("请输入四个数字\n");
    for(int a = 0;a < 4;a++){  //用另外一个数组储存输入的数字 
        scanf("%d",&shu);
        input[a] = shu;
    }
    
    
    int num = 0,space1 = 0,a = 0,space2;
    for(int i = 0;i < 4;i++){   //算出数字和位置都正确的个数 
        if(input[a] == array[i]){
            num++;
        }
            a++;
    }
    
    a = 0; 
    while(a < 4){              //算出数字正确的个数 
        for(i = 0;i < 4;i++){
            if(input[a] == array[i]){
            space1++;
            }
        }
        a++;
    } 
    
    
    space2 = space1 - num;//算出数字正确,位置不正确的个数 
    printf("%dA%dB\n",num,space2);
    if(num == 4){
        printf("猜测正确!");
        break;
    }
    
}
 
    return 0;
}

函数版

#include <stdio.h>
#include <stdlib.h> 
#include <time.h>
void randomNumber(int array[4]);// 生成随机数 
void bubbleSort(int array[4]);//排序 
int game(int array[4]);//进行游戏 

int main(){
    int array[4] = {};
    randomNumber(array);
    bubbleSort(array);//()中的array是指针,指向array这个数组的首地址,这样做可以直接访问地址,修改数据 

    while(1){
        game(array);
    
        if(game(array) == 4){
            printf("猜测正确!");
            break;
        }
    }
    return 0;
}

void randomNumber(int array[4]){
    srand(time(NULL));
    for (int i = 0; i < 4; i++){
        int temp = rand() % 9 + 1;
        
        if (i == 0){//第一个 直接保存 
            array[i] = temp;
        }else{
            //判断前面是否已经存在了
            int j = 0; 
            for(; j <i; j++){
                //比较j对应的值和temp是否相同 
                if(array[j] == temp){
                    //重复了
                //  printf("重复了:%d\n",temp); 
                    break; 
                } 
            }
            //判断是怎么出来的
            if (j == i){
                //将i前面的比较一遍都没发现重复的
                //保存temp值
                array[i] = temp; 
            }else{
                //重复了
                //重新回到当前这一次 
                i--; 
            }
        } 
    }   
}

void bubbleSort(int array[4]){
    
    int i,j,t;          //从小到大排序 ;冒泡排序 
    for(i = 0;i < 3;i++){  //控制遍历次数 有N个数,遍历N-1次; 
        for(j =0;j < 4 -i -1;j++){
            if(array[j] > array[j + 1]){
                t = array[j];
                array[j] = array[j + 1];
                array[j + 1] = t;
            }
        }   
    } 
}

int game(int array[4]){

    int input[4],shu;
    printf("请输入四个数字\n");
    for(int a = 0;a < 4;a++){  //用另外一个数组储存输入的数字 
        scanf("%d",&shu);
        input[a] = shu;
    }
    
    
    int num = 0,space1 = 0,a = 0,space2;
    for(int i = 0;i < 4;i++){   //算出数字和位置都正确的个数 
        if(input[a] == array[i]){
            num++;
        }
            a++;
    }
    
    a = 0; 
    while(a < 4){              //算出数字正确的个数 
        for(int m = 0;m < 4;m++){
            if(input[a] == array[m]){
            space1++;
            }
        }
        a++;
    } 
    
    
    space2 = space1 - num;//算出数字正确,位置不正确的个数 
    printf("%dA%dB\n",num,space2);
    return(num); 
}


//若要输出原来的四个数字,则在array和while之间加入以下代码  
/*  for (int i = 0; i< 4; i++){
        printf("%d ", array[i]);
    }
    printf("\n");
*/
  • 如果使用DEV C++,srand(time(NULL));中可以自动转换,若用Visual studio,则需进行强制转换。srand((unsigned int)time(NULL));
  • 在Visual studio中,输入需要使用vs封装的scanf。scanf_s("%d",&shu);

作者有话说

  • 到此,这个demo就做完啦!
  • 通过这个demo,对各种循环语句运用更加熟练了
  • 并且意识到要用自定义函数来单独进行某个功能的重要性
  • 还有......熟能生巧!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容