C语言:猜数字(不断改善代码的版本)

制作不易,希望大家多多点赞评论支持。

如果有疑问,在评论区询问,我也会及时寻找解决方法。

一、应用到的知识:scanf、if、while、break、rand、log2、switch

1.  int scanf("格式符", &变量);  返回值为输入的个数,scanf的用法和printf类似

2.  条件语句:if 和 else if 和else 

// 条件1成立,则执行代码块1,不执行代码块2和3;若不成立,则继续看else if条件2
if (条件1){  
    代码块1;
} else if (条件2){
    代码块2;
} else {
    代码块3;
}

3.  循环语句:while

// 条件为真,则一直执行代码块
while(条件){
    代码块;
}

4.  中断语句:break   // 作用是退出循环

5.  int rand(void):是库stdlib.h中的一个函数,生成0-RAND_MAX之间的一个函数

6.  double log2(double x):math.h中的一个函数,数学计算公式,需要强制类型转换为int型

7.  条件语句:switch

// 如果条件和case后面的条件相同,则执行相应代码块
switch (条件) {
  case 条件1: 代码块1; break; // 没有break的话,会继续向下执行代码
  case 条件2: 代码块2; break;
  default: 代码块; break; // 所有条件均不满足,则执行default中的代码块
}

二、猜数字游戏代码改进过程

下面就是整个猜数字游戏一步一步改进的代码!

         最基本的猜数字,这个阶段涉及的知识点很少。

#include 

int main(){
    int randnum = 10; // 自己定义的数字
    int x;      // 输入要猜的数字

    printf("请输入你的猜测:");
    while(scanf("%d", &x) == 1) { // scanf的返回值为输入的个数
        if (x == randnum){ // 判断x是否等于randnum
            printf("恭喜你猜对了!\n");
            printf("游戏结束~");
            break;  // 猜对了,中断循环
        } else {
            printf("猜错了,请再猜一次吧:");
        }
    }
    
    return 0;
}

        猜测自己定义的数字太过无聊,请别人修改又太麻烦,能不能让他自己产生一个随机数呢?
并且漫无目的的猜测很难猜中,有没有提示呢?

1. 产生随机数:可以新增rand函数,然后利用随机种子,让他每次获取不同的随机数

2. 获取提示:使用if 和else if 和 else 来判断随机值与猜测值之间的关系,然后用printf输出

#include 
#include    // for time
#include  // for rand


int main(){
    srand((unsigned int)time(NULL)); // 利用时间初始化随机种子
    int randnum = (rand() % 100) + 1; // 产生1 ~ 100 范围内的随机数
    int x;

    printf("请输入你的猜测:");
    while(scanf("%d", &x) == 1) {
        if (x == randnum){
            printf("恭喜你猜对了!\n");
            printf("游戏结束~");
            break;
        } else if (x > randnum){
            printf("你猜的数太大,请再猜一次吧:");
        } else {
            printf("你猜的数太小,请再猜一次吧:");
        }
    }
    
    return 0;
}

        可不可以自己定义一个范围呢,比如说我输入两端点值,生成的随机数就在这个范围内,那我猜测的数字也就在这个范围?

1. 随机值范围更改:int x = rand() % 100 , 这句话的作用就是产生0-99之间的随机值,若自定义产生M ~ N (M <= N) 之间的值,只需要更改端点即可

#include 
#include 
#include  // for rand


int main(){
    srand((unsigned int)time(NULL)); // 利用时间初始化随机种子
    int x, M, N;

    printf("请分别输入左、右端点的值:");
    while(1){  // 限制 M <= N
        scanf("%d %d", &M, &N);
        if (M > N){
            printf("请重新输入左、右端点的值:");
        } else {
            break;
        }
    }
    
    int randnum = (rand() % (N - M + 1)) + M; // 产生1 ~ 100 范围内的随机数
    printf("请输入你的猜测:");
    while(scanf("%d", &x) == 1) {
        if (x == randnum){
            printf("恭喜你猜对了!\n");
            printf("游戏结束~");
            break;
        } else if (x > randnum){
            printf("你猜的数太大,请再猜一次吧:");
        } else {
            printf("你猜的数太小,请再猜一次吧:");
        }
    }
    
    return 0;
}

        还可以为游戏增加难度吗,比如说游戏最多只能猜测几次?
正常来说,猜测范围内数字都是利用二分法来猜测的,所以,1-100需要猜测 log2 100 < 7 次

1. 猜测次数计算:最小猜测次数为(int)log2(N - M + 1) + 1左右(N-M+1为2的幂时,后面不需要+1,否则需要+1),加上更大的数,是为了降低游戏难度

#include 
#include 
#include  // for rand
#include    // for log2

