【C语言】经典小游戏--扫雷

致读者:

扫雷,是一个Windows平台下一个经典的小游戏,今有兴趣玩了几把后,就利用所学二维数组的相关知识模拟实现了一个“扫雷游戏”。由于学识浅薄,界面有点简陋,尽请谅解!

【项目思路】:

1、首先想一想扫雷游戏在Windows平台下是如何实现的。 
2、其次通过观察游戏,我们可以想到需要用两个二维数组来实现扫雷的功能。 
3、游戏刚开始,需要需要显示棋盘,用“*”遮盖雷的坐标,所以要有一个填充棋盘的函数。 
4、通过rand()函数,随机生成雷的坐标,埋雷的函数。 
5、每次扫过后,都要显示新的棋盘,显示棋盘的函数。
6、如果要想第一次踩不到雷的,需要把该坐标下得雷移动到其他不是雷的坐标,并且点击不是雷,还要满足一点击一片的效果。 
7、最后需要一个函数判断是否扫雷成功。

【项目样图】:


是不是很有意思?当然重中之重的是

要注意需要用二维数组来打印两个棋盘,假如我们要打印10X10的棋盘,那我们的二维数组元素也要为10X10个吗?,不能,因为我们在设计算法时需要统计坐标周围8个方位雷的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在10X10的边界多上一圈元素,也就要定义12X12的数组元素,这些元素我们不要打印出来,心里有数就行

【项目代码】:

game.h:

/*********************************************************************************************
*                     项目名称:扫雷游戏                                                       *
*		      编译环境:Vs 2013			                               	      *
*                     创建日期:2018.4.18                                                      *
*                     项目编辑:Mr.Yao                                                         * 
***********************************************************************************************/
 //知识点:
//1.数组
//2.函数
//3.循环
//4.扩展内容: 递归 (内存换取时间)

#ifndef __GAME_H_
#define __GAME_H_

#include <stdio.h>
#include <Windows.h>
#include <time.h>
#include <string.h>
 
enum opp
{
	EXIT,
	PLAY
};

#define EASY 10
#define HARD 30

#define ROW 10
#define COL 10

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

void InitMap(char arr[ROWS][COLS], int row,int col, char set); //创建初始化棋盘
void PrintMap(char arr[ROWS][COLS], int row, int col);	//打印棋盘
void SetMy(char arr[ROWS][COLS], int row, int col, int count); //布雷
void SweepMap(char my_map[ROWS][COLS], char player_map[ROWS][COLS], int row, int cow, int sum);	//扫雷
void MoveLei(char my_map[ROWS][COLS], int x, int y); //若第一次扫到雷,则移动雷的位置
void GetCount(char my_map[ROWS][COLS], char player_map[ROWS][COLS], int x, int y);//统计雷数


#endif

game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitMap(char arr[ROWS][COLS], int row, int col, char set)
{
	memset(arr, set, col*row*sizeof(arr[0][0]));
}

void PrintMap(char arr[ROWS][COLS], int row, int col)
{
		int i = 0;
		int j = 0;
		printf("   ");
		for (i = 1; i<=row ; i++)
		{
			printf("%3d", i);
		}
		printf("\n");
		for (i = 0; i<=row; i++)
		{
			printf("---");
		}
		printf("\n");
		for (i = 1; i <= row; i++)
		{								 
			printf("%2d|", i);
			for (j = 1; j <= col ; j++)
			{
				printf("%3c", arr[i][j]);
			}
			printf("\n");
		}
	 
}
void SetMy(char arr[ROWS][COLS], int row, int col, int sum)
{
	int count = sum;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}

void SweepMap(char my_map[ROWS][COLS],char player_map[ROWS][COLS], int row, int col, int sum)
{
	int x = 0;
	int y = 0;
	int count = 0;
	int temp = 0;
	int win = 0;
	
	while (win < (row * col - sum))
	{
		printf("请输入你扫雷坐标:>");
		scanf("%d%d", &x, &y);
		temp++;
		if (x >= 1 && x <= row&&y >= 1 && y <= col)
		{

			while ((my_map[x][y] == '1') && (temp == 1))
			{
				//保证玩家第一次不死
				MoveLei(my_map, x, y);
				//对周围的雷数进行遍历
				GetCount(my_map, player_map, x, y);
			}

			if (my_map[x][y] == '1')
			{
				printf("\n恭喜你,壮烈牺牲\n");
				PrintMap(my_map, ROW, COL);
				break;
			}
			else
			{
				GetCount(my_map, player_map, x, y);
				printf("\n");
				win++;
			}
			PrintMap(player_map, ROW, COL);
		}
		else
		{
			printf("坐标输入有误\n");
		}

	}
	if(win == (row * col - sum))
	{
		printf("恭喜你,排完了\n");
	}
	
}

