博主是一位刚上大一的新生,自学了C语言两个月左右。博主最近临近期末,作为大学生也没有什么事可以干,于是就在寝室里面写了这个C++的扫雷低配版,供大家分享学习也可以大家进行讨论,欢迎大家的各种意见和见解。
我的作品还是老规矩哈。
想要下载源代码,得先关注孩子一波哦> ^ _ ^ <
点击——>扫雷C++源代码
点个赞吧,孩子三天没吃饭了。
第1个视频是屏幕录制的游戏的玩的过程。
第2个视频是操作介绍,用于帮助语文小白。
扫雷
操作
这是第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 );
这部分代码用于游戏的初始化。
里面对数组的某些子成员进行了赋值,并且判断了每个方块周围有多少个地雷。
这个函数还自动为玩家翻开了一些方块,也方便玩家进行游玩。
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;
}
打印出我们的地图以及任意时刻地图的样式。
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;
}
这部分代码块的作用是从玩家对键盘的输入获取一个值,并且该函数的返回值为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);
}
该代码块用于移动光标(圆圈)的位置。
同时这串代码也可以对玩家输入的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;
}
很多朋友可能会问,为什么不把数组和我们的光标位置的两个变量定义为全局变量?
由于我们的代码主要是考验我们对语言的掌握能力,同时也为了提高我们计算机运行的效率,所以我们的每一个子函数都有许多的参数。
这个代码花了我大约一天白天的时间,当然除去我们吃饭以及开会以及学习的时间。
所以还希望有条件的朋友能够给我点个赞。> ^ _ ^ <
最后希望我们大家能够一同进步,共同学习,如果有对代码看法的朋友可以在下方评论区打出,欢迎大家参与讨论。