C语言实现扫雷游戏(完整版)



头文件定义、函数声明


下面就是扫雷中使用到的所有函数,为了省事我把所有的代码都放在一个C文件中实现

宏定义中设置了游戏的界面布局,以及设置地雷的个数(这里默认的是10个地雷),界面是一个9*9的方格布局


如图:

在这里插入图片描述

代码如下:

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

//布局9*9方格
#define ROW 9
#define COL 9

//多出隐藏的两行两列用来补全边缘棋盘6个方格凑9个方便计算
#define ROWS    ROW + 2
#define COLS    COL + 2

#define MINE_COUNT 10//地雷个数

/*******************************************************************************/

//游戏实现
void play();
//初始化界面布局
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印布局
void DisplayBoard(char board[ROWS][COLS], int rows, int cols);
//布置地雷
void SetMine(char board[ROWS][COLS], int row, int col);
//判断成功排除后剩下的方格数是否等于地雷数
int IsWin(char show[ROWS][COLS], int row, int col);
//使用递归函数来实现周围没地雷时展开多个
void spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
//计算周围地雷个数
int mine_count(char mine[ROWS][COLS], int x, int y); 
//扫雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//递归实现连续排除周围地雷
void spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);

/*******************************************************************************/


函数定义


游戏规则设定


这里使用了函数递归的方式来实现周围8个方格如果都没有地雷的话就一次性展开使用空格来填补,以及通过字符的ASCII码值来计算周围八个方格中地雷的数量以数字形式显示周围地雷个数。

接下来就可以进行简单的排雷操作了,输入坐标进行排雷,直到排完所有雷则通过游戏,如果输入的方格坐标为之前布置的雷坐标那么恭喜你踩到雷了游戏结束,你可以选择继续玩或者直接退出。


如图:

在这里插入图片描述


在这里插入图片描述


代码如下:

int IsWin(char show[ROWS][COLS], int row, int col)
{
    int num = 0;
    //排除一个地雷时便进行累加
    for (int i = 1; i <= row; i++)
    {
        for (int j = 1; j <= col; j++)
        {
            if (show[i][j] == '*')
                num++;
        }
    }
    return num;
}

void spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
    int count = mine_count(mine, x, y);//周围地雷的个数(此时是字符的ASCII码值)

    if (count == 0)
    {
        show[x][y] = ' ';
        int i = 0, j = 0;

        for (i = -1; i <= 1; i++)
        {
            for (j = -1; j <= 1; j++)
            {
                //连续排除时限制范围在棋盘范围内
                if ((x + i) > 0 && (y + i) > 0 && (x + i < ROWS) && (y + j < COLS) && show[x + i][y + j] == '*')
                {        
                    spread(mine, show, x + i, y + j);//递归实现周围如果都没地雷连续排除
                }
            }
        }
    }
    else
    {
        show[x][y] = count + '0';//将字符ASCII码值转换为数字从而显示
    }
}

int mine_count(char mine[ROWS][COLS], int x, int y)
{
    //将周围八个方格中字符的ASCII码值之和减去八个‘0’的值得到周围地雷个数
    return mine[x - 1][y] +
        mine[x - 1][y - 1] +
        mine[x][y - 1] +
        mine[x + 1][y - 1] +
        mine[x + 1][y] +
        mine[x + 1][y + 1] +
        mine[x][y + 1] +
        mine[x - 1][y + 1] - 8 * '0';
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0, y = 0;

    while (1)
    {
        printf("请输入排雷坐标:>");
    loop:
        scanf("%d%d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)//判断坐标是否合法
        {
            if (mine[x][y] == '1')//‘1’为地雷
            {
                printf("你已踩到雷,游戏结束\n");
                DisplayBoard(mine, ROW, COL);
                break;
            }
            else
            {
                spread(mine, show, x, y);//计算周围地雷数量,连续排除无雷的方格
                DisplayBoard(show, ROW, COL);
            }
        }
        else
        {
            printf("请输入正确的坐标:");
            goto loop;
        }
        int ret = IsWin(show, row, col);
        if (ret == MINE_COUNT)//当累加的地雷数量等于布置地雷的数量则说明地雷全部排除
        {
            printf("恭喜你,通关成功!\n");
            break;
        }
    }
}

/*******************************************************************************/

布置地雷


这里使用了rand()函数在该方格没有地雷的情况下随机布置相应的地雷,有地雷的方格值为1,没有地雷的方格值为0,布置完地雷后再使用打印函数将界面布局打印出来


扩展:

在C语言中,我们一般使用 <stdlib.h> 头文件中的rand()函数来生成随机数

int rand (void);        //void 表示不需要传递参数。

但是多次运行上面的代码,你会发现每次产生的随机数都一样

实际上,rand() 函数产生的随机数是伪随机数,是根据一个数值按照某个公式推算出来的,这个数值我们称之为“种子”,我们可以通过 srand() 函数来重新“播种”,这样种子就会发生改变。

void srand (unsigned int seed);

它需要一个 unsigned int 类型的参数。在实际开发中,我们可以用时间作为参数,只要每次播种的时间不同,那么生成的种子就不同,最终的随机数也就不同。


使用<time.h>头文件中的 time() 函数即可得到当前的时间(精确到秒),就像下面这样:

srand((unsigned)time(NULL));

代码如下:

void SetMine(char board[ROWS][COLS], int row, int col)
{
    int count = MINE_COUNT;//布置地雷数量
    while (count)
    {
        //当该方格内没有地雷时随机布置相应数量地雷
        int x = rand() % row + 1;//(行,随机数范围1~9)
        int y = rand() % col + 1;//(列,随机数范围1~9)
        if (board[x][y] == '0')//判断没有地雷
        {
            board[x][y] = '1';//布置地雷
            count--;//直到布置完所有地雷
        }
    }
}

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0, j = 0;
    
    for (i = 0; i <= col; i++)//打印列号
    {
        printf(" %d ", i);
    }
    printf("\n");
    for (i = 1; i <= row; i++)
    {
        printf(" %d ", i);//打印行号
        for (j = 1; j <= col; j++)
        {
            printf(" %c ", board[i][j]);//打印9*9方格内字符布局
        }
        printf("\n");
    }
    printf("\n");
}

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i = 0, j = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = set;//初始化所有方格内的字符
        }
    }
}

