C语言——扫雷游戏最全讲解

简介: 《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。

一、扫雷游戏简介

《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
image.png

二、扫雷游戏设计思路讲解

首先我们需要将总体的代码分成3个部分来实现:
1.test.c 扫雷游戏的测试实现
2.game.h 扫雷游戏的函数声明
3.game.c 扫雷游戏的实现

2.1扫雷游戏菜单的打印

{
    printf("*****************```js

*\n");

printf("************1.play************\n");
printf("************0.exit************\n");
printf("******************************\n");

}


打印出游戏菜单之后,通过switch语句使用户进行一定的选择,如用户选择‘1’,则将进入扫雷游戏,选择‘0’则退出扫雷游戏,如果输入其他的数字,则将提示用户''输入错误,请重新输入。''
代码如下:

{

int input = 0;
menu();
printf("请输入:>>");
scanf("%d", &input);
switch (input)
{
case 1:
    game();
    break;
case 0:
    printf("退出扫雷游戏\n");
    break;
default:
    printf("输入错误,请重新输入\n");
    break;
}

return 0;

}


## 2.2对扫雷游戏棋盘进行一定的初始化
我们此此设计的扫雷游戏为最初级的扫雷游戏,如果我们想要打印一个扫雷棋盘,我们自然而然的会想到用创建二维数组的方式来创建。在此我们可以创建一个9*9的二维数组来实现此次的扫雷游戏。
但是创建9*9的二维数组会遇到一些问题,如数组越界问题,为什么会遇到数组越界问题呢,让我们往下看:

![image.png](https://ucc.alicdn.com/pic/developer-ecology/1bdfa570c19d44a7a30e77ba2d31```js

4cec.png)
如果我们要排查图中红框的位置,那么我们需要遍历的 就是篮框所示的位置,而这就会涉及到[数组越界]问题。
所以我们为了避免数组越界问题,我们干脆创建一个11 *11的二维数组来作为扫雷游戏的棋盘。
又因为之后方便管理代码,我们可以这样定义扫雷棋盘的二维数组:

#define COL 9
#define ROWS ROW+2
#define COLS COL+2

接下来我们直接定义一个叫init_board的函数来对扫雷游戏的棋盘进行一定的初始化,代码如下:

void init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = set;//set 既可以表示‘0’,又可以表示‘*’
        }
    }
}

2.3对扫雷游戏进行棋盘打印

接下来我们对棋盘进行打印操作,我们利用for循环来进行棋盘的打印操作,我们可以定义一个display_board函数来实现该操作,代码实现如下:

void display_board(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    //定义列号
    for (j = 0; j <= col; j++)
    {
        printf("%d ", j);
    }
    printf("\n");
    for (i = 1; i <= row; i++)//定义行号
    {
        printf("%d ", i);
        for (j = 1; j <= col; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }

}

image.png

2.3扫雷游戏的布雷操作

接下来我们进行布雷操作,布雷这一操作是随机的,不确定的,所以我们需要用到rand函数来产生随机数字来实现这一操作,而使用rand我们就不得不使用到srand以及时间戳,所以我们可以自定义一个==set_mine==函数来实现此项功能。
代码如下:

{
    //例如埋10个雷
    int count = EASY_COUNT;
    while (count)
    {
        int x = rand() % row + 1;
        int y = rand() % row + 1;
        if (mine[x][y] == '0')
        {
            mine[x][y] = '1';//埋雷的核心操作
            count--;
        }
    }
}

运行截图如下:
image.png

2.4扫雷游戏排雷的实现

我们可以自定义一个==find_mine== 函数来实现该操作,在该函数中,我们首先需要输入一个合格的坐标数值,通过该函数来判断这个坐标是合格的还是已经被排查过的或者可能是雷,则游戏结束。在排查雷的过程中,我们如果没有排查到雷的话,则需要对排查坐标周围对雷的数量进行遍历操作,所以我们需要再自定义一个get_mine_count函数来实现该操作。

{
    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');
}

完整的find_mine函数如下:

{
    int x = 0;
    int y = 0;
    int win = 0;
    while (win < row * col - EASY_COUNT)
    {
        printf("请输入要查询的坐标:》");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            //如果坐标被排查过
            if (show[x][y] == '*')
            {
                if (mine[x][y] == '1')
                {
                    printf("很遗憾,你被炸死了\n");
                    display_board(show, ROW, COL);
                    break;
                }
                else
                {
                    int count = get_mine_count(mine, x, y);
                    show[x][y] = count + '0';
                    display_board(show, ROW, COL);
                    win++;
                }
            }
            else
            {
                printf("该坐标已经被排查过了\n");
            }
        }
        else
        {
            printf("坐标非法,请重新输入\n");
        }
    }
    if (win == row * col - EASY_COUNT)
    {
        printf("恭喜你,排雷成功\n");
        display_board(show, ROW, COL);
    }
}

test.c的完整代码

//扫雷游戏
#include"game.h"
void menu()
{
    printf("******************************\n");
    printf("************1.play************\n");
    printf("************0.exit************\n");
    printf("******************************\n");
}
void game()
{
    //设计两个数组存放信息
    char mine[ROWS][COLS] = { 0 };
    char show[ROWS][COLS] = { 0 };
 //初始化棋盘
    //mine 初始化为'0'
    //show 初始化为'*'
    init_board(mine, ROWS, COLS, '0');
    init_board(show, ROWS, COLS, '*');
    //打印棋盘
    //display_board(mine, ROW, COL);
    //display_board(show, ROW, COL);
    //布雷
    set_mine(mine, ROW, COL);
    //排雷
  //display_board(mine, ROW, COL);
    display_board(show, ROW, COL);
    find_mine(mine, show, ROW, COL);
}
int main()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    menu();
    printf("请输入:>>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
        game();
        break;
    case 0:
        printf("退出扫雷游戏\n");
        break;
    default:
        printf("输入错误,请重新输入\n");
        break;
    }

    return 0;
}

