扫雷小游戏(c语言)

  • 一.前言
  • 二.项目的创建
  • game.h(函数声明,定义宏)
  • game.c(函数的定义)
  • test.c(测试游戏运行)
  • 三.扫雷项目的步骤以及相关代码实现
  • 相关信息的介绍:
  • 1.游戏界面的创建
  • 2.创建棋盘以及棋盘的初始化
  • 3.打印排雷游戏的棋盘
  • 4.布置雷,设置雷的数量
  • 5.判断是否成功排雷
  • 6.game()的整体组成
  • 四.结语


一.前言

扫雷《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。这个游戏的玩法很简单,有初级、中级、高级和自定义等模式,雷区中随机布置一定数量的地雷,玩家需要尽快找出所有不是地雷的方块,但不许踩到地雷。

二.项目的创建

game.h(函数声明,定义宏)

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 9
#define COL 9

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

#define EASY_COUNT 10

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

//打印棋盘
void display_board(char L[ROWS][COLS], int rows, int cols);

//设置雷的位置
void set_board(char L[ROWS][COLS], int row, int col);

//排雷
void find_mine(char L1[ROWS][COLS], char L2[ROWS][COLS], int row, int col);

game.c(函数的定义)

#include"game.h"

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

void display_board(char L[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", L[i][j]);
		}
		printf("\n");
	}
}

void set_board(char L[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (L[x][y] == '0')
		{
			L[x][y] = '1';
			count--;
		}
	}
}

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

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

test.c(测试游戏运行)

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

	return 0;
}

三.扫雷项目的步骤以及相关代码实现

相关信息的介绍:

数组L1是用以存放雷,数组L2是用以排雷,选择ROW和ROWS是为了后续判断选择的位置附近的雷的数量时,数组不会越界访问

1.游戏界面的创建

void menu()
{
	printf("******   1.play   ******\n");
	printf("******   0.exit   ******\n");
}
打印效果展示:

android studio仿扫雷_游戏开发


2.创建棋盘以及棋盘的初始化

棋盘的创建:

char L1[ROWS][COLS] = { 0 };
	char L2[ROWS][COLS] = { 0 };

因为我们需要一个数组存放雷,一个数组进行排雷,所以创建两个数组

棋盘的初始化

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

由于此处两个数组存放的字符不同,所以设置一个char set用来设定初始化的字符,更加方便


3.打印排雷游戏的棋盘

代码展示:

void display_board(char L[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", L[i][j]);
		}
		printf("\n");
	}
}
打印效果展示:

android studio仿扫雷_游戏开发_02


4.布置雷,设置雷的数量

设置雷的数量是在头文件中使用define进行的宏定义,对于后面数据的更改操作更为方便

设置雷的数量相关代码:

void set_board(char L[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (L[x][y] == '0')
		{
			L[x][y] = '1';
			count--;
		}
	}
}

rand()函数是创建随机数的关键,而rand%row的取值为0~row-1,rand()%col也是同理,但是运用rand()前需要使用srand(),不然每次随机数产生都是相同的,为了防止此情况的发生,我们使用了时间戳,也就是time(),可以到相关网站上查询其用法,所以为了让rand()取得不同的数值,我们须引用:srand((unsigned)time(NULL))

5.判断是否成功排雷

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

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

6.game()的整体组成

void game()
{
	char L1[ROWS][COLS] = { 0 };
	char L2[ROWS][COLS] = { 0 };
	init_board(L1, ROWS, COLS, '0');
	init_board(L2, ROWS, COLS, '*');
	//display_board(L2, ROW, COL);//展示初始棋盘

	set_board(L1, ROW, COL);
	//display_board(L1, ROW, COL);
	display_board(L2, ROW, COL);
	find_mine(L1, L2, ROW, COL);
}

四.结语

这个扫雷小游戏需要将所有的正确坐标全部排查完才算成功,所以还可以将其进行改进,通过输入一个坐标判断其周围的一部分坐标附近的雷数。总体过程是快乐的,很享受解决每一个问题的过程,我盼望着有一天可以像那些大佬一样可以完全自己设计程序,也希望每一个程序员可以在编程中找到乐趣,爱上编程,永远不头秃!