扫雷,C++【低配版】

扫雷C++低配版

创作背景

博主是一位刚上大一的新生,自学了C语言两个月左右。博主最近临近期末,作为大学生也没有什么事可以干,于是就在寝室里面写了这个C++的扫雷低配版,供大家分享学习也可以大家进行讨论,欢迎大家的各种意见和见解。

下载链接

我的作品还是老规矩哈。
想要下载源代码,得先关注孩子一波哦> ^ _ ^ <
点击——>扫雷C++源代码

广告

点个赞吧,孩子三天没吃饭了。

效果视频

第1个视频是屏幕录制的游戏的玩的过程。
第2个视频是操作介绍,用于帮助语文小白。

扫雷

操作

代码部分

第1部分代码块

这是第1部分的代码。里面包含所需要的宏定义、结构体、还有部分声明的函数。
在我的代码里面没有对子函数的用途进行注释,但大家可以通过英文来判断该子函数是用于做什么的。
我的扫雷是通过数组结构体结合制作的,这种创作应该还比较新颖,在网上应该还没有类似的写法。

#define SIZE 7 
#define BOOM 5

struct SmallSquare
{
   
   
	int NnmberOfDetectrd;			//1~8为正常探测,-1为炸弹。
	int rw;							//1表示已经翻开,0表示未被翻开,2表示被标记为雷。
};
int INIT( SmallSquare map[SIZE][SIZE] );

int PRINT( SmallSquare map[SIZE][SIZE] , int *pointerI , int *pointerJ );

int GetCommand();

int MOVE( SmallSquare map[SIZE][SIZE] , int *pointerI , int *pointerJ ,int command , int *win );
第2部分代码块

这部分代码用于游戏的初始化。
里面对数组的某些子成员进行了赋值,并且判断了每个方块周围有多少个地雷。
这个函数还自动为玩家翻开了一些方块,也方便玩家进行游玩。

int INIT( SmallSquare map[SIZE][SIZE] )
{
   
   
	int tempI , tempJ;			//tempI表示行,tempJ表示列。

	//所有的小方格都未被翻开。
	for( tempI = 0 ; tempI < SIZE ; tempI++ )
	{
   
   
		for( tempJ = 0 ; tempJ < SIZE ; tempJ++ )
		{
   
   
			map[tempI][tempJ].rw = 0;
		}
	}
	//产生随机数t1
	time_t t1;
	int total = 1;
	int magic;

	//埋地雷。
	while( total <= BOOM )
	{
   
   
		magic = time(&t1) % 100;
		tempI = ( magic * rand() ) % SIZE;
		tempJ = ( magic * rand() ) % SIZE;
		if( map[tempI][tempJ].NnmberOfDetectrd != -1 )					//防止在一个方格放下2颗雷。
		{
   
   
			map[tempI][tempJ].NnmberOfDetectrd = -1;
			total++;
		}
		else
		{
   
   
			continue;
		}
	}

	//探测一个方块旁有多少雷。
	for( tempI = 0 ; tempI < SIZE ; tempI++ )
	{
   
   
		for( tempJ = 0 ; tempJ < SIZE ; tempJ++ )
		{
   
   
			if(map[tempI][tempJ].NnmberOfDetectrd != -1 )
			{
   
   
				map[tempI][tempJ].NnmberOfDetectrd = 0;
				if( tempI - 1 >= 0 && tempI - 1 < SIZE && tempJ - 1 >= 0 && tempJ - 1 < SIZE && map[tempI - 1][tempJ - 1].NnmberOfDetectrd == -1 )		//左上
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI - 1 >= 0 && tempI - 1 < SIZE && tempJ >= 0 && tempJ < SIZE && map[tempI - 1][tempJ].NnmberOfDetectrd == -1 )					//正上
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI - 1 >= 0 && tempI - 1 < SIZE && tempJ + 1 >= 0 && tempJ + 1 < SIZE && map[tempI - 1][tempJ + 1].NnmberOfDetectrd == -1 )		//右上
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI >= 0 && tempI < SIZE && tempJ - 1 >= 0 && tempJ - 1 < SIZE && map[tempI][tempJ - 1].NnmberOfDetectrd == -1 )					//左
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI >= 0 && tempI < SIZE && tempJ + 1 >= 0 && tempJ + 1 < SIZE && map[tempI][tempJ + 1].NnmberOfDetectrd == -1 )					//右
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI + 1 >= 0 && tempI + 1 < SIZE && tempJ - 1 >= 0 && tempJ - 1 < SIZE && map[tempI + 1][tempJ - 1].NnmberOfDetectrd == -1 )		//左下
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI + 1 >= 0 && tempI + 1 < SIZE && tempJ >= 0 && tempJ < SIZE && map[tempI + 1][tempJ].NnmberOfDetectrd == -1 )					//正下
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
				if( tempI + 1 >= 0 && tempI + 1 < SIZE && tempJ + 1 >= 0 && tempJ + 1 < SIZE && map[tempI + 1][tempJ + 1].NnmberOfDetectrd == -1 )		//右下
				{
   
   
					map[tempI][tempJ].NnmberOfDetectrd++;
				}
			}
		}
	}

	int help = 0;
	while( help <= SIZE - 2 )					//翻开一些方块,来帮助玩家。
	{
   
   
		magic = time(&t1) % 100;
		tempI = ( magic * rand() ) % SIZE;
		tempJ = ( magic * rand() ) % SIZE;

		if( -1 != map[tempI][tempJ].NnmberOfDetectrd && 1 != map[tempI][tempJ].rw)
		{
   
   
			map[tempI][tempJ].rw = 1;
			help++;
		}
		else
		{
   
   
			continue;
		}
	}

	return 1;
}
第3部分的代码块

