目錄
前言
前期的準備
游戲代碼的具體實作
1、text.c
2、game.h
3、game.c
完整版的掃雷小游戲代碼:
1、game.h
2、text.c
3、game.c
總結
前言
《掃雷》是一款大眾類的益智小游戲,于1992年發行,游戲目標是在最短的時間內根據點擊格子出現的數字找出所有非雷格子,同時避免踩雷,踩到一個雷即全盤皆輸,
而現在,學習了已有的知識后,我們不僅有能力自己用代碼寫出簡單的三字棋小游戲,還可以寫一些稍稍簡單的掃雷了,怎么樣,雖然比不上用滑鼠稍稍點擊就可以判斷的發行版本,但是也可以是使自己感到滿足了,好了,話不多說,讓我們一起去了解掃雷的代碼實作吧!(本篇博客和上一篇三字棋博客的大致方向是差不多的,如果大家先看一看上一篇博客的話效果會跟好哦),
前期的準備
和上一篇博客一樣,同樣需要模塊化的思想,將其分成3個模塊:text.c,game.c,game.h,
text.c:游戲的測驗邏輯(主函式;游戲的邏輯實作)
game.c:游戲的實作邏輯(各種所需要的函式的實作)
game.h:游戲實作函式的宣告;行號、列號的宣告;頭檔案的包含
游戲的思路:
1.使用do...while回圈,讓游戲至少執行一次,列印出選單模塊,設計選單函式;玩家進入游戲后,可以根據自己的選擇決定是否來玩游戲,提示用戶輸入,根據輸入值來確定后續的游戲行程(1代表玩游戲,0代表退出,其他需要重新選擇),
2.熟練的使用陣列和函式,若只創建一個棋盤,把雷放上去之后,玩家就可以直接看見,沒有任何的可玩性,所以我們需要兩個棋盤,一個用來我們內部實作的,存放一些雷,而另一個則是給玩家看的,
3創建完以后呢,就可以放置一些雷在內部陣列中,
4.最后,完成坐標的輸入;對雷的排查,每排查一個雷所展現在玩家眼前不同的棋盤,以及踩到雷或是掃雷成功的提示和演算法實作,
游戲代碼的具體實作
1、text.c
主函式:
int main() { test(); return 0; }test()函式的具體實作:
void test() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請選擇:>"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戲\n"); break; default: printf("選擇錯誤,請重新選擇\n"); } } while (input); }選單界面(可調于test函式):
void menu() { printf("***********************\n"); printf("***** 1. play ****\n"); printf("***** 0. exit ****\n"); printf("***********************\n"); }游戲函式:
void game() { //創建布置雷的資訊的陣列(內部,不給玩家看) char mine[ROWS][COLS] = { 0 }; //創建排查雷的資訊的陣列(外部,給玩家看的) char show[ROWS][COLS] = { 0 }; //初始化棋盤 InitBoard(mine, ROWS, COLS, '0');//把內部全部初始化為0 InitBoard(show, ROWS, COLS, '*');//把外部全部初始化為* //DisplayBoard(mine, ROW, COL);(列印這個棋盤可以自己除錯用,但不給玩家看) //DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); //列印棋盤(想要列印中間的9*9的棋盤,但傳過去的是11*11的整個陣列) DisplayBoard(show, ROW, COL); //排查雷 FineMine(mine, show, ROW, COL); }
2、game.h
//頭檔案的包含 #include <stdio.h> #include <time.h> #include <stdlib.h> //符號的宣告 #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 //函式的宣告 //初始化棋盤 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //列印棋盤 void DisplayBoard(char board[ROWS][COLS], int row, int col); //布置雷 void SetMine(char mine[ROWS][COLS], int row, int col); //排查雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
3、game.c
這個是整個游戲的最重要的一步(各個函式的作用在上面的游戲函式寫了,我就直接上代碼了),
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } } void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; //列印列號,因為之前列印了個行號,所以讓第一列是0,但得多列印一行, //所以前面i=0,后面i<=row for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { //列印行號 printf("%d ", i); //列印棋盤 for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void SetMine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } static int get_mine_count(char mine[ROWS][COLS], int x, int y) { return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0'; } void open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { int count = get_mine_count(mine, x, y); if (count == 0) { show[x][y] = ' '; if (show[x - 1][y - 1] == '*') open_mine(mine, show, x - 1, y - 1); if (show[x - 1][y] == '*') open_mine(mine, show, x - 1, y); if (show[x - 1][y + 1] == '*') open_mine(mine, show, x - 1, y + 1); if (show[x][y - 1] == '*') open_mine(mine, show, x, y - 1); if (show[x][y + 1] == '*') open_mine(mine, show, x, y + 1); if (show[x + 1][y - 1] == '*') open_mine(mine, show, x + 1, y - 1); if (show[x + 1][y] == '*') open_mine(mine, show, x + 1, y); if (show[x + 1][y + 1] == '*') open_mine(mine, show, x + 1, y + 1); } else show[x][y] = get_mine_count(mine, x, y) + '0'; } void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win < row * col - EASY_COUNT) { printf("請輸入要排查雷的坐標:>"); scanf("%d %d",&x, &y); //判斷坐標是否合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { //踩雷 if (mine[x][y] == '1') { printf("很遺憾,你被炸死了\n"); DisplayBoard(mine, row, col); break; } //未踩雷 else { //int count = get_mine_count(mine, x, y); //show[x][y] = count + '0';//使用遞回后不需要這兩個了,在open_mine中實作了這 //些功能 open_mine(mine, show, x, y);//如果輸入坐標附近無雷,則向四周展開直到遇到雷 DisplayBoard(show, ROW, COL);//每次排雷后再次列印棋盤 win++; } } else { printf("坐標非法,請重新輸入\n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功\n"); DisplayBoard(mine, row, col); } }上面使用遞回實作的,如果不想實作展開的話,可以這樣做(洗掉open_mine,并且解除上面注釋的內容)
//open_mine函式洗掉全部內容 void open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win < row * col - EASY_COUNT) { printf("請輸入要排查雷的坐標:>"); scanf("%d %d",&x, &y); //判斷坐標是否合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { //踩雷 if (mine[x][y] == '1') { printf("很遺憾,你被炸死了\n"); DisplayBoard(mine, row, col); break; } //未踩雷 else { int count = get_mine_count(mine, x, y); show[x][y] = count + '0'; //使用上面這兩個 //open_mine(mine, show, x, y);//洗掉該函式 DisplayBoard(show, ROW, COL);//每次排雷后再次列印棋盤 win++; } } else { printf("坐標非法,請重新輸入\n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功\n"); DisplayBoard(mine, row, col); } }
完整版的掃雷小游戲代碼:
1、game.h
//頭檔案的包含 #include <stdio.h> #include <time.h> #include <stdlib.h> //符號的宣告 #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 //函式的宣告 //初始化棋盤 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //列印棋盤 void DisplayBoard(char board[ROWS][COLS], int row, int col); //布置雷 void SetMine(char mine[ROWS][COLS], int row, int col); //排查雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
2、text.c
#include "game.h" void menu() { printf("***********************\n"); printf("***** 1. play ****\n"); printf("***** 0. exit ****\n"); printf("***********************\n"); } void game() { //創建布置雷的資訊的陣列(內部,不給玩家看) char mine[ROWS][COLS] = { 0 }; //創建排查雷的資訊的陣列(外部,給玩家看的) char show[ROWS][COLS] = { 0 }; //初始化棋盤 InitBoard(mine, ROWS, COLS, '0');//把內部全部初始化為0 InitBoard(show, ROWS, COLS, '*');//把外部全部初始化為* //DisplayBoard(mine, ROW, COL);(列印這個棋盤可以自己除錯用,但不給玩家看) //DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); //列印棋盤(想要列印中間的9*9的棋盤,但傳過去的是11*11的整個陣列) DisplayBoard(show, ROW, COL); //排查雷 FineMine(mine, show, ROW, COL); } void test() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請選擇:>"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戲\n"); break; default: printf("選擇錯誤,請重新選擇\n"); } } while (input); } int main() { test(); return 0; }
3、game.c
#include "game.h" void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } } void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; //列印列號,因為在之前列印了個行號,所以讓第一列是0,但得多列印一行, //所以前面i=0,后面i<=row for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { //列印行號 printf("%d ", i); //列印棋盤 for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void SetMine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } static int get_mine_count(char mine[ROWS][COLS], int x, int y) { return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0'; } void open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { int count = get_mine_count(mine, x, y); if (count == 0) { show[x][y] = ' '; if (show[x - 1][y - 1] == '*') open_mine(mine, show, x - 1, y - 1); if (show[x - 1][y] == '*') open_mine(mine, show, x - 1, y); if (show[x - 1][y + 1] == '*') open_mine(mine, show, x - 1, y + 1); if (show[x][y - 1] == '*') open_mine(mine, show, x, y - 1); if (show[x][y + 1] == '*') open_mine(mine, show, x, y + 1); if (show[x + 1][y - 1] == '*') open_mine(mine, show, x + 1, y - 1); if (show[x + 1][y] == '*') open_mine(mine, show, x + 1, y); if (show[x + 1][y + 1] == '*') open_mine(mine, show, x + 1, y + 1); } else show[x][y] = get_mine_count(mine, x, y) + '0'; } void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win < row * col - EASY_COUNT) { printf("請輸入要排查雷的坐標:>"); scanf("%d %d",&x, &y); //判斷坐標是否合法 if (x >= 1 && x <= row && y >= 1 && y <= col) { //踩雷 if (mine[x][y] == '1') { printf("很遺憾,你被炸死了\n"); DisplayBoard(mine, row, col); break; } //未踩雷 else { open_mine(mine, show, x, y);//如果輸入坐標附近無雷,則向四周展開直到遇到雷 DisplayBoard(show, ROW, COL);//每次排雷后再次列印棋盤 win++; } } else { printf("坐標非法,請重新輸入\n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功\n"); DisplayBoard(mine, row, col); } }
總結
本次博客到這里就接近尾聲了,有啥不足的地方,歡迎提出來一起共同進步哦!如果喜歡這篇博客的話,歡迎鐵汁們動動你們的小手,一鍵三連哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/357210.html
標籤:其他
下一篇:c語言實作掃雷(簡易版)



