数组应用之扫雷游戏

    xiaoxiao2021-04-17  177

    一、实现的功能

    (1)棋盘可改变大小(利用宏实现) (2)雷的随机生成,可改变大小(利用宏实现) (3)棋盘可实现展开,展示周围雷的个数(递归实现) (4)第一次踩雷不死,改变雷的位置

    二、效果截图

    菜单: 游戏过程: 成功: 失败(小棋盘容易失败):

    三、代码参考

    注意点: 有两个数组分别代表给玩家展示的棋盘和雷盘(放雷的棋盘) 当失败是可以展示雷盘给玩家!

    棋盘定义时要多定义两行两列,因为在后期扫雷的时候,要判断一个坐标点的周围8个坐标的雷数,当坐标为(1,1)的时候也可以正常扫雷,如图: 也就是说我们实际用的棋盘大小是内部的

    代码参考: 多文件编写,运行环境是VS2013 注释很详细。可以相互学习,如果有错误的地方请提出来。 main.c

    #include "sweep.h" void Menu(){ printf("********************************\n"); printf(" 1.开始游戏 2.结束游戏 \n"); printf(" 3.游戏帮助 \n"); printf("********************************\n"); } int main(){ int select = 0; do{ Menu(); printf("请选择:\n"); scanf("%d", &select); switch (select){ case 1: Game(); break; case 2: break; case 3: printf("(1)实现了棋盘改变大小!雷的个数\n(2)第一次下棋不炸死\n(3)棋盘展开\n"); break; default: printf("没有这个选项!\n"); break; } } while (select != 2); system("pause"); return 0; }

    sweep.h

    #ifndef _SWEEP_H_ #define ROW 10 #define COL 10 #define COUNT 5 //雷的个数 #include <stdio.h> #include <Windows.h> #include <time.h> #pragma warning(disable:4996) void Game(); //埋雷函数 void MineBoard(char board[][COL], int row, int col); //扫雷,扩展棋盘 void SweepBoard(char board[][COL], char board0[][COL], int x, int y); //获得雷的数量 char GetMines(char board[][COL], int x, int y); //转移雷的地放,只有第一次踩到雷采用到 void ChangeBoard(char board[][COL], int x, int y); //展示棋盘 void ShowBoard(char board[][COL], int x, int y); //判断是否踩到雷 int Fail(char board[][COL], int x, int y); //扫描棋盘,判断是否雷已经扫描完毕 int Win(char board[][COL],int row, int col); #endif

    sweep.c

    #include "sweep.h" void Game(){ //定义一个棋盘(雷盘) char board[ROW][COL] = {'0'}; //定义一个棋盘(玩家盘) char board0[ROW][COL] = {'0'}; int x = 0; int y = 0; int result = 0;//结果是0,表示玩家没猜踩到雷,否则踩到雷 //初始化棋盘(这个棋盘是玩家棋盘) int first = 1; //判断是否为第一次下棋 memset(board0, '*', sizeof(board0)); //千万要初始化雷盘,而且必须全盘初始化 memset(board, '0', sizeof(board)); //埋雷 MineBoard(board, ROW - 2, COL - 2); while (1){ //展示棋盘 ShowBoard(board0, ROW - 2, COL - 2); printf("请输入坐标:(x,y)\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= COL - 2){ //是第一次就挖到雷的话就转移雷的地方 if (first == 1 && board[x][y] == '1'){ board[x][y] = '0'; ChangeBoard(board, x, y); first++; } first = 0;//无论第一次踩没踩到以后踩到就会结束,所以这里改变first result = Fail(board, x, y); if (1 == result){ printf("你踩到雷了,游戏结束\n"); ShowBoard(board, ROW - 2, COL - 2); break; } else{ SweepBoard(board, board0, x, y); //扫描一遍,棋盘判断是否将雷全部扫除 if (Win(board0,ROW - 2, COL - 2) == 1){ ShowBoard(board, ROW - 2, COL - 2); printf("扫雷小能手!!!你赢了\n"); break; } else{ //空语句 } } } else{ printf("你输入的位置有误请重新输入!\n"); } } } void MineBoard(char board[][COL], int row, int col){ srand((unsigned int)time(NULL)); int x, y; int i = 0; int j = 0; //埋雷前先将棋盘变为白纸 for (i = 1; i <= row; i++){ for (j = 1; j <= col; j++){ board[i][j] = '0'; } } //开始埋雷 for (i = 0; i < COUNT; i++){ x = rand() % row + 1; y = rand() % col + 1; if (board[x][y] == '0'){ board[x][y] = '1'; //1代表有雷,0代表无雷 } else{ i--; //这个雷不计数,重新生成一次 } } } //展开原则:遇到雷就停止开展 void SweepBoard(char board[][COL], char board0[][COL], int x, int y){ if (board[x][y] == '0' && x >= 1 && x <= (ROW-2) && y >= 1 && y <= (COL-2) && board0[x][y] == '*'){ board0[x][y] = GetMines(board,x,y); } if (board[x - 1][y - 1] == '0' && x-1 >= 1 && x-1 <= (ROW - 2) && y-1 >= 1 && y-1 <= (COL - 2) && board0[x - 1][y - 1] == '*'){ board0[x - 1][y - 1] = GetMines(board, x - 1, y - 1); if (GetMines(board, x - 1, y - 1) == '0'){ SweepBoard(board, board0, x - 1, y - 1); } } if (board[x - 1][y] == '0' && x-1 >= 1 && x-1 <= (ROW - 2) && y >= 1 && y <= (COL - 2) && board0[x - 1][y] == '*'){ board0[x - 1][y] = GetMines(board, x - 1, y); if (GetMines(board, x - 1, y) == '0'){ SweepBoard(board, board0, x - 1, y); } } if (board[x - 1][y + 1] == '0' && x-1 >= 1 && x-1 <= (ROW - 2) && y+1 >= 1 && y+1 <= (COL - 2) && board0[x - 1][y + 1] == '*'){ board0[x - 1][y + 1] = GetMines(board, x - 1, y + 1); if (GetMines(board, x - 1, y + 1) == '0'){ SweepBoard(board, board0, x - 1, y + 1); } } if (board[x][y - 1] == '0' && x >= 1 && x <= (ROW - 2) && y-1 >= 1 && y-1 <= (COL - 2) && board0[x][y - 1] == '*'){ board0[x][y - 1] = GetMines(board, x, y - 1); if (GetMines(board, x, y - 1) == '0'){ SweepBoard(board, board0, x, y - 1); } } if (board[x][y + 1] == '0' && x >= 1 && x <= (ROW - 2) && y+1 >= 1 && y+1 <= (COL - 2) && board0[x][y + 1] == '*'){ board0[x][y + 1] = GetMines(board, x, y + 1); if (GetMines(board, x, y + 1) == '0'){ SweepBoard(board, board0, x, y + 1); } } if (board[x + 1][y - 1] == '0' && x+1 >= 1 && x+1 <= (ROW - 2) && y-1 >= 1 && y-1 <= (COL - 2) && board0[x + 1][y - 1] == '*'){ board0[x + 1][y - 1] = GetMines(board, x + 1, y - 1); if (GetMines(board, x + 1, y - 1) == '0'){ SweepBoard(board, board0, x + 1, y - 1); } } if (board[x + 1][y] == '0' && x + 1 >= 1 && x + 1 <= (ROW - 2) && y >= 1 && y <= (COL - 2) && board0[x + 1][y] == '*'){ board0[x + 1][y] = GetMines(board, x + 1, y); if (GetMines(board, x + 1, y) == '0'){ SweepBoard(board, board0, x + 1, y); } } if (board[x + 1][y + 1] == '0' && x + 1 >= 1 && x + 1 <= (ROW - 2) && y + 1 >= 1 && y + 1 <= (COL - 2) && board0[x + 1][y + 1] == '*'){ board0[x + 1][y + 1] = GetMines(board, x + 1, y + 1); if (GetMines(board, x + 1, y + 1) == '0'){ SweepBoard(board, board0, x + 1, y + 1); } } } char GetMines(char board[][COL], int x, int y){ //返回的数字 return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \ board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + \ board[x + 1][y] + board[x + 1][y + 1] - 7 * '0'; } //转移雷 void ChangeBoard(char board[][COL], int x, int y){ int i = 0; int j = 0; srand((unsigned int)time(NULL)); while (1){ i = rand() % (ROW - 2) + 1; j = rand() % (COL - 2) + 1; if (board[i][j] == '0' && i != x && j != y){ board[i][j] = '1'; break; } } } void ShowBoard(char board[][COL], int row, int col){ int i = 0; int j = 0; int i0 = 0; //最顶层的线 for (i = 1; i <= col; i++){ printf("///", i); } printf("\n"); printf(" \\"); //列坐标提示 for (i = 1; i <= col; i++){ if (i >= 10){ printf(" %d ", i); } else{ printf(" %d ", i); } } for (i = 1; i <= row; i++){ printf("\n"); //行坐标提示 printf(" "); for (i0 = 1; i0 <= col; i0++){ printf("------", i0); } printf("\n"); if (i < 10){ printf(" "); } printf(" %d |", i); //打印内容 for (j = 1; j <= col; j++){ printf(" %c |", board[i][j]); } } printf("\n"); //最底层的线 for (i = 1; i <= col; i++){ printf("-------", i); } printf("\n"); } //返回1说明踩到雷了,否则继续游戏 int Fail(char board[][COL], int x, int y){ if (board[x][y] == '1'){ return 1; } else{ return 0; } } int Win(char board[][COL],int row, int col){ int i, j; int count = 0; for (i = 1; i <= row; i++){ for (j = 1; j <= col; j++){ if (board[i][j] == '*'){ count++; } } } if (count > COUNT){ //雷没有扫完,返回0继续游戏 return 0; } else{ //*总不能比雷少吧,只能等于了 return 1; } }

    参考声明:

    扫雷扩展棋盘的时候遇到不懂的地方,百度到了一个大佬的博客,参考了一下! 链接:大佬博客


    最新回复(0)