打印出我们的地图以及任意时刻地图的样式。
pointerI和pointerJ这两个变量规定了圆圈在地图上的位置。

int PRINT( SmallSquare map[SIZE][SIZE] , int *pointerI , int *pointerJ )
{
   
   
/*地图样式

雷|  0  1  2  3  4  5  6
-------------------------   
0 |  #  #  #  #  #  #  #
  |
1 |  #  #  #  #  #  #  #
  |
2 |  #  #  #  #  #  #  #
  |
3 |  #  #  #  #  #  #  #
  |
4 |  #  #  #  #  #  #  #
  |
5 |  #  #  #  #  #  #  #
  |
6 |  #  #  #  #  #  #  #

*/
	system("cls");
	int tempI , tempJ;

	//打印地图
	printf("请输入wasd来控制指针移动\n");
	printf("'○'表示指针\n");
	printf("'Z'表示左键,及走上去。\n");
	printf("'X'表示右键,及标记该处有雷\n");

	printf("雷|  0  1  2  3  4  5  6 \n");
	printf("-------------------------\n");
	for( tempI = 0 ; tempI < SIZE ; tempI++ )
	{
   
   
		printf("%d |",tempI);

		for( tempJ = 0 ; tempJ < SIZE ; tempJ++ )
		{
   
   
			if( tempI == *pointerI && tempJ == *pointerJ )
			{
   
   
				printf(" ○");
			}
			else if( map[tempI][tempJ].rw == 0 )
			{
   
   
				printf("  #");
			}
			else if( map[tempI][tempJ].rw == 1 )
			{
   
   
				printf("  %d",map[tempI][tempJ].NnmberOfDetectrd);
			}
			else if( map[tempI][tempJ].rw == 2 )
			{
   
   
				printf(" ★");
			}
		}
		printf("\n");
	}
	return 0;
}
第4部分代码块

这部分代码块的作用是从玩家对键盘的输入获取一个值,并且该函数的返回值为123456分别对应wasdzx。

int GetCommand()
{
   
   
	char key;
	int TempNumber;
	
	key = _getch();
	switch(key)
	{
   
   
	case 'W':
	case 'w':
		TempNumber = 1;			//表示向上
		break;

	case 'A':
	case 'a':
		TempNumber = 2;			//表示向下
		break;

	case 'S':
	case 's':
		TempNumber = 3;			//表示向下
		break;

	case 'D':
	case 'd':
		TempNumber = 4;			//表示向左
		break;

	case 'Z':
	case 'z':
		TempNumber = 5;			//1、探测周围有多少雷 2、踩上去		(1和2同时进行)
		break;

	case 'X':
	case 'x':
		TempNumber = 6;			//标记有雷。
		break;

	default :
		printf("\n");
		printf("输入错误!!!\n");
		break;
	}
	return(TempNumber);
}
第5部分代码块

该代码块用于移动光标(圆圈)的位置。
同时这串代码也可以对玩家输入的Z和X进行判定,并且做出相应的回应以及计数玩家所扫出雷的总数目。

int MOVE( SmallSquare map[SIZE][SIZE] , int *pointerI , int *pointerJ , int command , int *win)
{
   
   
	//用户输入'W'
	if( 1 == command && 0 == *pointerI )		//特殊情况
	{
   
   
		*pointerI = SIZE - 1;
	}
	else if( 1 == command )
	{
   
   
		(*pointerI)--;							//指针向上移动
	}

	//用户输入'A'
	if( 2 == command && 0 == *pointerJ )
	{
   
   
		*pointerJ = SIZE - 1;
	}
	else if( 2 == command )
	{
   
   
		(*pointerJ)--;
	}

	//用户输入'S'
	if( 3 == command && SIZE - 1 == *pointerI )
	{
   
   
		*pointerI = 0;
	}
	else if( 3 == command )
	{
   
   
		(*pointerI)++;
	}

	//用户输入'D'
	if( 4 == command && SIZE - 1 == *pointerJ )
	{
   
   
		*pointerJ = 0;
	}
	else if( 4 == command )
	{
   
   
		(*pointerJ)++;
	}

	//用户输入'z'
	if( 5 == command )
	{
   
   
		if( -1 != map[*pointerI][*pointerJ].NnmberOfDetectrd && 0 == map[*pointerI][*pointerJ].rw)				//	不是雷的情况
		{
   
   
			map[*pointerI][*pointerJ].rw = 1;
		}
		else if( -1 == map[*pointerI][*pointerJ].NnmberOfDetectrd )			//	是雷的情况
		{
   
   
			return 0;
		}
	}

	//用户输入为'X'
	if( 6 == command )
	{
   
   
		if( -1 == map[*pointerI][*pointerJ].NnmberOfDetectrd && 0 == map[*pointerI][*pointerJ].rw )
		{
   
   
			map[*pointerI][*pointerJ].rw = 2; 
			(*win)++;
		}
		else if( -1 != map[*pointerI][*pointerJ].NnmberOfDetectrd && 0 == map[*pointerI][*pointerJ].rw )
		{
   
   
			return 0;
		}
	}
	return 1;
}

很多朋友可能会问,为什么不把数组和我们的光标位置的两个变量定义为全局变量?
由于我们的代码主要是考验我们对语言的掌握能力,同时也为了提高我们计算机运行的效率,所以我们的每一个子函数都有许多的参数。

这个代码花了我大约一天白天的时间,当然除去我们吃饭以及开会以及学习的时间。
所以还希望有条件的朋友能够给我点个赞。> ^ _ ^ <

最后希望我们大家能够一同进步,共同学习,如果有对代码看法的朋友可以在下方评论区打出,欢迎大家参与讨论。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章