前言
扫雷游戏起源于1973年的“方块”游戏。1992年微软发布的Windows3.1中加入该游戏,从此风靡全世界。玩扫雷游戏,可以锻炼观察和推理能力,培养细心和耐心。
游戏规则:游戏目标是找出所有雷,格子里的数字代表它四周8个坐标内有几个雷,“触雷”则输。
实现思路
1,游戏框架(包括游戏的开始与退出)
2,游戏部分的实现
3,多文件协作完成
1,游戏框架
此部分较为简单自接上代码
#include<stdio.h>
void menu() {
printf("#######################\n");
printf("######## 1.play #######\n");
printf("######## 0.exit #######\n");
printf("#######################\n");
}
int main() {
int input = 0;
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input) {
case 1:
printf("-------扫雷------\n");
break;
case 0:
printf("退出游戏.\n");
break;
default:
printf("选择错误,请重新选择.\n");
}
} while (input);
}
运行结果:
2,游戏部分的实现
游戏部分的实现是扫雷游戏的核心部分,也是扫雷游戏实现的关键,此部分的实现可以有:
①初始化雷的“棋盘”
②显示雷的“棋盘”
③布置雷
④排查雷
①初始化雷的“棋盘”
使用两个字符二维数组来表示雷的“棋盘“”,第一个用于后台布置雷和排查雷的操作,第二个用展示给玩家,数组大小为“棋盘”大小加二,防止在布置、排查雷时数组越界。
第一个数组内容全初始化为‘0’(字符0),方便后期计算。
第二个数组内容可全取初始化为‘+’(也可为*,&等)
函数主体:
//初始化
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 print(char board[ROWS][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");
}
}
③布置雷
布置雷时应满足雷的随机性,才能保障游戏的可玩性,那么将会使用到srand()函数、rand函数和time()函数以及它们对应的库函数<stdlib.h>和<time.h>。
函数主体:
//布置雷
void setmine(char board[ROWS][COLS], int row, int col) {
int x, y,count=0;
count = EASYCOUNT;
while (count) {
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] != '1') {
board[x][y] = '1';
count--;
}
}
}
④排查雷
此步是关键中的关键,实现思路如下:
1.输入一个坐标
2.判断是否越界
3.这个位置是否是雷 ①是,炸死,游戏失败 ②不是,显示雷的个数
函数主体:
//排查雷
int getminecount(char mine[ROWS][COLS], int x, int y) {
int i, j,count=0;
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
if (mine[x + i][y + j] == '1')
count++;
}
}
return count;
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x, y, i, j,count=0;
while (count<row*col-EASYCOUNT) {
printf("请输入要排查的位置:");
scanf("%d%d", &x, &y);
if (x > 0 && x <= row && y>0 && y <= col) {
if (mine[x][y]== '1') {
printf("\n踩雷了,游戏结束.\n");
printf("雷布置如下:\n");
print(mine, ROW, COL);
break;
}
else {
count++;
i= getminecount(mine,x,y);
show[x][y] = i + '0';
print(show, ROW, COL);
}
}
else {
printf("输入错误,请重新输入x(1~9),y(1~9)\n");
}
}
if (count == row * col - EASYCOUNT)
printf("\n游戏胜利.\n");
}
3,多文件协作完成
一般为三个文件两个.c文件,一个.h文件。
第一个.c文件存放游戏主体框架。
第二个.c文件存放函数的定义。
.h文件存放库函数的声明和函数的声明,以及一些特殊值的声明。
使用多文件协作完成,可以使程序可读性更好,方便定位查找bug等优点。
全部源程序:
test.c(游戏框架):
#include"game.h"
void menu() {
printf("#######################\n");
printf("######## 1.play #######\n");
printf("######## 0.exit #######\n");
printf("#######################\n");
}
void game() {
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化
Initboard(mine, ROWS, COLS, '0');
Initboard(show, ROWS, COLS, '+');
//打印雷
print(show, ROW, COL);
//布置雷
setmine(mine, ROW, COL);
//排查雷
findmine(mine, show, ROW, COL);
}
int main() {
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input) {
case 1:
printf("-------扫雷------\n");
game();
break;
case 0:
printf("退出游戏.\n");
break;
default:
printf("选择错误,请重新选择.\n");
}
} while (input);
}
game.h(函数声明):
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASYCOUNT 10
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char set);
//打印雷
void print(char board[ROWS][COLS], int row, int col);
//布置雷
void setmine(char board[ROWS][COLS], int row, int col);
//排查雷
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols);
game.c(函数定义):
#include"game.h"
//初始化
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 print(char board[ROWS][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");
}
}
//布置雷
void setmine(char board[ROWS][COLS], int row, int col) {
int x, y,count=0;
count = EASYCOUNT;
while (count) {
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] != '1') {
board[x][y] = '1';
count--;
}
}
}
//排查雷
int getminecount(char mine[ROWS][COLS], int x, int y) {
int i, j,count=0;
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
if (mine[x + i][y + j] == '1')
count++;
}
}
return count;
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x, y, i, j,count=0;
while (count<row*col-EASYCOUNT) {
printf("请输入要排查的位置:");
scanf("%d%d", &x, &y);
if (x > 0 && x <= row && y>0 && y <= col) {
if (mine[x][y]== '1') {
printf("\n踩雷了,游戏结束.\n");
printf("雷布置如下:\n");
print(mine, ROW, COL);
break;
}
else {
count++;
i= getminecount(mine,x,y);
show[x][y] = i + '0';
print(show, ROW, COL);
}
}
else {
printf("输入错误,请重新输入x(1~9),y(1~9)\n");
}
}
if (count == row * col - EASYCOUNT)
printf("\n游戏胜利.\n");
}
Respect!