扫雷游戏详解

1. 游戏描述

扫雷游戏
可以从以上图片看出扫雷游戏的规则是:如果排查到雷游戏结束,没排查到那么就显示周围8个坐标是否有雷,有多少个雷。
获胜判定:整个棋盘都被排查完了只剩下有雷的格子那么游戏胜利.
游戏需求:游戏菜单,初始化棋盘,打印棋盘,布置雷,排查雷.

2. 实现思路

创建三个文件分别为:
test.c:测试游戏的文件
game.c实现游戏功能的文件
game.h:包含游戏功能里的函数声明及库函数的头文件

3. 讲解思路

3.1.菜单打印和建立框架

利用do while和Switch搭起菜单的选择(选择1为开始游戏,选择0为退出游戏,选择其他数字则提示玩家选择错误)和游戏进入的框架

int main()
{
    int input = 0;
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("输入错误,重新输入\n");
        }
    } while (input);
    return 0;
}
void menu()
{
    printf("********************************\n");
    printf("*******   扫雷游戏   ***********\n");
    printf("*****1.开始游戏  0.退出游戏*****\n");
    printf("********************************\n");
}

3.2.game函数的游戏思路

实现定义出来个数组一个用来布置雷,一个用来隐藏游戏的界面给玩家排查.

 char mine[ROWS][COLS];//布置雷在此数组
 char show[ROWS][COLS];//隐藏界面全为*

当然如果我们要改雷的数量不定义一个宏定义是要改很多地方的,而宏定义我们只需要改一个地方其他地方就会跟着改变.

#define ROW 9
#define COL 9

在系统排查雷时排查到边上的8个坐标是否有雷那么会导致数组越界所以我们还要定义两个宏定义让数组成1111的数组,而我们排查时用99的数组就可以避免数组越界了.

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

定义完数组后,下面是game函数的实现代码:

void game()
{
    char mine[ROWS][COLS];//布置雷在此数组
    char show[ROWS][COLS];//隐藏界面*
    Init_Board(mine, ROWS, COLS, '0');
    Init_Board(show, ROWS, COLS, '*');
    //打印棋盘
    //print(mine, ROW, COL);
    print(show, ROW, COL);
    //布置雷
    Layout_lightning(mine, ROW, COL);
    print(mine, ROW, COL);
    //排查雷
    Check(mine, show, ROW, COL);
}

3.3.game.c文件中游戏功能的实现

初始化棋盘

我们在我们传入参数是加上’0’或号传给函数以此来初始化两个数组,函数定义一个变量接收传入的参数是’0’还是号然后初始化为这个字符.

void Init_Board(char board[ROWS][COLS], int rows, int cols, char ret)
{
    int i = 0;
    for (i = 0; i < rows; i++)
    {
        int j = 0;
        for (j = 0; j < cols; j++)
        {
            board[i][j] = ret;
        }
    }
}

打印棋盘

利用循环嵌套来打印这两个棋盘,打印后因为棋盘是9*9或者更大所以我们在行和列边上加上坐标来更好的让玩家输入坐标.

void print(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    printf("-------扫雷游戏-------\n");
    显示行坐标
    for (i = 0; i <= row; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    for (i = 1; i <= row; i++)
    {
       //显示列坐标
        printf("%d ", i);
        int j = 0;
        for (j = 1; j <= col; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
}

布置雷

布置雷给mine数组,布置前我们可以在game.c文件定义雷的数量,之后要改雷的数量就好改些.(布置的雷用’1’显示)

#define RAY 10
利用随机数来随机布置雷的坐标.
  **注**:单用rand函数是不能让随机数随机的,我们要加是一个srand函数和time时间戳来给rand生成随机数,srand在整个工程出现一次就可以了,所以我们把srand定义在主函数就行,还有rand和srand,还有time是库函数所以要在自己的game.h内包含库函数的头文件.
//time的参数不用就定义为空指针(NULL)
//把time的返回值强制转换为无符号的int类型
 srand((unsigned int)time(NULL));
void Layout_lightning(char board[ROWS][COLS], int row, int col)
{
    int count = RAY;
    while (count)
    {
        //用rand%row和col得到的是1-8的数,
        //加1之后就是1-9的数
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }

    }
}

排查雷及判断输赢

把两个数组都传进去,让玩家输入坐标,然后判断这个坐标行和列是否大于1和小于行和列,判断为真后进入if语句,为假这提示玩家坐标不正确.
判断为真后进入判断这个坐标是否是雷,是雷就提示被炸死了并且打印出被炸死的游戏界面;
不是雷进入else定义一个函数判断周围8个坐标是否有雷,有雷的话显示周围有几个雷.

void Check(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 - RAY)
    {
        printf("输入要排查的坐标:>");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (mine[x][y] == '1')
            {
                printf("很遗憾,你被炸死了!\n\n");
                print(mine, ROW, COL);
                break;
            }
            else
            {
                int count = Check_nearby(mine, x, y);
                show[x][y] = count + '0';
                print(show, ROW, COL);
                win++;
            }
        }
        else
        {
            printf("\n坐标不正确,重新输入\n");
        }
    }
}

