思路
1,首先我们得有个棋盘布置雷,还得存放雷的位置信息,所以我们需要一个二维数组存放雷的位置信息。
2,最开始棋盘没有雷,我们要布置雷,那我们怎么区分雷和不是雷呢?我们用0表示不是雷,1表示雷,但这个1有歧义,它可以表示周围雷的个数是1,也可以表示当前位置是雷。所以我们打算分开存储,我们准备两个数组,一个存放布置雷的位置信息,一个存放当前位置的周围雷数量。
3,接下来是排雷,我们需要统计当前位置周围八个坐标的雷的信息,假设当前位置在棋盘的边缘,那么周围的坐标就有可能越界,所以我们可以把数组上下多加一行,左右多加一列,为了方便计算,两个数组都同样扩大。
4,最开始棋盘展示全是*字符,统计出雷的信息放数字字符,所以设计为字符数组,为了方便,两个数组都设计为字符数组,雷用字符'1',非雷字符'0',
代码设计
1,玩一把不过瘾要继续玩,所以选择用do while。
2,制作菜单,选择菜单内容可以用switch。
3,设计游戏模块,两个数组,一个存放布置好的雷(mine),一个存放排查出雷的信息(show)。
4,初始化棋盘,mine数组一开始全是‘0’,show数组一开始全是‘*’。
5,打印棋盘,加上行列号辅助。
6,布置雷,在mine数组布置雷,通过生成随机坐标布置雷。
7,排查雷,输入坐标并检查坐标是否合理,输入后和mine数组判断,是雷就失败,不是雷就统计周围信息,因为雷是字符‘1’,所以统计雷就把周围八个字符加起来再减去8个字符‘0’就得出雷的数量了。
菜单
初始化棋盘
打印棋盘
布置雷
排查雷
完整代码
main.c
#include "game.h"
void menu()
{
printf("~~~~~~~~~~~~~~\n");
printf("~~~ 0.quit ~~\n");
printf("~~~ 1.start ~~\n");
printf("~~~~~~~~~~~~~~\n");
printf("~please select:>");
}
void game()
{
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
CreateMine(ROW, COL);
DisplayBoard(show, ROW, COL);
FindMine(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 0:
printf("game exit\n");
break;
case 1:
game();
break;
default:
printf("err, input again\n");
break;
}
} while (input);
return 0;
}
game.c
#include "game.h"
void InitBoard(char board[ROWS][COLS], int row, int col, char set)
{
for(int i=0; i<row; i++) for(int j=0; j<col; j++) board[i][j]=set;
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
//打印分割符
for (int i = 0; i <= row*2; i++) printf("-");
printf("\n");
//打印行辅助号码
for(int i=0; i<=row; i++) printf("%d ", i);
printf("\n");
//打印分割符
for (int i = 0; i <= row * 2; i++) printf("-");
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i); //打印列的辅助号码
for (int j = 1; j <= col; j++) printf("%c ", board[i][j]);
printf("\n");
}
}
void CreateMine(int row, int col)
{
int x, y;
int count = MINE;
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
int GetMineCount(char board1[ROWS][COLS], int x, int y)
{
return board1[x - 1][y - 1] + board1[x - 1][y] + board1[x - 1][y + 1] + board1[x][y - 1] + board1[x][y + 1]
+ board1[x + 1][y - 1] + board1[x + 1][y] + board1[x + 1][y + 1] - 8 * '0';
}
void FindMine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col)
{
int x, y, step = 0;
while (row*col-MINE > step)
{
printf("input:>");
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col)
{
if (board1[x][y] == '1')
{
printf("game over\n");
DisplayBoard(board1, row, col);
break;
}
else
{
int count = GetMineCount(mine, x, y);
board2[x][y] = count + '0';
DisplayBoard(board2, row, col);
step++;
}
}
else printf("err, input again\n");
}
if (row * col - MINE == step) printf("you win\n");
}
//bug记录:
//1,mine[x][y] == '1'; 写多了一个=号。
//2,x = rand() % row + 1; y = rand() % col + 1; 这两个应该放在while里面。
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MINE 4
#define ROW 4
#define COL 4
#define ROWS ROW+2
#define COLS COL+2
char mine[ROWS][COLS]; //存放雷
char show[ROWS][COLS]; //负责展示
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int row, int col, char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//生成雷
void CreateMine(int row, int col);
//排查雷
void FindMine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col);
//统计周围雷的数量
int GetMineCount(char board1[ROWS][COLS], int x, int y);
代码仓库
Minesweeper/Minesweeper · 林宇恒/code_c - 码云 - 开源中国 (gitee.com)