扫雷
七夕到了,没有女朋友怎么办?没事~ 写一个小游戏,让女朋友陪你玩扫雷~
首先创建:
game.c的源文件–>游戏函数的实现
test.c的源文件–>测试使用
game.h的头文件–>游戏函数的声明
一共需要创建两个二维数组:
如果要实现9*9的数组雷区,则实际要创建11 *11的数组雷区,为了防止数组越界。
1.初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set) { int i, j; for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { board[i][j] = set; } } }
void game() { char mine[ROWS][COLS] = { 0 };//存放雷的信息 char show[ROWS][COLS] = { 0 };//存放排查雷的信息 //初始化棋盘 InitBoard(mine, ROWS, COLS ,'0'); InitBoard(show, ROWS, COLS,'*'); //展示棋盘 DisplayBoard(mine, ROWS, COLS); DisplayBoard(show, ROWS, COLS); }
2.展示棋盘
void DisplayBoard(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < 10; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i < ROWS-1; i++) { printf("%d ", i); for (j = 1; j < COLS-1; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("\n"); }
最外层的行列可以让玩家容易分清楚是在第几行第几列
3.布置雷
void SetMine(char board[ROWS][COLS], int row, int col) { int count = EAST_COUNT; while (count) { //1.生成随机下标 int x = rand() % row + 1; int y = rand() % col + 1; if (board[x][y] != '1') { board[x][y] = '1'; count--; } } }
0 1 2 3 4 5 6 7 8 9 1 1 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 3 0 0 0 1 0 0 0 0 0 4 1 0 0 0 1 1 0 0 0 5 0 0 0 0 0 1 0 0 0 6 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 9 0 1 0 1 0 0 0 0 0
4.排除雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//排查雷 { int x, y; printf("输入要排查雷的坐标:>"); scanf("%d%d", &x, &y); while (1) { if (x >= 1 && x <= 9 && y >= 1 && y <= 9) { if (mine[x][y] == '1') { printf("很遗憾,你被炸死了,女朋友很伤心๐·°(৹˃̵﹏˂̵৹)°·๐"); DisplayBoard(show, ROWS, COLS); break; } else { int count = GetMineCount(mine, x, y); show[x][y] = count+'0'; DisplayBoard(show, ROWS, COLS); break; } } else printf("输入坐标非法,请重新输入"); }
下图说明在2 5坐标的周围8个格子中一共有一个雷
5.优化展示效果
(1)展开一片
如何实现这种可以展开一大片的效果呢?
规则:满足该坐标不是雷,并且周围8个位置也不是雷,就会展开一片
声明:以下代码来自点击到空白格子时自动展开
//连续展开 void blankOpen(int r,int c) { //打开格子 map[r][c] -= 20; count++; //点开后遍历九宫格 for (int m=r-1;m<=r+1;m++) { for (int n=c-1;n<=c+1;n++) { if (m >= 1 && m <= ROW && n >= 1 && n <= COL) //保证是游戏区 { if (map[m][n] >= 19 && map[m][n] <= 28) //必须为空白格 { if (map[m][n]!=20) { map[m][n] -= 20; count++; } else { blankOpen(m,n); } } } } } }
此时就需要用到递归了
(2)显示剩余的雷数
声明:以下代码来自关于显示剩余的雷数
int print() { char num[MINE_NUM]; int n = 0; for (int r = 1; r <= ROW; r++) { for (int c = 1; c <= COL; c++) { if (map[r][c] == 19 || map[r][c] == -1) { n++; } } } outtextxy(770, 200, "剩余的雷:"); sprintf(num, "%02d", n); outtextxy(790, 230, num); printf("\n\n\n"); printf("%02d",n); }
6.最终展示结果
1.排雷失败:(1代表雷,0代表非雷)
2.排雷成功
最终的所有的代码如下: