【c语言】扫雷游戏实现

设计思路

  • 由于这个代码相较于平常所写的,代码比较多,故我采用多文件管理,减少维护成本
    • 函数声明放在game.h头文件
    • 与游戏有关函数定义放在game.c源文件
    • main函数单独放在main.c中
  • 设计代码时,先写出主体逻辑,然后边测试逻辑的正确性边进行代码的具体实现
如下:
主函数
int main(void)
{
	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;
}
菜单
void menu()
{
	printf("****************************************\n");
	printf("*******     1.play    0.exit   *********\n");
	printf("****************************************\n");
}
game函数的逻辑
  • 设计时需要一个棋盘布置雷,我们把雷设置为字符1(后续好计算雷的个数),其他设置为字符0,此时若要显示你所输入的坐标周围雷的个数,若有一个雷,就会与雷冲突,所以我们设置两个数组一个布置雷,一个显示周围雷的数量
  • 由于后面要检查周围8个位置的雷个数,在边界时防止数组越界,故数组扩大一圈
  • 初识化棋盘,将初始化的字符作为参数传递
  • 设置雷
  • 打印显示雷数量的棋盘
  • 开始排雷
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	srand((unsigned)time(NULL));

	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');

	SetMine(mine, ROW, COL, DIGIT_MINE);

	PrintBoard(show, ROW, COL);

	CheckMine(mine, show, ROW, COL, DIGIT_MINE);
}
初始化棋盘
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 SetMine(char mine[ROWS][COLS], int row, int col, int digitMine)
{
	int x = 0;
	int y = 0;
	while (digitMine > 0)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;

		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			digitMine--;
		}
	}
}
打印棋盘
void PrintBoard(char board[ROWS][COLS], int row, int col)
{
	int  i = 0;
	int j = 0;

	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 CheckMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int digitMine)
{
	int x = 0;
	int y = 0;
	int ret = 0;

	int count = 0;
	while (row * col - digitMine > count)
	{
		printf("请输入坐标:");
		scanf("%d %d", &x, &y);

		if (mine[x][y] == '1')
		{
			printf("你已被炸死!\n");
			PrintBoard(mine, ROW, COL);

			break;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] == '*')
			{
				ret = GetMine(mine, x, y);
				show[x][y] = ret + '0';
				count++;
				PrintBoard(show, ROW, COL);

			}
			else
			{
				printf("该坐标已被排查!\n");
			}
		}
		else
		{
			printf("输入错误,请重新输入!\n");
		}
	}
	if (count == row * col - digitMine)
	{
		printf("恭喜你排雷成功!\n");
		PrintBoard(mine, ROW, COL);
	}
}
坐标周围雷的数量

由于雷是用字符1表示,故把周围的字符都相加减去8个字符0,就会得到周围雷的个数

int GetMine(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] + \
		mine[x + 1][y] + \
		mine[x][y - 1] + \
		mine[x][y + 1] + \
		mine[x - 1][y - 1] + \
		mine[x + 1][y + 1] + \
		mine[x - 1][y + 1] + \
		mine[x + 1][y - 1] - 8 * '0';
}
全部代码
#define _CRT_SECURE_NO_WARNINGS 1

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define DIGIT_MINE 10
#include
#include
#include

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

//打印棋盘
void PrintBoard(char board[ROWS][COLS], int row, int col);

//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col, int digitMine);
//扫雷
void CheckMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int digitMine);

\
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

int GetMine(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] + \
		mine[x + 1][y] + \
		mine[x][y - 1] + \
		mine[x][y + 1] + \
		mine[x - 1][y - 1] + \
		mine[x + 1][y + 1] + \
		mine[x - 1][y + 1] + \
		mine[x + 1][y - 1] - 8 * '0';
}
//初始化棋盘
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 PrintBoard(char board[ROWS][COLS], int row, int col)
{
	int  i = 0;
	int j = 0;

	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 digitMine)
{
	int x = 0;
	int y = 0;
	while (digitMine > 0)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;

		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			digitMine--;
		}
	}
}


void CheckMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int digitMine)
{
	int x = 0;
	int y = 0;
	int ret = 0;

	int count = 0;
	while (row * col - digitMine > count)
	{
		printf("请输入坐标:");
		scanf("%d %d", &x, &y);

		if (mine[x][y] == '1')
		{
			printf("你已被炸死!\n");
			PrintBoard(mine, ROW, COL);

			break;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] == '*')
			{
				ret = GetMine(mine, x, y);
				show[x][y] = ret + '0';
				count++;
				PrintBoard(show, ROW, COL);

			}
			else
			{
				printf("该坐标已被排查!\n");
			}
		}
		else
		{
			printf("输入错误,请重新输入!\n");
		}
	}
	if (count == row * col - digitMine)
	{
		printf("恭喜你排雷成功!\n");
		PrintBoard(mine, ROW, COL);
	}
}


#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

void menu()
{
	printf("****************************************\n");
	printf("*******     1.play    0.exit   *********\n");
	printf("****************************************\n");
}
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	srand((unsigned)time(NULL));

	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');

	SetMine(mine, ROW, COL, DIGIT_MINE);

	PrintBoard(show, ROW, COL);

	CheckMine(mine, show, ROW, COL, DIGIT_MINE);
}
int main(void)
{
	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语言,c语言,游戏)