赞
踩
目录
首先我们需要一个菜单来选择开始游戏或者退出游戏,do...while循环至少会运行一次符合我们对游戏程序的要求
- #include <stdio.h>
- void mean()
- {
- printf("************************\n");
- printf("***** 0.退出游戏 *****\n");
- printf("***** 1.开始游戏 *****\n");
- printf("************************\n");
- }
- void game()
- {
- }
- int main()
- {
- int n = 0;
- do
- {
- mean();
- scanf("%d", &n);
- switch (n)
- {
- case 0:
- break;
- case 1:
- game();
- break;
- default:
- printf("请选择正确的选项\n");
- break;
- }
- } while (n);
- }

测试我们的菜单逻辑没有问题
初阶扫雷的棋盘为9x9所以我们需要一个创建一个二维数组作为棋盘,考虑到我们需要在游戏未结束之前隐藏雷的位置和棋盘的内容,为了方便起见我们可以创建两个棋盘。一个用来展示,一个用来存放雷。
我们在选择一个位置后,如果不是雷则需要判断周围8格有几个雷,为了避免数组越界我们创建的存放雷的棋盘要比实际的宽两格,ROW和COL是我们创建的一个宏,值为9.
ROWS和COLS是(ROW+1)和(COL+1)
- #define ROW 9
- #define COL 9
- #define ROWS (ROW+2)
- #define COLS (COL+2)
数组创建之后我们需要将其初始化,考虑到需要,我们将展示的棋盘数组全部初始化为*
存放雷的棋盘全部初始化为0
为了方便后续代码的编写,我们将展示的棋盘也设置为11x11,不过在打印时只打印9x9
初始化完成之后将棋盘打印出来
- void game()
- {
- char show_board[ROWS][COLS];
- char memory_board[ROWS][COLS];
- init_show(show_board,ROW,COL);//初始化展示的棋盘
- init_memory(memory_board, ROWS, COLS);//初始化存放雷的棋盘
- printf_board(show_board, ROW, COL);
- printf_board(memory_board, ROW, COL);
- }
- void init_show(char board[][COL],int row,int col)
- {
- int i, j;
- for (i = 0; i < row; i++)
- {
- for (j = 0; j < col; j++)
- {
- board[i][j] = '*';
- }
- }
- }
- void init_memory(char board[][COLS], int row, int col)
- {
- int i, j;
- for (i = 0; i < row; i++)
- {
- for (j = 0; j < col; j++)
- {
- board[i][j] = '0';
- }
- }
- }
- void printf_board(char board[][COLS], int row, int col)
- {
- int i, j;
- 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 ", board[i][j]);
- }
- printf("\n");
- }
- }

测试结果符合预期,其中存放雷的棋盘只是为了方便观察和编写程序才将其打印出来,程序完成之后将其删去。
此时我们已经有了一个符合要求的棋盘,那么我们需要将雷布置到存放雷的棋盘中。
初阶扫雷有10个雷,所以我们需要将10个雷布置到我们的数组当中。
- void place_mine(char board[][COLS], int row, int col)
- {
- int i = 0;
- while (i<mined)//mined是我们定义的一个宏用来确定放置雷的数量
- {
- int x = rand() %row+1;
- int y = rand() %co+l;
- if (board[x][y] == '0')
- {
- board[x][y] = '1';
- i++;
- }
- }
- }
可以看到我们已经将10个雷分布到了雷盘中
首先我们需要输入一个坐标,然后在在输入之后首先判断是否是雷,如果是雷则游戏结束。
如果不是雷则需要将,一圈八格雷的总数展示出来。
- void saolei(char showboard[][COLS],char memoryboard[][COLS])
- {
- int x = 0,y=0;
- while (1)
- {
- printf("请输入坐标:\n");
- scanf(" %d%d", &x, &y);
- if (x <= ROW && x > 0&&y > 0 && y <= COL&& showboard[x][y] == '*')
- {
- if (memoryboard[x][y] == '1')
- {
- printf_board(memoryboard, ROW, COL);
- printf("boom*\n");
- printf("you die\n");
- break;
- }
- else
- {
- count(showboard, memoryboard, x, y);
- }
- if (showboard[x][y] == '0' && x > 0 && y > 0)
- ufold(showboard, memoryboard, x, y);
- printf_board(showboard, ROW, COL);
- int win=whether_win(showboard,ROW,COL);
- if (win)
- {
- printf("恭喜排雷成功\n");
- printf_board(showboard, ROW, COL);
- printf_board(memoryboard, ROW, COL);
- break;
- }
- }
- else
- printf("坐标不合法,请重新输入\n");
- }
- }