int main(){
    srand((unsigned int)time(NULL)); // 利用时间初始化随机种子
    int x, M, N;
    int num = 0;

    printf("请分别输入左、右端点的值:");
    while(1){
        scanf("%d %d", &M, &N);
        if (M > N){
            printf("请重新输入左、右端点的值:");
        } else {
            break;
        }
    }
    
    int randnum = (rand() % (N - M + 1)) + M; // 产生1 ~ 100 范围内的随机数

    printf("请输入你的猜测:");
    
    while(scanf("%d", &x) == 1) {
        if (num > ((int)log2(N - M + 1) + 4)){
            printf("\n你猜的次数太多了,游戏失败...\n");
            break; // 游戏失败,退出游戏
        }

        if (x == randnum){
            printf("恭喜你猜对了!\n");
            printf("游戏结束~");
            break;
        } else if (x > randnum){
            printf("你猜的数太大,请再猜一次吧:");
        } else {
            printf("你猜的数太小,请再猜一次吧:");
        }

        /* 
            猜测次数增加,当超过一定值的时候,游戏就失败了
        */
        num++;
        
    }
    
    return 0;
}

        还可以继续改善吗?比如说,将猜数字的这个小游戏封装成一个函数,然后增加一个主界面,之后进行选择!

1. 封装成函数:将主函数代码块中的  除return 0部分放在GuessNum()函数中,然后放在主函数上面即可

2. 主页面选择:添加一个switch进行选择,1的时候是猜数字游戏,2的时候就是退出游戏,其他选择则重新进入主页面

#include 
#include 
#include  // for rand
#include    // for log2 

void GuessNum(){
    srand((unsigned int)time(NULL)); // 利用时间初始化随机种子
    int x, M, N;
    int num = 0;

    printf("请分别输入左、右端点的值:");
    while(1){
        scanf("%d %d", &M, &N);
        if (M > N){
            printf("请重新输入左、右端点的值:");
        } else {
            break;
        }
    }
    
    int randnum = (rand() % (N - M + 1)) + M; // 产生1 ~ 100 范围内的随机数
    printf("请输入你的猜测:");
    while(scanf("%d", &x) == 1) {

        if (num > ((int)log2(N - M + 1) + 4)){
            printf("\n你猜的次数太多了,游戏失败...\n");
            break; // 游戏失败,退出游戏
        }

        if (x == randnum){
            printf("恭喜你猜对了!\n");
            printf("游戏结束~");
            break;
        } else if (x > randnum){
            printf("你猜的数太大,请再猜一次吧:");
        } else {
            printf("你猜的数太小,请再猜一次吧:");
        }

        // 猜测次数增加,当超过一定值的时候,游戏就失败了
        num++;
        
    }
}

int main(){
    while(1){
        printf("\n\n");
        printf("**********************\n");
        printf("*** 欢迎来到小游戏 ***\n");
        printf("*** 1、猜数字游戏  ***\n");
        printf("*** 2、退出游戏    ***\n");
        printf("**********************\n");
        printf("\n\n");

        int choice;
        printf("请输入你的选择:");
        scanf("%d", &choice);
        switch(choice){
            case 1: 
                printf("猜数字游戏开始~\n\n"); 
                while(1){
                    GuessNum();

                    getchar(); // 将缓冲区的回车释放掉,保证下面的scanf正常运行
                    char ch;
                    printf("\n\n是否退出此游戏(输入n退出,其他则重新开始游戏): ");
                    scanf("%c", &ch);
                    if (ch == 'n'){
                        break;
                    }
                }
                break;
            case 2:
                printf("退出游戏成功!");
                exit(0);
                break;
            default:
                printf("选择错误,重新进入主页面。");
        }
    }
    
    return 0;
}

三、最终代码

#include 
#include 
#include  // for rand
#include    // for log2 

void GuessNum(){
    srand((unsigned int)time(NULL)); // 利用时间初始化随机种子
    int x, M, N;
    int num = 0;

    printf("请分别输入左、右端点的值:");
    while(1){
        scanf("%d %d", &M, &N);
        if (M > N){
            printf("请重新输入左、右端点的值:");
        } else {
            break;
        }
    }
    
    int randnum = (rand() % (N - M + 1)) + M; // 产生1 ~ 100 范围内的随机数
    printf("请输入你的猜测:");
    while(scanf("%d", &x) == 1) {

        if (num > ((int)log2(N - M + 1) + 4)){
            printf("\n你猜的次数太多了,游戏失败...\n");
            break; // 游戏失败,退出游戏
        }

        if (x == randnum){
            printf("恭喜你猜对了!\n");
            printf("游戏结束~");
            break;
        } else if (x > randnum){
            printf("你猜的数太大,请再猜一次吧:");
        } else {
            printf("你猜的数太小,请再猜一次吧:");
        }

        // 猜测次数增加,当超过一定值的时候,游戏就失败了
        num++;
        
    }
}

int main(){
    while(1){
        printf("\n\n");
        printf("**********************\n");
        printf("*** 欢迎来到小游戏 ***\n");
        printf("*** 1、猜数字游戏  ***\n");
        printf("*** 2、退出游戏    ***\n");
        printf("**********************\n");
        printf("\n\n");

        int choice;
        printf("请输入你的选择:");
        scanf("%d", &choice);
        switch(choice){
            case 1: 
                printf("猜数字游戏开始~\n\n"); 
                while(1){
                    GuessNum();

                    getchar(); // 将缓冲区的回车释放掉,保证下面的scanf正常运行
                    char ch;
                    printf("\n\n是否退出此游戏(输入n退出,其他则重新开始游戏): ");
                    scanf("%c", &ch);
                    if (ch == 'n'){
                        break;
                    }
                }
                break;
            case 2:
                printf("退出游戏成功!");
                exit(0);
                break;
            default:
                printf("选择错误,重新进入主页面。");
        }
    }
    
    return 0;
}

你可能感兴趣的:(c语言,游戏)