//若输入的坐标无雷,则要遍历周围,统计雷数  
//若周围无雷,则递归遍历,统计周围雷数  
void GetCount(char my_map[ROWS][COLS], char player_map[ROWS][COLS], int x, int y)
{


	if ((my_map[x][y] == '0'))
	{
		int count = 0;

		if (my_map[x - 1][y - 1] == '1')
			count++;

		if (my_map[x - 1][y] == '1')
			count++;

		if (my_map[x - 1][y + 1] == '1')
			count++;

		if (my_map[x][y - 1] == '1')
			count++;

		if (my_map[x][y + 1] == '1')
			count++;
		if (my_map[x + 1][y - 1] == '1')
			count++;

		if (my_map[x + 1][y] == '1')
			count++;

		if (my_map[x + 1][y + 1] == '1')
			count++;

		player_map[x][y] = (count + '0');
	}

	if (player_map[x][y] == '0')
	{
		if (player_map[x - 1][y - 1] == '*')
			GetCount(my_map, player_map, x - 1, y - 1);

		if (player_map[x - 1][y] == '*')
			GetCount(my_map, player_map, x - 1, y);

		if (player_map[x - 1][y + 1] == '*')
			GetCount(my_map, player_map, x - 1, y + 1);

		if (player_map[x][y - 1] == '*')
			GetCount(my_map, player_map, x, y - 1);

		if (player_map[x][y + 1] == '*')
			GetCount(my_map, player_map, x, y + 1);

		if (player_map[x + 1][y - 1] == '*')
			GetCount(my_map, player_map, x + 1, y - 1);

		if (player_map[x + 1][y] == '*')
			GetCount(my_map, player_map, x + 1, y);

		if (player_map[x + 1][y + 1] == '*')
			GetCount(my_map, player_map, x + 1, y + 1);
	}
}

//为提高游戏体验,设置玩家第一次无论如何都不会被炸死  
void MoveLei(char my_map[ROWS][COLS], int x, int y)
{
	int ret = 1;
	do
	{
		my_map[x][y] = '0';
		while (ret)
		{
			x = rand() % ROW + 1;
			y = rand() % COL + 1;
			if (my_map[x][y] == '0')
			{
				my_map[x][y] = '1';
			}
			ret--;
		}
	} while (ret);
}
 

test.c:

#define _CRT_SECURE_NO_WARNINGS 1


#include "game.h"

void GotoXY(int x, int y) //设定输出位置
{
	COORD c;
	c.X = x - 1;
	c.Y = y - 1;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

void meau()
{
	GotoXY(10, 5); printf("开始游戏\n         Let's Go!");
	Sleep(1500);
	system("cls");
	printf("****    《扫雷》    ****\n");
	printf("************************\n");
	printf("*******  1.play  *******\n");
	printf("*******  0.exit  *******\n");
	printf("************************\n");
}

void game()
{
	int input = 0;
	int sum = 0;
	char my_map[ROWS][COLS];
	char player_map[ROWS][COLS];

	InitMap(my_map,ROWS,COLS,'0');
	InitMap(player_map, ROWS, COLS, '*');

	printf("**** 1.Easy 0.Hard *****\n");
	scanf("%d", &input);
	switch (input)
	{
		case PLAY:
			sum = EASY;
			break;
		case EXIT:
			sum = HARD;
			break;
		default:
			printf("输入有误\n");
			break;
	}
	printf("\n这个棋盘有%d个雷。\n", sum);
	SetMy(my_map,ROW,COL,sum);

	PrintMap(player_map, ROW, COL);
	//PrintMap(my_map, ROW, COL);
	SweepMap(my_map,player_map ,ROW, COL, sum);
	system("pause");
}



void test()
{	 
	int input = 0;
	do
	{
		meau();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case PLAY:
			game();
			break;
		case EXIT:
			break;
		default:
			printf("输出有误\n");
		}

	} while (input);
}

int main()
{
	srand((unsigned)time(NULL));
	test();
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41035588/article/details/80032914