- void count(char showboard[][COLS],char memoryboard[][COLS], int x, int y)
- {
- int i = 0, j = 0;
- char sum = '0';
- for (i = x - 1; i <= x + 1; i++)
- {
- for (j = y - 1; j <= y + 1; j++)
- {
- if (memoryboard[i][j] == '1')
- sum++;
- }
- }
- showboard[x][y] = sum;
- }
在扫雷中如果我们选择的位置周围没有雷,则会展开周围八格,然后展开的格子中如果存在周围没有雷的格子则会继续展开。
所以这里我们可以写一个递归,让它每次识别到没有雷的格子就继续展开。
注意添加限制条件避免数组越界,此处编写过程中条件如果不完善容易陷入死循环,如果在调试运行过程中出现栈溢出的错误,可以仔细检查这里看是否出现死循环。
- void ufold(char showboard[][COLS], char memoryboard[][COLS], int x, int y)
- {
- int i = 0, j = 0;
- int num = 0;
- for (i = x - 1; i <= x + 1; i++)
- {
- for (j = y - 1; j <= y + 1; j++)
- {
- if (i > 0 && i <= ROW && j > 0 && j <= COL && showboard[i][j] == '*')
- {
- count(showboard, memoryboard, i, j);
- if(showboard[i][j]=='0')
- ufold(showboard, memoryboard, i, j);
- }
- }
- }
- }

测试递归展开逻辑没有问题
- int whether_win(char showboard[][COLS], int row, int col)
- {
- int sum = 0;
- int i = 0, j = 0;
- for (i = 1; i <= row; i++)
- {
- for (j = 1; j <= col; j++)
- {
- if (showboard[i][j] == '*')
- sum++;
- if (sum > mined)
- return 0;
- }
- }
- return 1;
- }

在这里为了节省时间提高效率,我们可以将雷数量mine改为2进行测试。测试完毕没有问题。
#define mined 2//雷的数量
1.删去 printf_board(memory_board, ROW, COL);这个是我们存放雷的棋盘,为了方便观察才打印出来的。
2.美化雷盘,美化到自己满意即可,此处不做过多演示
- void printf_board(char board[][COLS], int row, int col)
- {
- int i, j;
- printf(" ");
- for (i = 0; i <= col; i++)
- {
- printf("%d ", i);
- }
- printf("\n");
- for (i = 0; i <= col; i++)
- {
- printf("--");
- }
- printf("\n");
- for (i = 1; i <= row; i++)
- {
- printf("%d |", i);
- for (j = 1; j <= col; j++)
- {
- printf("%c ", board[i][j]);
- }
- printf("\n");
- }
- }

3.在合适位置添加清屏函数提升界面美观度
windows系统下可以使用system("cls"),头文件为stdlib.h
代码整体难度较低,所用到的知识非常基础,在编写时保证头脑清晰冷静可以较快完成。
头文件
- #define _CRT_SECURE_NO_WARNINGS 1
- #define ROW 9
- #define COL 9
- #define ROWS (ROW+2)
- #define COLS (COL+2)
- #define mined 10//雷的数量
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- void init_show(char board[][COLS], int row, int col);//初始化展示的棋盘
- void init_memory(char board[][COLS], int row, int col);//初始化存放雷的棋盘
- void printf_board(char board[][COLS], int row, int col);//打印棋盘
- void place_mine(char board[][COLS], int row, int col);//布置雷
- void saolei(char showboard[][COLS], char memoryboard[][COLS]);//扫雷
- void count(char showboard[][COLS], char memoryboard[][COLS], int x, int y);//计算雷的数量
- void ufold(char showboard[][COLS], char memoryboard[][COLS], int x, int y);//递归展开没有雷的格子
- int whether_win(char showboard[][COLS], int row, int col);//判断是否成功

