C语言二维数组语言实现简单扫雷游戏

  1. 编写思维
    可以多文件也可以写在一个mian函数中
    这里选择了整合在一起,但在实际编写中,多文件更好
    扫雷需要两个棋盘,通过memset函数完成对字符数组的初始化,show_board和mine_board两个二位数组。show_board数组是为了打印屏幕,mine_board是为了实现扫雷的逻辑判断
    需要用到的函数有:
  • main:主函数
  • Menu:游戏选项菜单;
  • Game:
    1⃣️判断玩家输入坐标是否越界【show_board二维数组仅仅去除最外围的一圈,保留内部,后期不用考虑判断问题和玩家输入坐标值差1问题】
    2⃣️判断玩家输入的坐标值是否被排除过,防止重复排雷
    3⃣️判断玩家是否被炸死
    4⃣️顺便将玩家指定的坐标周四周八个点的雷数量值覆盖玩家输入的制定坐标轴的值
    5⃣️判断输赢
  • SetMines:通过随机值在mine_board中布置一定数量的地雷
  • GetMines:棋盘上通过二维数组show_board模拟出的坐标轴,用户输入x,y即可获取指定坐标并计算坐标(x,y)周围8个格子内部的地雷数量
  • ShowBoard:主要展现show_board二维数组的内容打印在屏幕,通过for循环打印第一行数字,再通过嵌套循环打印除show_board第一行所有元素之外的全部元素
  • ShowLine:展示二维数组show_board打印一行之后的换行效果
  1. 代码
#ifndef __GAME_H__
#define __GAME_H__

#include 
#include 
#include 
#include 

#define ROW 12//二维数组的行
#define COL 12//二维数组的列
#define NUMS 20//指定的地雷数量

#endif

//游戏菜单
void Menu() {
     
    printf("#################\n");
    printf("##1.Play 2.Exit##\n");
    printf("#################\n");
    printf("请选择:");
}
//随机埋地雷
void SetMines(char mine_board[ROW][COL]) {
     
    int count = NUMS;
    while (count) {
     
        int x = rand() % 10 + 1;//为了取得1~10之间的整数,防止在12个单位的二维数组中越界
        int y = rand() % 10 + 1;
        if (mine_board[x][y] == '0') {
     
            mine_board[x][y] = '1';
            count--;
        }
    }
}
//为了展示二维数组show_board打印一行之后的换行效果
void ShowLine(nums) {
     
    for (int i = 0; i < nums; ++i) {
     
        printf("-");
    }
    printf("\n");
}
//展现二维数组show_board的内容,其中|,' ',*,和数字之间的对齐要注意有ROW和COL决定,这里仅仅是配12行12列
void ShowBoard(char show_board[ROW][COL]) {
     
    printf("   ");
    for (int i = 1; i < ROW-1; ++i) {
     
        printf("%2d |", i);
    }
    printf("\n");
    ShowLine(3 * COL + 7);
    for (int i = 1; i < ROW-1; ++i) {
     
        printf("%2d|", i);
        for (int j = 1; j < COL-1; ++j) {
     
            printf(" %c |", show_board[i][j]);
        }
        printf("\n");
        ShowLine(3 * COL + 7);
    }
}
//获取玩家输入(x,y)之后周围8个单位中地雷'1'的数量【字符'1'减去字符'0'等于1】
int GetMines(char mine[ROW][COL], 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 Game() {
     
	//以时间为种子,进行无限次数随机
    srand((unsigned int) time(NULL));
    char show_board[ROW][COL];
    char mine_board[ROW][COL];
    //初始化打印屏幕给用户看的棋盘
    memset(show_board, '*', sizeof(show_board));
    //初始化实现逻辑判断的棋盘
    memset(mine_board, '0', sizeof(mine_board));
    SetMines(mine_board);
    int count = (ROW - 2) * (COL - 2) - NUMS;
    int x = 0;
    int y = 0;
    do {
     
        ShowBoard(show_board);
        printf("请输入你的位置:");
        scanf("%d %d", &x, &y);
        if (x < 1 || x > 10 || y < 1 || y > 10) {
     
            printf("输入越界\n");
            continue;
        }
        if (show_board[x][y] != '*') {
     
            printf("对不起,该位置已经被排除\n");
            continue;
        }
        if (mine_board[x][y] == '1') {
     
            break;
        }
        int num = GetMines(mine_board, x, y);
        show_board[x][y] = num + '0';
        count--;
    } while (count);
    //意外break退出游戏判断count>0就代表踩中地雷
    if (count > 0) {
     
        printf("你猜到了雷\n");
    } else {
     
        printf("你赢了\n");
    }
    //游戏无论输赢都会给玩家展现雷区的分布图
    printf("以下是雷区分布图:\n");
    ShowBoard(mine_board);
}

int main() {
     
    int quit = 0;
    int select = 0;
    while (!quit) {
     
        Menu();
        scanf("%d", &select);
        switch (select) {
     
            case 1:
                Game();
                printf("再来一盘\n");
                break;
            case 2:
                printf("推出\n");
                quit = 1;
                break;
            default:
                printf("输入有误\n");
                break;
        }
    }
    return 0;
}

你可能感兴趣的:(游戏)