C语言实战之猜数游戏

简介: C语言实战之猜数游戏

前言

所涉及的知识内容

1.if 分支语句、do、while、for循环语句
2.随机数的生成与种子的变更
3.数组的设定与获取
在这里插入图片描述

猜数游戏设置步骤

在这里插入图片描述

游戏设计

条件分支(不可玩版)

为了实现最后的猜数游戏,我们先从一个简陋的猜数游戏谈起。设计一个程序,用来显示玩家输入的数值与计算机中设置好的数值的比较结果。

#include<stdio.h>
int main()
{
    int a;//读取的数字
    int ans;//简陋版本设定的目标数字
    ans = 30;//设置需要猜的数为30
    printf("请输入一个你猜测的整数:");
    scanf("%d", &a);
    if (a > ans)
    {
        printf("你猜大了!\n");
    }
    else if (a < ans)
    {
        printf("你猜小了!\n");
    }
    else
    {
        printf("你猜对了!\n");
    }
    return 0;
}
上述程序用到了if 分支语句,不熟悉的朋友可以复习下相关语句。

重复循环(粗糙版)

上述代码虽能展示出玩家所猜的结果与设定数的大小关系,但是却只能玩一次,每猜一次程序就会结束,想猜第二次就需要重新打开程序,这样未免太过无趣。因此我们需要使用do 语句来让程序可以一直重复,直到玩家猜对为止。

#include<stdio.h>
int main()
{
    int a;
    int ans;
    ans = 30;
    do
    {
        printf("请输入一个你猜测的整数:");
        scanf("%d", &a);
        if (a > ans)
        {
            printf("你猜大了!\n");
        }
        else if (a < ans)
        {
            printf("你猜小了!\n");
        }
    } while (a != ans);
    printf("你猜对了!");
    return 0;
}
上述程序用到了do循环语句,不熟悉的朋友可以复习下相关语句。

当然,我们的可以实现重复循环这一要求的语句并不止do语句,我们下面用while语句实现上述要求。

#include<stdio.h>
int main()
{
    int a;
    int ans;
    ans = 30;
    while (1)
    {
        printf("请输入一个你猜测的整数:");
        scanf("%d", &a);
        if (a > ans)
        {
            printf("你猜大了!\n");
        }
        else if (a < ans)
        {
            printf("你猜小了!\n");
        }
        else
        {
            break;
        }
    }
        printf("你猜对了!");
    return 0;
}
上述程序用到了while语句,不熟悉的朋友可以复习下相关语句。
while语句的控制表达式为1,1为真故循环会一直进行,但是当我们猜对了数字,那么就会执行break语句,break语句的作用是跳出循环,如此我们便用while语句完成了循环的要求。

**这里我们来区分以下do语句和while语句的具体区别:
do语句是先循环后判断,无论如何,循环体都会被运行一次。
while语句和for语句都是先判断后循环,循环体可能会一次也不执行。**

数字随机(可玩版)

上述代码虽然能够玩,但是当玩家答对一次后,以后就能一次猜出答案,为了能让游戏的每次答案都不同,提高游戏的可玩性,我们应该让每次的答案都随机起来。下面我们写几组生成随机数的代码。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int retry;
    printf("能够生成0~%d的随机数。\n", RAND_MAX);
    do
    {
        printf("\n生成了随机数%d\n", rand());
        printf("是否再运行一次?否···0     是···1\n");
        scanf("%d", &retry);
    } while (retry == 1);
    return 0;
}
上述程序用到了rand语句,不熟悉的朋友可以复习下相关语句。

介绍以下rand函数:
在这里插入图片描述

使用rand函数需要引用头文件:#include<stdlib.h>
rand的功能:rand函数返回一个范围从0到RAND_MAX的伪随机整数。
rand的返回值:返回生成的伪随机数整数