test.c
- #include "game.h"
- void mean()
- {
- printf("************************\n");
- printf("***** 0.退出游戏 *****\n");
- printf("***** 1.开始游戏 *****\n");
- printf("************************\n");
- }
- void game()
- {
- char show_board[ROWS][COLS];
- char memory_board[ROWS][COLS];
- init_show(show_board,ROWS,COLS);
- init_memory(memory_board, ROWS, COLS);
- place_mine(memory_board, ROW, COL);
- printf_board(show_board, ROW, COL);
- saolei(show_board, memory_board);
- }
- int main()
- {
- srand((unsigned int)time(NULL));
- int n = 0;
- do
- {
- mean();
- scanf("%d", &n);
- switch (n)
- {
- case 0:
- break;
- case 1:
- game();
- break;
- default:
- printf("请选择正确的选项\n");
- break;
- }
- } while (n);
- }

game.c
- #include "game.h"
-
- void init_show(char board[][COLS],int row,int col)
- {
- int i, j;
- for (i = 0; i < row; i++)
- {
- for (j = 0; j < col; j++)
- {
- board[i][j] = '*';
- }
- }
- }
- void init_memory(char board[][COLS], int row, int col)
- {
- int i, j;
- for (i = 0; i < row; i++)
- {
- for (j = 0; j < col; j++)
- {
- board[i][j] = '0';
- }
- }
- }
- void printf_board(char board[][COLS], int row, int col)
- {
- int i, j;
- printf(" ");
- for (i = 1; i <= col; i++)
- {
- printf("%d ", i);
- }
- printf("\n");
- for (i = 0; i <= col; i++)
- {
- printf("--");
- }
- printf("\n");
- for (i = 1; i <= row; i++)
- {
- printf("%d |", i);
- for (j = 1; j <= col; j++)
- {
- printf("%c ", board[i][j]);
- }
- printf("\n");
- }
- }
- void place_mine(char board[][COLS], int row, int col)
- {
- int i = 0;
- while (i<mined)
- {
- int x = rand()%row+1;
- int y = rand()%col+1;
- if (board[x][y] == '0')
- {
- board[x][y] = '1';
- i++;
- }
- }
- }
- void ufold(char showboard[][COLS], char memoryboard[][COLS], int x, int y)
- {
- int i = 0, j = 0;
- int num = 0;
- for (i = x - 1; i <= x + 1; i++)
- {
- for (j = y - 1; j <= y + 1; j++)
- {
- if (i > 0 && i <= ROW && j > 0 && j <= COL && showboard[i][j] == '*')
- {
- count(showboard, memoryboard, i, j);
- if(showboard[i][j]=='0')
- ufold(showboard, memoryboard, i, j);
- }
- }
- }
- }
- void count(char showboard[][COLS],char memoryboard[][COLS], int x, int y)
- {
- int i = 0, j = 0;
- char sum = '0';
- for (i = x - 1; i <= x + 1; i++)
- {
- for (j = y - 1; j <= y + 1; j++)
- {
- if (memoryboard[i][j] == '1')
- sum++;
- }
- }
- showboard[x][y] = sum;
- }
- int whether_win(char showboard[][COLS], int row, int col)
- {
- int sum = 0;
- int i = 0, j = 0;
- for (i = 1; i <= row; i++)
- {
- for (j = 1; j <= col; j++)
- {
- if (showboard[i][j] == '*')
- sum++;
- if (sum > mined)
- return 0;
- }
- }
- return 1;
- }
- void saolei(char showboard[][COLS],char memoryboard[][COLS])
- {
- int x = 0,y=0;
- while (1)
- {
- printf("请输入坐标:\n");
- scanf(" %d%d", &x, &y);
- system("cls");
- if (x <= ROW && x > 0&&y > 0 && y <= COL&& showboard[x][y] == '*')
- {
- if (memoryboard[x][y] == '1')
- {
- printf_board(memoryboard, ROW, COL);
- printf_board(showboard, ROW, COL);
- printf("boom*\n");
- printf("you die\n");
- break;
- }
- else
- {
- count(showboard, memoryboard, x, y);
- }
- if (showboard[x][y] == '0' && x > 0 && y > 0)
- ufold(showboard, memoryboard, x, y);
- printf_board(showboard, ROW, COL);
- int win=whether_win(showboard,ROW,COL);
- if (win)
- {
- printf("恭喜排雷成功啦>>>>>>>>>>>\n");
- printf_board(showboard, ROW, COL);
- printf_board(memoryboard, ROW, COL);
- break;
- }
- }
- else
- printf("坐标不合法,请重新输入\n");
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。