1. 程式人生 > 其它 >c小遊戲-掃雷

c小遊戲-掃雷

嗨,又是我,前幾天寫了個三子棋後,意猶未盡,於是乎,今天又寫了一個掃雷小遊戲。下面就是我寫的掃雷程式碼了。


在寫之前,同樣是先將思路捋一遍。
按照網頁上的掃雷遊戲,進入畫面後,首先列印一份選單,以供玩家選擇是否開始遊戲,以及選擇難度。(不過今天為了試驗程式碼,便將難度預設為簡單難度,在99的棋盤裡佈置10個雷。)選擇完難度後,進入遊戲,能看到一個99棋盤,等待玩家選擇座標。輸入座標後判斷是否踩雷,以及附近有幾顆雷。並將雷的數量列印在棋盤中。直至盤內無雷,宣佈勝利。


捋完遊戲基本邏輯,那便開始寫吧。
首先當然是主函式,
列印完選單後,便等待玩家輸入是否開始遊戲

#define ROW 9
#define COW 9
#define COWS COW+2
#define ROWS ROW+2
#define EASY 10
void Initboard(char board[ROWS][COWS], int row, int cow, char a);
void Print(char board[ROWS][COWS], int row, int cow);
void setboard(char board[ROWS][COWS], int row, int cow, int n);
void Find(char board1[ROWS][COWS], char board2[ROWS][COWS], int row, int cow);


int main()
{
int a = 0;
srand((unsigned int)time(NULL));//時間戳,建立隨機數
do
{
	menu();//列印選單
	printf("請選擇是否開始遊戲:>");
	scanf("%d", &a);
	switch (a)
	{
	case 1:
		game();//遊戲實現函式
		break;
	case 0:
		printf("退出遊戲");
		break;
	default:
		printf("輸入錯誤");
	}
} 
while (a);
return 0;
}

將選單打印出來

void menu()
{
system("cls");
printf("\n********************************");
printf("\n***********1.開始遊戲***********");
printf("\n***********0.退出遊戲***********");
printf("\n********************************\n");
}

進入遊戲後,按照掃雷邏輯,首先列印棋盤,再在棋盤內佈置雷。 再由玩家輸入座標,判斷,列印棋盤,輸入座標,判斷,列印,一直迴圈

void game()
{
char board1[ROWS][COWS] = { 0 };
char board2[ROWS][COWS] = { 0 };
Initboard(board1, ROWS, COWS, '*');//初始化棋盤,棋盤初始化內容由函式給出
Initboard(board2, ROWS, COWS, '0');//初始化棋盤
Print(board1, ROW, COW);//列印棋盤
setboard(board2, ROW, COW, EASY);//佈置雷
Find(board1, board2, ROW, COW);//下座標及判斷是否踩雷或者遊戲勝利
}

棋盤設定為兩個,一個內建,一個打印出使玩家觀察,內建棋盤內佈置雷,判斷,再由另一個打印出來附近雷的數量。
以上就是遊戲的主體過程,只要再將函式補充便可。
並且,遊戲的棋盤大小為9* 9,但我們設計的棋盤是11* 11,這也是有原因的,如果棋盤只有9* 9,那在之後判斷座標為棋盤邊緣一圈時,就需要加一個判斷條件以免越界訪問,設計為11* 11則不需要,初始化11* 11的棋盤後,只要將中間9* 9的棋盤打印出來,之後的判斷時所有格子都能遍歷。

先是將棋盤初始化化

void Initboard(char board[ROWS][COWS], int row, int cow, char a)//初始化棋盤
{
int i, j;
for (i = 0; i < row; i++)
{
	for (j = 0; j < cow; j++)
	{
		board[i][j] = a;
	}
}
}

這步很簡單,只有一個初始化的內容是由函式給出,方便兩個棋盤分別初始化為不同的值。

void Print(char board[ROWS][COWS], int row, int cow)//列印棋盤
{
printf("\n");
int i, j;
for (j = 0; j <= row; j++)
{
    printf("%d ", j);
}printf("\n");
for (i = 1; i <= row; i++)
{
	printf("%d ", i);
	for (j = 1; j <= cow; j++)
	{
		printf("%c ", board[i][j]);
	}
	printf("\n");
}
printf("————————————————\n");
}

我們的棋盤大小是11 * 11,列印只需列印9 * 9,所以迴圈的下標從1開始,到9結束。

void setboard(char board[ROWS][COWS], int row, int cow,int n)//佈置雷
{
int a = n;
while (a)
{
	int x = rand() % row + 1;
	int y = rand() % cow + 1;
	if (board[x][y] == '0')
	{
		board[x][y] = '1';
		a--;
	}
}
}

雷的位置是隨機,所以需要建立橫縱座標兩個隨機數。雷的數量也需要傳參。

int Getmine(char board2[ROWS][COWS], int x, int y)//判斷座標附近有幾個雷
{
return
	board2[x - 1][y - 1] +
	board2[x - 1][y] +
	board2[x - 1][y + 1] +
	board2[x][y - 1] +
	board2[x][y + 1] +
	board2[x + 1][y] +
	board2[x + 1][y + 1] - 7 * '0';
}


void Find(char board1[ROWS][COWS], char board2[ROWS][COWS], int row, int cow)
{
int x = 0;
int y = 0;
int n = ROW * COW - EASY;
while (n)
{
	printf("請輸入一個座標:>\n");
	scanf("%d%d", &x, &y);
	if (x >= 1 && x <= row || y >= 1 && y <= cow)
	{
		if (board2[x][y] == '1')
		{
			printf("\n很遺憾,踩到雷了:>\n");
			Print(board2, ROW, COW);
			break;
		}
		else
		{
			int count = Getmine(board2, x, y);
			board1[x][y] = count + '0';
			Print(board1, ROW, COW);
			n--;
		}
	}
	else
	{
		printf("輸入非法,重新輸入:>\n");
	}
}
if (n == 0)
{
	printf("恭喜你,排雷成功\n");
}
printf("按任意鍵繼續");
getch();
}

到了排雷的過程,建立一個計數器,計數棋盤內非雷的個數。再由玩家輸入座標後,要判斷座標是否合法,在確定座標合法後,判斷座標位置是否踩雷,如果沒有踩雷,那就將座標附近雷的數量賦值在展示用棋盤上,並打印出來,在進行輸入座標。每走一步,計數器減少1,直至棋盤內非雷個數為0;

在break出迴圈後,因為還有一種踩雷的結果會跳出迴圈,所以,在函式末尾,還需要加一個判斷計數器是否為0,只有為0,才會出現勝利。

今天的掃雷比較粗糙,很多功能都沒有,如判斷座標附近0個雷時,座標應該展開等等,之後還會補進。

感謝觀看到這裡,有不足之處,希望大佬指出。