上述程序虽然能够生成一组随机数,但是当我们多次运行就会发现。每次运行时生成的随机数序列都是一样的,这种rand生成的值并不是真正的随机,因此我们需要对其进行改进。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
    int retry;/*再来一次*/
    srand(time(NULL));/*根据当前时间设置随机数种子*/
    printf("能够生成0~%d的随机数。\n", RAND_MAX);
    do
    {
        printf("\n生成了随机数%d\n", rand());
        printf("是否再运行一次?否···0     是···1\n");
        scanf("%d", &retry);
    } while (retry == 1);
    return 0;
}
上述程序用到了srand语句,不熟悉的朋友可以复习下相关语句。
使用srand设置了种子的值为程序运行的时间,这样就能保证每次运行时候的种子不同自然每次生成的随机数序列就不会相同了!

介绍以下srand函数:
在这里插入图片描述

使用srand函数需要引用头文件:#include<time.h>
srand的功能:srand函数设置生成一系列伪随机整数的起点,简而言之,给rand函数设置一个种子,用于生成后续的随机数序列。如果不适用srand函数,那么rand函数会一开始就把种子值设置为1。

上述代码虽然能够完成随机数生成这一要求,但是,rand函数生成的值为:0~RAND_MAX (32767) ,我们需要的随机数值并不能完全在自己设定的范围之内,因此我们需要进一步改进,设置以下生成数的范围,这样才能让游戏更加具有可玩性。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
    int a;/*输入的值*/
    int ans;/*随机数*/
    srand(time(NULL));/*设置时间种子*/
    ans = rand() % 100;/*生成的随机数除以100的余数赋给ans*/
    puts("请输入一个0~99的数字。");
    do
    {
        printf("请输入一个你猜测的整数:");
        scanf("%d", &a);
        if (a > ans)
        {
            printf("你猜大了!\n");
        }
        else if (a < ans)
        {
            printf("你猜小了!\n");
        }
    } while (a != ans);
    printf("你猜对了!");
    return 0;
}
我们将rand函数生成的随机数除以100再取余数,就能获得一组范围在0~99的随机数
rand()% (a+1) 将范围设置在大于等于0且小于等于a的范围内
b+rand()% (a+1)将范围设置在大于等于b且小于等于b+a的范围内

限制次数(次完美版)

其实上述代码已经能有不错的游戏体验了,但是我们可以让他变得更加有意思,我们可以设置输入次数的限制,使游戏变得更加有趣。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_STAGE 10 /*最多输入的次数!*/
int main()
{
    int a;/*输入的值*/
    int ans;/*随机数*/
    const int max = MAX_STAGE;/*最多输入次数*/
    int remain = max;
    srand(time(NULL));/*设置时间种子*/
    ans = rand() % 100;/*生成的随机数除以100的余数赋给ans*/
    puts("请输入一个0~99的数字。");
    do
    {
        printf("你还剩余%d次机会,请输入你猜测的整数:",remain);
        scanf("%d", &a);
        remain--;
        if (a > ans)
        {
            printf("你猜大了!\n");
        }
        else if (a < ans)
        {
            printf("你猜小了!\n");
        }
    } while (a != ans && remain > 0 );
    if (a != ans)
    {
        printf("\n很遗憾,正确答案为:%d", ans);
    }
    else
    {
        printf("回答正确!\n");
        printf("你用了%d次猜中了。\n",max-remain);
    }
    return 0;
}
这里声明最多次输入次数变量max的时候使用了const使变量的值无法修改,这样就不用担心后续reamin--写成了max--而不自知的情况了(编译器会报错)
在修改数据声明时,const关键字指定该对象或变量不可修改。当跟随成员函数的形参列表时,const关键字指定函数不修改被调用的对象。

保存输入(完美版)

上述代码已经很完美了,但是如果我们再添加保存输入记录的功能,就会使这个游戏更加完美。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_STAGE 10 /*最多输入的次数!*/
int main()
{
    int i;
    int stage = 0;/*已输入次数*/
    int a;/*读取的值*/
    int ans;/*目标的值*/
    int num[MAX_STAGE];/*读取的值的历史记录*/
    srand(time(NULL));
    ans = rand() % 100;
    printf("请输入一个0~99的数字\n");
    do
    {
        printf("你还剩余%d次机会,请输入你猜测的整数:", MAX_STAGE - stage);
        scanf("%d", &a);
        num[stage++] = a;
        if (a > ans)
        {
            printf("你猜大了!\n");
        }
        else if (a < ans)
        {
            printf("你猜小了!\n");
        }
    } while (a != ans && stage < MAX_STAGE);
    if (a != ans)
    {
        printf("\n很遗憾,正确答案为:%d", ans);
    }
    else
    {
        printf("回答正确!\n");
        printf("你用了%d次猜中了。\n",  stage);
    }
    puts("------输入记录-------");
    for (i = 0; i < stage; i++)
        printf("%2d:%4d %+4d\n", i + 1, num[i], num[i] - ans);
    return 0;
}

