扫雷

扫雷游戏大家应该都不陌生,在以前的电脑上几乎都有扫雷的身影,它也算是我们童年的一个回忆吧!

现在就让我们用C语言来写一个简易版的扫雷吧

游戏规则:

1.布置十个雷

2.扫雷

输入坐标

若是雷就提示被炸死了,游戏结束

若不是雷就 告诉玩家这个坐标周围8个坐标上一共有几个雷

知道把使用雷的位置找出来,游戏结束,扫雷成功

游戏思路:

首先我们需要将扫雷的菜单页面打印出来,可以写一个menu函数

接着,重头戏就是game函数的实现

思考:如何查看布置好的雷的信息和排查出雷的信息?

采取定义两个二维数组来分别展示

定义char mine[9][9]来查看布置好的雷的信息

定义 字符1 为雷

定义 字符0 为非雷

定义char show[9][9]布置好的雷的信息

定义 字符*为为排查

定义 数组字符为已排查

但是如何处理下标越界问题?

于是采取将数组放大为11行11列来解决越界问题

接下来,就要实现初始化棋盘---打印棋盘---随机布置雷---玩家排查雷等步骤(详见game.c)

//test.c #include "game.h" void menu() {
    printf("*******************\n");
    printf("****  1.play  ****\n");
    printf("****  0.exit  ****\n");
    printf("*******************\n");
} void game() {//  扫雷游戏的实现     //mine是用来存放布置好的雷的信息的     char mine[ROWS][COLS] = { 0 };//'0'     //show数组时用来排查出雷的信息的     char show[ROWS][COLS] = { 0 };//'*'     //初始化棋盘     init_board(mine, ROWS, COLS,'0');
    init_board(show, ROWS, COLS, '*');
    //打印棋盘     //show_board(mine, ROW, COL);     //随机布置雷     set_mine(mine, ROW, COL);
    show_board(show, ROW, COL);
    //排查雷     find_mine(mine,show,ROW,COL);

} int main() {
    srand((unsigned int)time(NULL));
    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;
} //game.h #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define Easy_count 10//放十个雷 #include<stdlib.h> #include<time.h> //初始化棋盘 void init_board(char arr[ROWS][COLS], int rows,int cols,char set); //打印棋盘 void show_board(char arr[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 show[ROWS][COLS], int row,int col); //game.c #define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void init_board(char arr[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++)
        {
            arr[i][j] = set;
        }
    }
} void show_board(char arr[ROWS][COLS], int row, int col) {
    int i = 0;
    int j = 0;
    //打印列号     printf("-------扫雷-------\n");//将mine棋盘和show棋盘分开     for (size_t j = 0; j <= col; j++)
    {
        printf("%d ", j);
    }
    printf("\n");

    for (size_t i = 1; i <= row; i++)
    {
        printf("%d ", i);//在每一行前面加一个序号         for (size_t j = 1; j <= col; j++)
        {
            printf("%c ", arr[i][j]);
        }
        printf("\n");
    }
} //随机布置雷 void set_mine(char mine[ROWS][COLS], int row, int col) {
    int count = Easy_count;
    while (count != 0)
    {
        int x = 0;
        int y = 0;

        x = rand()%row + 1;//x必须是1~9,         y = rand()%col + 1;//y也必须是1~9,         if (mine[x][y]=='0')//判断格子有没有被占用,确保放满十个         {
            mine[x][y] = '1';
            count--;
        }
    }
} //找周围有几个雷 int get_mine_(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 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 (mine[x][y] == '1')
            {
                printf("很遗憾,你被炸死了\n");
                show_board(mine, ROW, COL);
                break;
            }
            else//选中的不是雷              //统计周围八个格子炸弹的个数             {
                int count = get_mine_(mine, x, y);
                show[x][y] = count + '0';//如果count为1,应该将字符1放到这个空子里,0的ASCII值为48,加上1,                  //就是49,就是字符1的ASCII值                 show_board(show, ROW, COL);
                win++;
            }
            
        }
        else             printf("坐标非法,请重新输入\n");
    }
    if (win = row * col - Easy_count)//排雷成功了     {
        printf("恭喜你,排雷成功了\n");
        show_board(mine, ROW, COL);
    }
}

我在许多地方后面加了注释,大家可以看看

我认为极妙的地方:

1.get_mine_(mine, x, y)函数的实现利用了'0'-'0'=0,'1'-'0'=1来计算一个坐标周围的雷的个数,呼应了前面将雷用字符1来表示,非雷用字符0来表示

2.求出get_mine_(mine, x, y)的返回值count后,如何将int型count放到char数组中?

采用了将count+'0'来转化成count的字符形式,本质上式利用了ASCII值进行的思考

当然,代码中采用函数封装,多文件调用也是很好的习惯,以后要多多培养项目思维

代码中有许多有趣的小细节以及结果的实现,更能让我感到编程的魅力!

全部评论
这么多年了,我依然不知道扫雷怎么玩
点赞 回复 分享
发布于 2022-08-21 15:47 陕西
小比特?
点赞 回复 分享
发布于 2024-02-29 17:25 福建

相关推荐

我知道自己这个念头不好,但是真的很羡慕😭大家的父母长辈都能帮到自己吗?
大飞的诡术妖姬:父母都是普通打工人,身体也不好,能供我读到本科毕业很不容易,毕业以后帮衬心里会有罪恶感。虽然可能会错过很多风景,但还是想活的心安理得。
点赞 评论 收藏
分享
那一天的Java_Java起来:他本来公司就是做这个的,不就是正常的游戏客户端和服务器开发,软硬件联动,有啥恶心不恶心的,提前告诉你就是怕你接受不了,接受不了就没必要再往后走流程浪费时间,虽然这公司是一坨。
点赞 评论 收藏
分享
05-01 22:41
中南大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务