怀旧小游戏——扫雷

小时候电脑课上偷偷玩扫雷,现在长大了自己来实现一个扫雷。

一扫雷游戏的基本思路

①首先界面上会弹出相应的提示:提示玩游戏或者退出游戏。扫雷游戏应该要做到可以反复玩。

②首先需要布置雷,雷的位置应该是要随机生成的,雷的个数是自定义的。

③之后玩家输入对应的坐标,进行排雷操作。

排雷的过程中,需要提示玩家坐标的周围有多少个雷。

④游戏结束有两种方式:

a 被雷炸死,直接结束

b 成功排查出所有的雷,游戏成功

二 扫雷游戏的实现

我们建立game.c game.h test.c的三个项目。game.c专门用来实现游戏 game.h对函数声明,头文件包含等。test.c用来实现整个游戏的一个基本思路

缺点:这个游戏不能实现展开一片和标记的效果。仅仅是一个简易版的扫雷。

① test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"

void test()
{
	menu();
	int input = 0;
	char set[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	printf("PLEASE INPUT THE NUMBER HERE:");

	srand((unsigned int)time(NULL));

	do {
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			init_board(set, ROWS, COLS, '0');
			init_board(show, ROWS, COLS, '*');//初始化
			print_show_chess(show, ROW, COL);//打印棋盘
			set_mine(set, ROW, COL);//设置雷
			search_mine(set, show, ROW, COL);
			break;
		case 0:
			printf("THE GAME IS END\n");
			break;
		default:
			printf("THE NUMBER IS FALSE,PLEASE INPUT AGAIN!\n");
		}
	} while (1);
}

int main()
{
	test();
	return 0;
}#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"

void test()
{
	menu();
	int input = 0;
	char set[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	printf("PLEASE INPUT THE NUMBER HERE:");

	srand((unsigned int)time(NULL));

	do {
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			init_board(set, ROWS, COLS, '0');
			init_board(show, ROWS, COLS, '*');//初始化
			print_show_chess(show, ROW, COL);//打印棋盘
			set_mine(set, ROW, COL);//设置雷
			search_mine(set, show, ROW, COL);
			break;
		case 0:
			printf("THE GAME IS END\n");
			break;
		default:
			printf("THE NUMBER IS FALSE,PLEASE INPUT AGAIN!\n");
		}
	} while (1);
}

int main()
{
	test();
	return 0;
}

②mine.c

#define _CRT_SECURE_NO_WARNINGS 1 
#include"mine.h"

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

}
//初始化棋盘
void init_board(char arr[ROWS][COLS], int rows, int cols,char sign)
{
	
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = sign;
		}
		printf("\n");
	}
}//由于展示给玩家的棋盘和内置的棋盘都是需要初始化的,并且初始化的功能实现只有展示的字符不一致,因此把他们封装成函数

void print_show_chess(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("---------扫雷--------\n");
	for (i = 0; i <=col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <=row; i++)//已经初始化11*11,因此从0还是从1开始都可以得到相应的棋盘 从1开始方便打印标签
	{
		printf("%d ", i);
		for (j = 1; j <=col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
	printf("---------扫雷--------\n");
}//数组下标是从0开始,怎样调整更有利于玩家?->初始化的阶段不一定需要打印出来全部都初始化了有两个好处
//1 利于查找雷的时候数量的统计 2 下标经过调整之后更有利于玩家

void set_mine(char set[ROWS][COLS], int row, int col)
{
	int count = EASY_MINE;//宏不能直接修改,创建临时变量记住值
	int x = 0;
	int y = 0;
	while(count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;//随机生成1——9的数字
		if (set[x][y]=='0')//如果随机生成的位置没有雷才能放
		{
			set[x][y] = '1';//为什么要创建二维数组!二维数组可以保存下对应的信息
			count--;//循环次数>=10
		}
	}
}

void search_mine(char set[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int ret = 0;
	int count = 0;


	for (count = ROW * COL - EASY_MINE; count >= 0; count--)
	{
		printf("请输入坐标:");
		scanf("%d %d", &x, &y);

		if (x >= 1 && x <= row && y >= 1 && y <= col)//在有效坐标范围内
		{
			if (set[x][y] == '0')
			{
				ret = count_mine(set, x, y);//统计这个坐标附近八个位置的雷 在屏幕上打印
				show[x][y] = ret + '0';//将int的ret转换成char
				printf("周围有%d个雷\n", ret);//找到就--,直到找出所有的雷
				print_show_chess(show, ROW, COL);

			}
			else
			{
				printf("LOSE!\n");
				print_show_chess(show, ROW, COL);
				break;
			}
		}

		else
		{
			printf("坐标非法,重新输入\n");
		}

	}
	if (count == ROW * COL - EASY_MINE)
	{
		printf("排雷成功\n");
		print_show_chess(show, ROW, COL);
	}
}

//int count_mine(char set[ROW][COL],int x, int y)
//{
//	int ret = set[x - 1][y - 1] + set[x][y - 1] + set[x + 1][y - 1] +
//		set[x][y - 1] + set[x][y + 1] +
//		set[x + 1][y - 1] + set[x + 1][y] + set[x + 1][y + 1] - 8 * '0';
//	return ret;
//}

int count_mine(char set[ROW][COL], int x, int y)
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = x-1; i <= x+1; i++)
	{
		for (j = y-1; j <= y+1; j++)
		{
			if (set[i][j] == '1')
				count++;
		}
	}
	return count;
}//遍历找雷

③mine.h

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include

#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define EASY_MINE 10//宏定义雷的数量,方便后期难度调整



void menu();//打印菜单
void init_board(char arr[ROWS][COLS], int rows, int cols, char sign);//初始化棋盘
void print_show_chess(char arr[ROWS][COLS], int rows, int cols);//打印棋盘
void set_mine(char set[ROWS][COLS], int row, int col);//布置雷
void search_mine(char set[ROWS][COLS], char show[ROWS][COLS], int row, int col);//找雷
int count_mine(char set[ROW][COL], int x, int y);//计数

这里有几个需要注意的问题:

①为什么要定义ROW,ROWS与COL,COLS?->处理边角难于统计的问题

②为什么要定义两个棋盘->

一个是展示给玩家看的,主要实现排雷的操作(玩家可以直接观察)

一个是设置雷的棋盘,主要实现布置雷的操作(内置,只有游戏结束才能观察)

③定义两个二维数组数组->记住各自的信息。如果单纯使用两层嵌套就会比较繁琐。

三 效果展示

怀旧小游戏——扫雷_第1张图片

 

你可能感兴趣的:(小应用,c++,c#)