game.h的完整代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
 
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//初始化棋盘
void init_board(char board[ROWS][COLS],int rows,int cols,char set);
//打印棋盘
void display_board(char board [ROWS][COLS], int row, int col);
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col);
//排雷
void find_mine(char mine[ROWS][COLS], char shoe [ROWS][COLS],int row, int col);

==game.c的完整代码:==

# define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    //定义列号
    for (j = 0; j <= col; j++)
    {
        printf("%d ", j);
    }
    printf("\n");
    for (i = 1; i <= row; i++)//定义行号
    {
        printf("%d ", i);
        for (j = 1; j <= col; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }

}

//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
    //例如埋10个雷
    int count = EASY_COUNT;
    while (count)
    {
        int x = rand() % row + 1;
        int y = rand() % row + 1;
        if (mine[x][y] == '0')
        {
            mine[x][y] = '1';//埋雷的核心操作
            count--;
        }
    }
}


int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
    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 find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int win = 0;
    while (win < row * col - EASY_COUNT)
    {
        printf("请输入要查询的坐标:》");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            //如果坐标被排查过
            if (show[x][y] == '*')
            {
                if (mine[x][y] == '1')
                {
                    printf("很遗憾,你被炸死了\n");
                    display_board(show, ROW, COL);
                    break;
                }
                else
                {
                    int count = get_mine_count(mine, x, y);
                    show[x][y] = count + '0';
                    display_board(show, ROW, COL);
                    win++;
                }
            }
            else
            {
                printf("该坐标已经被排查过了\n");
            }
        }
        else
        {
            printf("坐标非法,请重新输入\n");
        }
    }
    if (win == row * col - EASY_COUNT)
    {
        printf("恭喜你,排雷成功\n");
        display_board(show, ROW, COL);
    }
}

代码运行示例:
image.png
image.png

相关文章
|
1月前
|
机器学习/深度学习 C语言
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
【8月更文挑战第5天】本篇文章用C语言采用多文件编写实现了一个基础的扫雷游戏(附源码),并讲解了关于函数递归的基础概念及其相对应的习题练习(附源码)
35 1
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
|
2月前
|
存储 C语言 开发者
C语言实战 | Flappy Bird游戏
【7月更文挑战第4天】Flappy Bird是由越南开发者制作的简单却极具挑战性的游戏,玩家需控制小鸟穿越水管障碍。游戏涉及角色初始化、显示和更新。小鸟和水管结构体存储数据,使用变量和数组。初始化小鸟和水管,显示背景、小鸟和水管,更新小鸟位置及碰撞检测。代码示例展示了小鸟和水管的状态管理,当小鸟与管道碰撞或触地时,游戏结束。游戏的成功在于其独特的虐心体验。
51 0
C语言实战 | Flappy Bird游戏
|
1月前
|
算法 编译器 C语言
【C语言篇】猜数字游戏(赋源码)
rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的⼤⼩是依赖编译器上实现的,但是⼤部分编译器上是32767。
|
1月前
|
C语言
扫雷(C语言)
扫雷(C语言)
34 4
|
2月前
|
存储 编译器 C语言
|
2月前
|
存储 编译器 C语言
C语言实战 | “贪吃蛇”游戏
【7月更文挑战第5天】在C语言实战中,本文档介绍了如何构建一个简单的“贪吃蛇”游戏。游戏的核心是控制蛇移动并增长,当吃掉食物时,蛇的身体变长。数据结构使用固定大小的数组表示蛇的位置,变量存储食物位置和蛇的长度。初始化后,利用非阻塞式`getKey()`函数实现WASD键盘控制蛇的运动方向。虽然蛇的边界检测和吃食物后的增长尚未详细说明,但提到了这些问题作为练习留给读者解决,并预告将在后续章节讨论模块化编程以简化复杂代码。
77 0
C语言实战 | “贪吃蛇”游戏
|
2月前
|
存储 数据管理 C语言
C语言实战 | 使用链表完成“贪吃蛇”游戏
【7月更文挑战第1天】整体思维,即系统思维,强调以整体视角理解事物。在编程中,结构体体现这种思想,将相关变量打包处理。示例展示了如何用链表而非数组实现“贪吃蛇”游戏,链表提供了更灵活的动态数据管理。一系列代码图片详细描绘了链表结构体在游戏中的应用,包括节点定义、移动、碰撞检测等,凸显了使用链表的优势和代码的清晰组织。
32 0
C语言实战 | 使用链表完成“贪吃蛇”游戏
|
3月前
|
存储 C语言
C语言实战 | “贪吃蛇”游戏重构
在程序设计中,模块化思维至关重要,尤其对于复杂项目,它帮助分解任务,便于团队协作。以“贪吃蛇”游戏为例,游戏涉及两个角色:蛇和食物。使用数组存储蛇的位置,变量存储食物位置。游戏流程分为初始化、显示和更新数据。初始化时,食物位置随机,蛇的位置根据数组设定。显示数据则根据这些信息在屏幕上呈现角色。更新数据时,处理蛇的移动和增长以及食物的生成和消失。类似地,通过模块化方法可开发“打砖块”游戏,涉及球、球拍和砖墙,每个角色都有相应数据结构和更新逻辑。通过这种方式,游戏开发就像搭建积木,遵循框架逐步实现。
59 0
C语言实战 | “贪吃蛇”游戏重构
|
3月前
|
C语言
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
21 1
|
3月前
|
C语言
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
21 1