在这里插入图片描述

为了让玩家的历次记录保存,需要将其储存在数组里面。

总结

游戏代码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_STAGE 10 /*最多输入的次数!*/
int main()
{
    int i;
    int stage = 0;/*已输入次数*/
    int a;/*读取的值*/
    int ans;/*目标的值*/
    int num[MAX_STAGE];/*读取的值的历史记录*/
    srand(time(NULL));
    ans = rand() % 100;
    printf("请输入一个0~99的数字\n");
    do
    {
        printf("你还剩余%d次机会,请输入你猜测的整数:", MAX_STAGE - stage);
        scanf("%d", &a);
        num[stage++] = a;
        if (a > ans)
        {
            printf("你猜大了!\n");
        }
        else if (a < ans)
        {
            printf("你猜小了!\n");
        }
    } while (a != ans && stage < MAX_STAGE);
    if (a != ans)
    {
        printf("\n很遗憾,正确答案为:%d", ans);
    }
    else
    {
        printf("回答正确!\n");
        printf("你用了%d次猜中了。\n",  stage);
    }
    puts("------输入记录-------");
    for (i = 0; i < stage; i++)
        printf("%2d:%4d %+4d\n", i + 1, num[i], num[i] - ans);
    return 0;
}

运行结果

在这里插入图片描述

知识总结

生成随机数的准备工作

生成随机数之前需要基于当前时间设定 ”种子“的值。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
srand(time (NULL));
在最初调用rand函数的时候先调用srand函数设置种子,如果没有调用srand函数,那么rand函数的种子会默认为1,这样产生的数就不够随机。

生成随机数的小技巧

**调用rand函数后会随机生成0~RAND_MAX的随机数,RAND_MAX取决于编译器,大于等于32767.
如果需要将随机数限定在某个范围,可以像下面这样操作:
rand()% (a+1) 将范围设置在大于等于0且小于等于a的范围内。
b+rand()% (a+1)将范围设置在大于等于b且小于等于b+a的范围内。**

三种循环的区别

**do语句是先循环后判断,无论如何,循环体都会被运行一次。
while语句和for语句都是先判断后循环,循环体可能会一次也不执行。**

相关文章
|
27天前
|
算法 C语言 C++
【C语言实战项目】三子棋游戏
【C语言实战项目】三子棋游戏
30 1
|
27天前
|
程序员 C语言
【C语言实战项目】猜数字游戏
【C语言实战项目】猜数字游戏
27 0
【C语言实战项目】猜数字游戏
|
1月前
|
C语言
关于使用C语言编写一个简单的猜数字游戏
关于使用C语言编写一个简单的猜数字游戏
23 0
|
22天前
|
人工智能 机器人 测试技术
【C/C++】C语言 21点桌牌游戏 (源码) 【独一无二】
【C/C++】C语言 21点桌牌游戏 (源码) 【独一无二】
|
26天前
|
程序员 C语言
【C语言实战项目】通讯录(动态增容版)
【C语言实战项目】通讯录(动态增容版)
19 0
|
27天前
|
编译器 定位技术 C语言
【C语言实战项目】扫雷游戏
【C语言实战项目】扫雷游戏
26 0
|
1月前
|
C语言
C语言中的文本冒险游戏
C语言中的文本冒险游戏
19 0
|
15天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
24 0
|
26天前
|
编译器 C语言 C++
【C语言】memset()函数(内存块初始化函数)
【C语言】memset()函数(内存块初始化函数)
26 0
|
2天前
|
存储 C语言
C语言函数的返回值
C语言函数的返回值
7 0