【C语言】扫雷游戏(附源码+思路讲解)

在这里插入图片描述
欢迎来到我的博客!!💃💃
🏡🏡推荐博客:August_._一起持续学习,不断总结,共同进步🎊🎊

思路讲解

文件结构设计

我们学过多文件的形式对函数的声明和定义,现在我们设计三个文件:

game.h //游戏需要的数据类型和函数声明
game.c //游戏中函数的实现
main.c //游戏的测试逻辑

结构分析

定义俩个数组:

char mine[ROWS][COLS] = {0};    //放雷
char show[ROWS][COLS] = {0};	//显示排雷的信息

⼀个棋盘(数组mine)存放布置好的雷的信息,另⼀个棋盘(数组show)存放排查出的雷的信息。在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。俩个数组使⽤同⼀套函数处理,可以使两个数组的类型⼀致,show数组开始时初始化为字符 ’ * ‘,mine数组最开始初始化为字符’0’,布置雷改成’1’。

注意:
扫雷游戏中排查四周时,访问周围的⼀圈8个位置,统计周围雷的个数时会越界,我们为了防⽌越界,可以给数组扩⼤⼀圈,雷还是布置在中间的 9 x 9 的坐标上,周围⼀圈不布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成11 x 11 是⽐较合适。

在这里插入图片描述

初始化棋盘

通过 for 循环遍历二维数组,完成棋盘的初始化。其中第四个参数 “set” 是棋盘初始化的字符。

for(int i=0; i<rows; i++)
        for(int j=0; j<rows; j++)
            qipan[i][j] = set;

打印棋盘

虽然定义了俩个 11 x 11 的数组,但我们只需打印出 show 数组中间 9 x 9 的部分就行了。
在这里插入图片描述

void dayin(char qipan[ROWS][COLS], int row, int col)
{
    int i;
    printf("-----------扫雷游戏-----------\n");
    for(i=0; i<=col; i++) printf("%d ", i);
    printf("\n");
    for(i=1; i<=row; i++){
        printf("%d ", i);
        for(int j=1; j<=row; j++) printf("%c ", qipan[i][j]);
        printf("\n");
    }
}

布置雷

在 game.h 文件中,先宏定义:

 #define COUNT 10    //设置雷的总数

通过while循环不断生成雷的坐标,当该坐标处没有雷时,在该处布置雷,并且变量 counts 减一,进入下次循环;直到 counts 等于0,此时循环结束。

void putmine(char qipan[ROWS][COLS], int row, int col)
{
    int x, y,counts = COUNT;
    while (counts) {
        x = rand()%row + 1;
        y = rand()%col + 1;
        if(qipan[x][y] == '0'){
            qipan[x][y] = '1';
            counts--;
        }
    }
}

统计雷的信息

玩家选择 行、列 后,game.c 文件中的 getmine() 函数会统计此处周围八个点含雷的数量。因为 “雷” 是用字符 ‘1’ 来表示的,如果此处没有 ”雷“ ,则用字符 ‘0’ 来表示。
在ASCII码中,'0' 是 48,'1' 是 49

int getmine(char mine[ROWS][COLS], int x, int y)
{
    return (mine[x-1][y-1] + mine[x-1][y] + mine[x-1][y+1] + mine[x][y-1] + mine[x][y+1] + mine[x+1][y-1] + mine[x+1][y] + mine[x+1][y+1] - 8 * '0');
}

findmine() 函数中:

sum = getmine(mine, x, y);  //接收getmine()返回的数字,即周围雷的总数
show[x][y] = sum + '0';    //将数字转化为字符

排查雷

定义变量 win ,如果 win == ROW*COL-COUNT 条件成立,则排雷成功,游戏结束。

if(win == ROW*COL-COUNT){
	printf("\n恭喜你,排雷成功!\n游戏结束!");
	break;
}

源代码

game.h

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

#define COUNT 10

#define ROW 9
#define COL 9

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

//初始化棋盘
void chushihua(char qipan[ROWS][COLS], int rows, int cols, int set);
//打印棋盘
void dayin(char qipan[ROWS][COLS], int row, int col);
//布置雷
void putmine(char qipan[ROWS][COLS], int row, int col);
//排查雷
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

main.c

#include "game.h"

void menu()
{
    printf(" ----------扫雷游戏------------\n");
    printf("|        【1】 Play            |\n");
    printf("|        【0】 Stop            |\n");
    printf(" ------------------------------\n");
}

void game()
{
    char mine[ROWS][COLS] = {0};//放雷
    char show[ROWS][COLS] = {0};//显示排雷的信息
    //初始化棋盘
    chushihua(mine, ROWS, COLS, '0');
    chushihua(show, ROWS, COLS, '*');
    //打印棋盘
    dayin(show, ROW, COL);
    //布置雷
    putmine(mine, ROW, COL);
    //排查雷
    findmine(mine, show, ROW, COL);
}

int main(void)
{
    int input;
    srand((unsigned int)time(NULL));

    do {
        menu();
        printf("请输入您的选择:");
        scanf("%d",&input);

        switch (input) {
            case 1:    game();
                        break;
            case 0:    printf("\n游戏结束!");
                        break;
            default:   printf("\n输入有误,请重新输入");
        }

    }while (input);

    return 0;

}

game.c

#include "game.h"

//初始化棋盘
void chushihua(char qipan[ROWS][COLS], int rows, int cols, int set)
{
    for(int i=0; i<rows; i++)
        for(int j=0; j<rows; j++)
            qipan[i][j] = set;
}

//打印棋盘
void dayin(char qipan[ROWS][COLS], int row, int col)
{
    int i;
    printf("-----------扫雷游戏-----------\n");
    for(i=0; i<=col; i++) printf("%d ", i);
    printf("\n");
    for(i=1; i<=row; i++){
        printf("%d ", i);
        for(int j=1; j<=row; j++) printf("%c ", qipan[i][j]);
        printf("\n");
    }
}

//放雷
void putmine(char qipan[ROWS][COLS], int row, int col)
{
    int x, y,counts = COUNT;
    while (counts) {
        x = rand()%row + 1;
        y = rand()%col + 1;
        if(qipan[x][y] == '0'){
            qipan[x][y] = '1';
            counts--;
        }
    }
}

//统计雷的信息
int getmine(char mine[ROWS][COLS], int x, int y)
{
    return (mine[x-1][y-1] + mine[x-1][y] + mine[x-1][y+1] + mine[x][y-1] + mine[x][y+1] + mine[x+1][y-1] + mine[x+1][y] + 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, win=0;
    while(win<ROW*COL-COUNT){
        printf("请输入坐标(x y): ");
        scanf("%d %d", &x, &y);

        if(x>=1&&x <= ROW && y >= 1 && y <= COL){
            if(mine[x][y] == '1'){
                printf("\n你踩到雷啦! 游戏结束!!\n");
                dayin(mine, ROW, COL);
                break;
            }

            else{
                int sum = getmine(mine, x, y);
                show[x][y] = sum + '0';
                dayin(show, ROW, COL);
                win++;
            }

            if(win == ROW*COL-COUNT){
                printf("\n恭喜你,排雷成功!\n游戏结束!");
                break;
            }
        }
    }
}

运行截图

以下是部分运行截图,你也可以试着运行下哦!
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值