C语言实现扫雷游戏

目录

1.扫雷实现的逻辑

2.游戏的实现

2.1打印菜单

2.2玩家选择 

2.3游戏实现扫雷的逻辑 

1.布置雷的逻辑

2.排雷的第一种情况

3.排雷的第二种情况

2.3棋盘的初始化

2.4打印棋盘

1.代码 

2.打印效果

2.5布置雷

2.6排雷

2.7game()函数

3.源代码

game.h

game.c

test.c

4.总结


和我们之前的三子棋一样,扫雷的核心思想也是二维数组的利用

今天我们就来试着利用数组的知识来实现扫雷游戏

1.扫雷实现的逻辑

跟三子棋一样,我们首先创建三个文件:game.h , game.c , test.c

C语言实现扫雷游戏_第1张图片

  • 1.用define定义常量,定义数组的行和列,这样改变数组行列不需要整个修改代码,只需要改变define后面定义常量的值;
  • 2.需要一个菜单来供我们选择进入游戏还是退出游戏,menu函数;
  • 3.玩游戏肯定不止玩一局,所以需要设置循环do...while;
  • 4.需要俩个数组,一个用来设置雷(mine),存放雷的信息;一个用来让玩家排查雷(show),存放玩家输入的坐标信息;
  • 5.需要初始化俩个数组,我们把要埋雷的数组初始化为’0‘,要排雷的数组初始化为’*‘;
  • 6.需要打印棋盘让玩家来排雷;
  • 7.需要设置雷和排雷函数;

2.游戏的实现

2.1打印菜单

定义一个menu()函数来打印菜单

void menu() {
	printf("******************\n");
	printf("***** 1.play *****\n");
	printf("***** 0.exit *****\n");
	printf("******************\n");
}

2.2玩家选择 

我们在main()中采取do-while循环来实现重复游戏,用switch()来获取玩家的选择

int main() {
	int input = 0;
	do {
		menu();
		printf("请选择>");
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

目前我们的实现效果是这样的

C语言实现扫雷游戏_第2张图片

2.3游戏实现扫雷的逻辑 

1.布置雷的逻辑

假设我们实现一个9*9的棋盘,上面布置十个雷

这样我们就需要一个9*9的数组来存放雷

假设这是我们的棋盘

 C语言实现扫雷游戏_第3张图片

最开始每个位置都放0;0表示非雷 

C语言实现扫雷游戏_第4张图片

当我们布置雷的时候,把雷放成1

2.排雷的第一种情况

 C语言实现扫雷游戏_第5张图片

假设我们在排这个绿色坐标的时候,它不是雷,这时候我们需要统计它周围红圈中8个坐标的雷的个数;像上面这种情况,我们需要显示1;但是这个1会与我们表示雷的1冲突,为了解决这个问题,我们再单独给他一个数组,全部放成 ‘ * ’ ;

C语言实现扫雷游戏_第6张图片

这个时候,我们在 ‘ * ’ 棋盘中,对应的位置显示‘1’表示这个坐标周围的八个坐标里有一个雷;我们给玩家展示的时候,展示第2个数组

  • 第一个棋盘存雷和非雷的信息
  • 第二个棋盘存玩家排查出来的雷的信息

3.排雷的第二种情况

C语言实现扫雷游戏_第7张图片

假设我们要排查边缘的这个坐标,这个是超出了我们9*9的数组范围

这个时候为了防止越界,我们再把这个数组扩充,即在设置存雷的数组的时候,范围设置成11*11

像这样

C语言实现扫雷游戏_第8张图片

这个时候,就不存在越界行为了

为了便于计算,我们的展示棋盘同样扩大到11*11(严丝合缝);

C语言实现扫雷游戏_第9张图片

2.4棋盘的初始化

我们定一个InitBoard()函数来初始化棋盘

定义两个11*11的数组

C语言实现扫雷游戏_第10张图片

这个数组用来放布置好的雷的信息(11*11)

C语言实现扫雷游戏_第11张图片

这个数组用来放排查出的雷的信息(11*11)

为了保证两个数组严格的统一,包括元素类型也要统一,我们定义为char数组 

game.h

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

game.c

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0, j = 0;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++) {
			board [i][j] = set;
		}
	}
}

test.c 

void game() {
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
}

2.5打印棋盘

我们定义一个DisplayBoard()函数来打印棋盘

在打印的时候,我们可以打印出坐标

C语言实现扫雷游戏_第12张图片

1.代码 

game.c

//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
	int i = 0, j = 0;
	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");
	}
}

test.c 

void game() {
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
}

2.打印效果

C语言实现扫雷游戏_第13张图片​ 

2.6布置雷

我们定义一个setMine()函数来布置雷

假设我要布置十个雷

  • 随机布置
  • 用1表示雷 

这里我们又要用到我们的随机数函数rand(),使用rand函数必然需要在main()函数中调用srand();

//布置雷
void setMine(char mine[ROWS][COLS], int row, int col) {
	int count = EASY_COUNT;
	while (count) {
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0') {
			mine[x][y] = '1';
			count--;
		}
	}
}

2.7排雷

排查雷的逻辑是:

  1. 如果这个位置不是雷,就计算这个位置周围八个坐标有几个雷,并显示雷的个数
  2. 如果这个位置是雷,就炸死了,游戏结束
  3. 如果把不是雷的位置都找出来了,那么游戏也结束,玩家胜利

在扫雷的过程中,我们还需要计算周围雷的个数

定义一个GetMineCount()函数来统计周围雷的个数 

int GetMineCount(char mine[ROWS][COLS], int x, int y) {
	return(mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x][y - 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0');
}

 定义一个FindMine()函数来排查雷

void FindMine(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);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (show[x][y] == '*') {
				if (mine[x][y] == '1') {
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(show, ROW, COL);
					break;
				}
				else {
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else {
				printf("该坐标已经被排查了\n");
			}
		}
		else {
			printf("非法坐标,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT) {
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

2.8game()函数

void game() {
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//布置雷
	setMine(mine, ROW, COL);
	//排查雷
	FindMine(mine, show, ROW, COL);
}

3.源代码

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include
#include
#include

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10//十个雷
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布雷
void setMine(char mine[ROWS][COLS], int row, int col);
//扫雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
//计算扫出来的雷个数
int GetMineCount(char mine[ROWS][COLS], int x, int y);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0, j = 0;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++) {
			board [i][j] = set;
		}
	}
}
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
	int i = 0, 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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("--------扫雷--------\n");
}
//布置雷
void setMine(char mine[ROWS][COLS], int row, int col) {
	int count = EASY_COUNT;
	while (count) {
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0') {
			mine[x][y] = '1';
			count--;
		}
	}
}
//扫雷
int GetMineCount(char mine[ROWS][COLS], int x, int y) {
	return(mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x][y - 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0');
}
void FindMine(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);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (show[x][y] == '*') {
				if (mine[x][y] == '1') {
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(show, ROW, COL);
					break;
				}
				else {
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else {
				printf("该坐标已经被排查了\n");
			}
		}
		else {
			printf("非法坐标,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT) {
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

test.c

#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] = { 0 };
	char show[ROWS][COLS] = { 0 };
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//布置雷
	setMine(mine, ROW, COL);
	//排查雷
	FindMine(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:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

4.总结

这就是扫雷的全部过程了,希望对各位有帮助4

今天我们练习写出了扫雷游戏,这是一个不错的进步,对数组有了更多的理解

小杜跟各位小伙伴在一起成长,祝我们都能成为大牛!

                                                                                                                                //小杜的成长之路

你可能感兴趣的:(游戏,c语言,开发语言)