实现原理实现过程
1.菜单2.初始化3.打印4.埋雷5.排雷6.坐标周围雷的数量7.标记雷
标记取消标记 8.展开非雷区9.游戏函数 总代码
game.hgame.ctest.c
实现原理用两个二维数组,
一个用来存放雷的排布(相当于系统游戏数据)mine数组
一个用来展示(给人们看到的界面) show数组
产生随机n个坐标存放到mine数组,当做雷
由玩家输入二维数组的坐标,来实现排雷
全部雷找到,玩家胜利
碰到雷,游戏结束
这就是一个人机交互的过程,也可以说是UI界面,一个好的菜单才能给玩游戏的玩家 有一个良好的体验
最简单的写法就是
void menu() { printf("***********************n"); printf("******** 1.Play *******n"); printf("******** 0.Exit *******n"); printf("***********************n"); }
是不是简单明了啊
这个可以按照大家自己的喜好来,每个人搞的UI都应该有个人的特点
2.初始化和井字棋一样,扫雷也有初始的界面,因此我们也要对mine和show数组初始化
//初始化 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; } } }
这和井字棋的初始化有略微的差异,井字棋的初始化只需要初始化一个数组,传入的形参就只需要arr数组、行、列,
但是,扫雷要初始化两个数组,两个数组的初始化内容不一样,因此我们再加入一个形参set,将要初始化的内容传给set
//埋雷数组 char mine[ROWS][COLS]; //展示数组 char show[ROWS][COLS]; //初始化数组 Init_Board(mine, ROWS, COLS, '0'); Init_Board(show, ROWS, COLS, '*');3.打印
一开始我们写代码时,要将mine和show数组打印来看,所以形参用的arr
打印的界面也可以根据自己的喜好来创造
//打印 void Show_Board(char arr[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("-------扫雷--------n"); for (i = 0; i <= col; i++) { printf("%d ", i); } printf("n"); for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", arr[i][j]); } printf("n"); } printf("-------扫雷--------n"); }4.埋雷
利用srand和rand函数产生n个随机坐标,来埋雷
注意,count–一定是在if里面的,只有埋雷成功,count才递减,所以循环次数是可能大于n的
//埋雷 void Set_Mine(char arr[ROWS][COLS], int row, int col) { int count = EASY_COUNT; int x = 0; int y = 0; while (count) { x = rand() % row + 1; y = rand() % col + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; count--; } } }5.排雷
玩家输入排查的坐标,不是雷,游戏继续,是雷游戏结束
//排查雷 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); fflush(stdin); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾,被炸死了n"); Show_Board(mine, ROW, COL); break; } else { Unfold_NoMine(mine, show, x, y); win++; Show_Board(show, ROW, COL); } } else { printf("坐标非法,请重新输入:n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功!n"); } }6.坐标周围雷的数量
排雷过程中,如果该坐标不是雷,那么我们要将在3*3的范围内看有几个雷,将雷的个数展示出来
//雷的个数 int Get_Mine_Count(char mine[ROWS][COLS], int x, int y) { return mine[x-1][y] + mine[x-1][y-1] + mine[x-1][y+1] + mine[x][y-1] + mine[x+1][y] + mine[x+1][y+1] + mine[x+1][y-1] + mine[x][y+1]-8*'0'; }7.标记雷
最开始时,我所想的标记是在排雷过程中直接进行,但是输入后会出现死循环,
调试后,发现标记和排雷应该是同步的,所以排雷的逻辑也得改(也就是说,上面的排雷的代码不是最终版,最终版在最后的总代码里)
void Mark_Mine(char show[ROWS][COLS]) { fflush(stdin); printf("要标记几个坐标:n"); int count = 0; scanf("%d", &count); for (int i = 0; i < count; i++) { int x = 0; int y = 0; scanf("%d %d", &x, &y); show[x][y] = '△'; } }
上述代码是错误的逻辑
标记玩家通过show数组展示出来的的数据,判断哪个坐标是雷,则可以对其进行标记
//标记 void Sign(char show[ROWS][COLS], int x, int y) { if (show[x][y] == '*') { show[x][y] = '$'; } }取消标记
玩家发现标记错误,则可以取消标记
//取消标记 void UnSign(char show[ROWS][COLS], int x, int y) { if (show[x][y] == '$') { show[x][y] = '*'; } }8.展开非雷区 4个条件 递归实现 1. 该坐标是否被排过 2. 该坐标周围的3*3范围内是否有雷 3. 该坐标是否是雷 4. 是否到达边界
//展开非雷区 void Unfold_NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { //判断是否到达边界(上、下、左、右) if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1) { return; } //判断是否排查过(如果没有被排查过那么,show数组元素的值应该是*) if (show[x][y] != '*') { return; } //x,y周围的雷数 int count = Get_Mine_Count(mine, x, y); if (count > 0) { show[x][y] = count + '0'; return; } //没有雷就递归展开 else if(count == 0) { show[x][y] = '0'; Unfold_NoMine(mine, show, x - 1, y); Unfold_NoMine(mine, show, x - 1, y-1); Unfold_NoMine(mine, show, x - 1, y+1); Unfold_NoMine(mine, show, x + 1, y-1); Unfold_NoMine(mine, show, x + 1, y); Unfold_NoMine(mine, show, x + 1, y+1); Unfold_NoMine(mine, show, x , y-1); Unfold_NoMine(mine, show, x , y+1); } }9.游戏函数
游戏的进行过程
void game() { //埋雷数组 char mine[ROWS][COLS]; //展示数组 char show[ROWS][COLS]; //初始化数组 Init_Board(mine, ROWS, COLS, '0'); Init_Board(show, ROWS, COLS, '*'); //埋雷 Set_Mine(mine, ROW, COL); //打印 //Show_Board(mine, ROW, COL); Show_Board(show, ROW, COL); //排查雷 Find_Mine(mine,show, ROW, COL); }总代码 game.h
#pragma once #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 #includegame.c#include #include #include //初始化数组 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 arr[ROWS][COLS], int row, int col); //排查雷 void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); //雷的个数 int Get_Mine_Count(char mine[ROWS][COLS],int x,int y); //标记 void Mark_Mine(char show[ROWS][COLS]); //展开非雷区 void Unfold_NoMine(char mine[ROWS][COLS], char[ROWS][COLS], int x, int y); //标记 void Sign(char show[ROWS][COLS],int x,int y); //取消标记 void UnSign(char show[ROWS][COLS], int x, int y);
#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"); for (i = 0; i <= col; i++) { printf("%d ", i); } printf("n"); for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", arr[i][j]); } printf("n"); } printf("-------扫雷--------n"); } //埋雷 void Set_Mine(char arr[ROWS][COLS], int row, int col) { int count = EASY_COUNT; int x = 0; int y = 0; while (count) { x = rand() % row + 1; y = rand() % col + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; count--; } } } //雷的个数 int Get_Mine_Count(char mine[ROWS][COLS], int x, int y) { return mine[x-1][y] + mine[x-1][y-1] + mine[x-1][y+1] + mine[x][y-1] + mine[x+1][y] + mine[x+1][y+1] + mine[x+1][y-1] + mine[x][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 (wintest.c"); scanf("%d %d", &x, &y); fflush(stdin); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾,被炸死了n"); Show_Board(mine, ROW, COL); break; } else { Unfold_NoMine(mine, show, x, y); win++; Show_Board(show, ROW, COL); } } else { printf("坐标非法,请重新输入:n"); } } else if (num == 2) { printf("请输入坐标:n"); scanf("%d %d", &x, &y); fflush(stdin); Sign(show, x, y); Show_Board(show, ROW, COL); } else if (num == 3) { printf("请输入坐标:n"); scanf("%d %d", &x, &y); fflush(stdin); UnSign(show, x, y); Show_Board(show, ROW, COL); } else if(num == 4) { return; } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功!n"); } } void Mark_Mine(char show[ROWS][COLS]) { fflush(stdin); printf("要标记几个坐标:n"); int count = 0; scanf("%d", &count); for (int i = 0; i < count; i++) { int x = 0; int y = 0; scanf("%d %d", &x, &y); show[x][y] = '△'; } } //展开非雷区 void Unfold_NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { //判断是否到达边界(上、下、左、右) if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1) { return; } //判断是否排查过(如果没有被排查过那么,show数组元素的值应该是*) if (show[x][y] != '*') { return; } //x,y周围的雷数 int count = Get_Mine_Count(mine, x, y); if (count > 0) { show[x][y] = count + '0'; return; } //没有雷就递归展开 else if(count == 0) { show[x][y] = '0'; Unfold_NoMine(mine, show, x - 1, y); Unfold_NoMine(mine, show, x - 1, y-1); Unfold_NoMine(mine, show, x - 1, y+1); Unfold_NoMine(mine, show, x + 1, y-1); Unfold_NoMine(mine, show, x + 1, y); Unfold_NoMine(mine, show, x + 1, y+1); Unfold_NoMine(mine, show, x , y-1); Unfold_NoMine(mine, show, x , y+1); } } //标记 void Sign(char show[ROWS][COLS], int x, int y) { if (show[x][y] == '*') { show[x][y] = '$'; } } //取消标记 void UnSign(char show[ROWS][COLS], int x, int y) { if (show[x][y] == '$') { show[x][y] = '*'; } }
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu() { printf("***********************n"); printf("******** 1.Play *******n"); printf("******** 0.Exit *******n"); printf("***********************n"); } void game() { //埋雷数组 char mine[ROWS][COLS]; //展示数组 char show[ROWS][COLS]; //初始化数组 Init_Board(mine, ROWS, COLS, '0'); Init_Board(show, ROWS, COLS, '*'); //埋雷 Set_Mine(mine, ROW, COL); //打印 //Show_Board(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: exit(0); break; default: printf("请重新输入n"); break; } } while (input); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)