掃雷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;
}
很多朋友可能會問,爲什麼不把數組和我們的光標位置的兩個變量定義爲全局變量?
由於我們的代碼主要是考驗我們對語言的掌握能力,同時也爲了提高我們計算機運行的效率,所以我們的每一個子函數都有許多的參數。
這個代碼花了我大約一天白天的時間,當然除去我們喫飯以及開會以及學習的時間。
所以還希望有條件的朋友能夠給我點個贊。> ^ _ ^ <
最後希望我們大家能夠一同進步,共同學習,如果有對代碼看法的朋友可以在下方評論區打出,歡迎大家參與討論。