/*******************************************************************************/

游戏实现函数


首先初始化游戏布局并打印出来,之后进行布置地雷以及计算周围八个方格中地雷的数量,最后开始扫雷


如图:

在这里插入图片描述


代码如下:

void play()
{
    //随机数种子,time函数的返回值生成时间戳,保证每次随机布置的地雷位置不同
    srand((unsigned int)time(NULL));
    //地雷信息的存储
    char mine[ROWS][COLS] = { 0 };//布置好的地雷信息11*11
    char show[ROWS][COLS] = { 0 };//排查出的地雷信息11*11

    InitBoard(mine, ROWS, COLS, '0');//将方格置为字符‘0’也就是无地雷状态
    InitBoard(show, ROWS, COLS, '*');//将方格内字符初始化为*达到隐藏效果
    DisplayBoard(show, ROW, COL);

    //DisplayBoard(mine,ROW,COL);//显示地雷位置
    SetMine(mine, ROW, COL);
    FindMine(mine, show, ROW, COL);
}

/*******************************************************************************/

菜单函数以及主函数定义


这里是进入游戏的一个简单的选择菜单界面,通过选择(1/2)来执行相应的操作,调用该游戏实现函数以及退出游戏和错误判断


如图:

在这里插入图片描述

代码如下:

int main()
{
    //菜单选择界面
    int input = 0, choose = 0;
    printf("&---------------------------&\n");
    printf("|        1、扫雷            |\n");
    printf("|---------------------------|\n");
    printf("|        2、退出            |\n");
    printf("&---------------------------&\n");
    printf("请选择(1/2)>:");
    do
    {
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            while (1)
            {
                printf("\n");
                play();
                printf("&---------------------------&\n");
                printf("|        1、继续            |\n");
                printf("|---------------------------|\n");
                printf("|        2、退出            |\n");
                printf("&---------------------------&\n");
                printf("请输入你的选择:");
            loop:
                scanf("%d", &choose);
                switch (choose)
                {
                case 1:
                    break;
                case 2:
                    return 0;
                default:
                    printf("请输入正确的选项:");
                    goto loop;
                }
            }
        case 2:
            printf("退出成功!\n");
            return 0;
        default:
            printf("请输入正确的选项:");
            break;
        }
    } while (input);

    return 0;
}

/*******************************************************************************/


总结

  以上就是个人分享的关于扫雷游戏所有的代码,用C语言简单的实现了扫雷这个小游戏,虽然在界面和功能的实现上都很粗糙,但是对于一个初学C语言小白的我来讲也是一个小小的进步,也希望自己继续加油之后写出更优秀的代码

  • 25
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
C语言是一种高效、底层的编程语言,虽然相对于其他语言来说,使用C语言开发3D游戏网盘可能会更复杂,但也是完全可行的。 首先,为了实现3D效果,我们需要使用类似OpenGL或者DirectX这样的图形API,它们提供了强大的图形渲染功能。C语言可以通过调用这些API来实现图形渲染,并处理用户输入、碰撞检测等功能。我们可以使用C语言的指针操作和底层算法来控制运行效率,并且可以利用C语言的内存管理功能,避免内存泄漏和资源浪费问题。 其次,对于网络功能,C语言提供了底层的套接字(Socket)库,我们可以使用该库来实现网络通信。通过套接字,我们可以在服务器和客户端之间传递数据,实现用户在网盘中上传、下载和分享文件的功能。C语言的底层特性使我们可以自定义网络通信协议和数据包格式,提高传输效率。 在开发过程中,我们可以使用C语言的模块化编程思想,将不同的功能模块拆分,并设计适当的接口,以提高代码的复用性和可维护性。同时,C语言还可以通过使用宏、预处理指令等特性实现代码的优化,提高性能。 然而,由于C语言的底层特性,相比其他高级语言,它需要更多的编码工作、对硬件的了解以及对内存管理的谨慎使用。此外,对于3D游戏网盘这样的大型项目,团队合作和代码管理也非常重要。 总的来说,尽管使用C语言开发3D游戏网盘相对复杂,但在充分利用C语言的特性、借助合适的库以及良好的团队协作下,完全可以实现一个高效、功能强大的3D游戏网盘。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请叫我阿杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值