在前面定义一个变量每排查完一次变量加1,之后用行和列相乘减去雷的数量,判断是否除了雷的地方,还有要排查的格子,如果有就不进去,没有就提示玩家排雷成功.

 if (win == row * col - RAY)
    {
        printf("\n恭喜你,排雷成功\n");
        print(mine, ROW, COL);
    }
int Check_nearby(char board[ROWS][COLS], int x, int y)
{
    return (board[x - 1][y] + board[x - 1][y - 1] + board[x][y - 1]
        + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1]
        + board[x][y + 1] + board[x - 1][y + 1] - 8 * '0');
}

排查8个坐标j减8后乘字符0让字符转为数字,返回后加上字符0转换为字符

3.4.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 RAY 10

//初始化棋盘
void Init_Board(char board[ROWS][COLS], int rows, int cols, char ret);
//打印棋盘
void print(char board[ROWS][COLS], int row, int col);
//布置雷
void Layout_lightning(char board[ROWS][COLS], int row, int col);
//排查雷
void Check(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

当然我们也可以在游戏开始或者其他地方加上:

system("cls");

以此清理前面的打印

4.游戏运行效果

扫雷游戏的运行效果

5.整体代码

test.c文件:

#include"game.h"

void menu()
{
    printf("********************************\n");
    printf("*******   扫雷游戏   ***********\n");
    printf("*****1.开始游戏  0.退出游戏*****\n");
    printf("********************************\n");
}

void game()
{
    char mine[ROWS][COLS];//布置雷在此数组
    char show[ROWS][COLS];//隐藏界面*
    Init_Board(mine, ROWS, COLS, '0');
    Init_Board(show, ROWS, COLS, '*');
    //打印棋盘
    //print(mine, ROW, COL);
    print(show, ROW, COL);
    //布置雷
    Layout_lightning(mine, ROW, COL);
    print(mine, ROW, COL);
    //排查雷
    Check(mine, show, ROW, COL);
}

int main()
{
    srand((unsigned int)time(NULL));
    int input = 0;
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        system("cls");
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("\n输入错误,重新输入\n\n");
        }
    } while (input);
    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 RAY 10

//初始化棋盘
void Init_Board(char board[ROWS][COLS], int rows, int cols, char ret);
//打印棋盘
void print(char board[ROWS][COLS], int row, int col);
//布置雷
void Layout_lightning(char board[ROWS][COLS], int row, int col);
//排查雷
void Check(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c文件:

void Init_Board(char board[ROWS][COLS], int rows, int cols, char ret)
{
    int i = 0;
    for (i = 0; i < rows; i++)
    {
        int j = 0;
        for (j = 0; j < cols; j++)
        {
            board[i][j] = ret;
        }
    }
}

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

void Layout_lightning(char board[ROWS][COLS], int row, int col)
{
    int count = RAY;
    while (count)
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }

    }
}

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

void Check(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 - RAY)
    {
        printf("\n输入要排查的坐标:>");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (mine[x][y] == '1')
            {
                printf("\n很遗憾,你被炸死了!\n\n");
                print(mine, ROW, COL);
                break;
            }
            else
            {
                int count = Check_nearby(mine, x, y);
                show[x][y] = count + '0';
                print(show, ROW, COL);
                win++;
            }
        }
        else
        {
            printf("\n坐标不正确,重新输入\n\n");
        }
    }
    if (win == row * col - RAY)
    {
        printf("\n恭喜你,排雷成功\n\n");
        print(mine, ROW, COL);
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值