我能“C“——扫雷游戏

一.前言:

扫雷游戏,一款经典的游戏,没玩过的话也可以试着玩一玩,这样对写扫雷游戏这个小游戏的化是会有一个很好的思路的。那么本片博客就来介绍如何实现扫雷游戏的具体步骤。扫雷游戏链接 扫雷游戏网页版 - Minesweeper

二.游戏思路与逻辑

1.创建菜单界面函数选择退出游戏或者是进入游戏
2.存放布置好雷的信息以及存放排查出雷的信息
3.进行雷的初始化棋盘
4.再打印出雷的初始化棋盘。注意:一定是要先进行 初始化 然后再 打印棋盘
5.就可以布置雷的信息了
6.输入排查雷的坐标
7.检查出的坐标是不是雷,布置雷存放的是字符(1) 没有放置的是字符(0)

注:我们实现扫雷最好要用到模块化编程

模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等!

总的来说就是:当你代码比较多的时候,就可以采用模块化编程来完成这个程序。

我能“C“——扫雷游戏_第1张图片

我能“C“——扫雷游戏_第2张图片

三.游戏实现的步骤

1.游戏菜单

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

 2.选择是否进行游戏

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;
}

3. 实现多行多列扫雷 

#define ROW 9
#define COL 9

#define宏定义的功能:

方便程序的修改,不用对整个程序进行修改,只需对宏定义上修改

如下图#define宏定义9*9的行列

我能“C“——扫雷游戏_第3张图片

4.实现多个雷

#define EASY_COUNT 10

这里表示宏定义10个雷

我能“C“——扫雷游戏_第4张图片

5.棋盘初始化 

打印棋盘,本质上是打印数组的内容。

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

char set 是实参传递到形参的字符。

注:实参数组名 可以省略,但是 不能进行省略。

6.棋盘打印

打印数组内容,这里数组的内容是字符'0'.

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("******* 扫雷 *******\n");
	for (j = 0;j <= col;j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1;i <= row;i++)
	{
		printf("%d ", i);
		for (j = 1;j <= col;j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

7.布置雷的信息

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 a = rand() % 10;    //产生0~9的随机数,注意10会被整除
如果要规定上下限:
int a = rand() % 51 + 13;    //产生13~63的随机数
分析:取模即取余,rand()%51+13 我们可以看成两部分:rand()%51 是产生 0~50 的随机数,后面+13保证 a 最小只能是 13,最大就是 50+13=63

使用 头文件中的 time() 函数即可得到当前的时间(精确到秒),就像下面这样:

srand((unsigned)time(NULL));


注意:这个在程序当中是只执行一次即可!

8.玩家输入雷实现步骤 

这里的玩家输入坐标,在玩家输入下棋的时候,定义了个静态局部变量,在执行代码的时候。玩游戏的时候会提醒一次, 输入第一个坐标记得空一格!每次进入游戏只有一次,这里主要就是用到了 静态局部变量 就可以保证上一次的值不会被销毁。

检查坐标处是不是雷,布置存放的是字符'1',没有放置雷存放的是字符'0'。

void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				//如果该坐标不是雷,就要统计这个坐标周围有几个雷
				int count = GetMineCount(mine,x,y);
				show[x][y] = count + '0';
				DisplayBoard(show, ROW, COL);
			}

		}
		else
		{
			printf("排查的坐标非法,请重新输入\n");  
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

 9.排查 x ,y 周围有多少

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');



}

 四.源码

1.test.c

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
	printf("*********************\n");
	printf("****** 1.play *******\n");
	printf("****** 0.exit *******\n");
	printf("*********************\n");
}
void game()
{
	//mine数组是专门存放布置好的雷的信息
	char mine[ROWS][COLS] = { 0 };
	//show数组是专门存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };
	//初始化棋盘
	InitBoard(mine, ROWS, COLS,'0');//'0'
	InitBoard(show, ROWS, COLS,'*');//'*'
	//打印棋盘
	DisplayBoard(show, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	//布置雷
	SetMine(mine,ROW,COL);
	//DisplayBoard(show, ROW, COL);
	//排查雷
	FineMine(mine,show,ROW,COL);

}
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;
}

2.game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#include
//初始化棋盘
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 FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

 3.game.c

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
	int i = 0;
	int 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;
	int j = 0;
	printf("******* 扫雷 *******\n");
	for (j = 0;j <= col;j++)
	{
		printf("%d ", j);
	}
	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 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 FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				//如果该坐标不是雷,就要统计这个坐标周围有几个雷
				int count = GetMineCount(mine,x,y);
				show[x][y] = count + '0';
				DisplayBoard(show, ROW, COL);
			}

		}
		else
		{
			printf("排查的坐标非法,请重新输入\n");  
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

初学者可以尝试一下,锻炼编程能力,增进对代码的理解,希望可以帮助到大家!

你可能感兴趣的:(游戏)