您好,登錄后才能下訂單哦!
這篇“C語言如何實現自定義掃雷游戲”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C語言如何實現自定義掃雷游戲”文章吧。
對于用C語言實現掃雷游戲得實現,可將游戲過程分為兩個板塊。
實現游戲關鍵功能得函數
搭建合理得游戲過程
實現游戲關鍵功能
為了將游戲功能方便管理和鍵入,首先我們創建一個頭文件,mine.h
對游戲功能進行聲明。
然后創建對應的源文件mine.c
對這些函數進行定義。
對于游戲功能,我們首先想到的是構建一個目標規格的雷盤,也就是二維數組。
為了使游戲更具可玩性,所以雷盤的規格應可以自定義。所以在mine.h
頭文件中,應先用define定義ROW(行)和列(列)的標識符便于自定義。
#define ROW 15 //先將他們的規格定義為15*15 #define COL 15 #define ROWS ROW+2 #define COLS COL+2
為什么要定義后面兩個宏?
對于雷盤的的核心功能實現,必然是能夠當玩家選擇坐標以后(若該位置不是雷)能夠精確的統計以該坐標為核心周圍九宮格雷的個數,那么處于邊界的地方該如何精準的判斷呢?
所以將真正的雷盤數組規格定義ROW+2,COL+2大小,在ROW,COL規格的雷盤中隨機置雷,使得游戲結果準確。
定義雷盤和顯示盤的初始化
定義兩同規格的二維數組,前者是真正的雷區,用‘1’和‘0’來表示雷和無雷,后者是顯示區,用于玩家操作和結果顯示。
void init(char arr[ROWS][COLS], int rows, int cols, char type) //memset批量操作時傳入的是指針,即數組開始地址 { memset(arr, type, rows*cols * sizeof(mine[0][0])); }
在顯示區隨機放置雷
void setmine(char mine[ROWS][COLS], int count) { srand((unsigned)time(NULL)); int i = 0; int j = 0; while (count) { i = (rand() % ROW) + 1; //讓隨機值0-9變成1-10 實現操作區隨機放雷 j = (rand() % COL) + 1; if (mine[i][j] == '0') { mine[i][j] = '1'; count--; } } }
打印界面
void display(char board[ROWS][COLS]) {//從第一行一列開始打因元素 int i = 0; int j = 0; printf("\n |"); for (i = 1; i <= COL; i++)//打印操作區的列號 { printf("%4d", i); //打印序號 } printf("\n"); printf("------|------------------------------------------\n"); for (i = 1; i <= ROW; i++) { printf("%4d |", i);//打印序號 for (j = 1; j <= COL; j++) { printf("%4c", board[i][j]); } printf("\n \n"); } }
統計目標點周圍雷的個數
int cal_mine(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] - (7 * '0'));//這里減7而不是8。因為這樣直接可以表示出數字字符 //此處的目的是統計周圍雷的個數,又因為是ASCII碼,'1'和'0'只相差1,然后進去'0'的ASCII值得到1的個數 }
如果目標點周圍無雷向外擴展
在掃雷游戲過程中必然會出來一點一大片凹陷的強烈快感,但自己實現的過程中這是如何做到的呢?
原則是如果該點周圍無雷,那么將用空格替代,然后向四周伸展將周圍的“周圍無雷點”繼續用空格替代,若四周存在“周圍有雷點”,那么停止向周圍延伸。
在苦思冥想后,想到了用遞歸的方法來實現這個一點一大片功能。
void expand(char mine[ROWS][COLS], char board[ROWS][COLS], int x, int y) { if (x >= 1 && x <= ROW&&y >= 1 && y <= COL) // 遞歸防止越界 { /*if (mine[x][y] == '0')*/ { char count = cal_mine(mine, x, y); if (count == '0') { board[x][y] = ' '; if (board[x - 1][y - 1] == '*') { expand(mine, board, x - 1, y - 1); } if (board[x - 1][y] == '*') { expand(mine, board, x - 1, y); } if (board[x - 1][y + 1] == '*') { expand(mine, board, x - 1, y + 1); } if (board[x][y - 1] == '*') { expand(mine, board, x, y - 1); } if (board[x][y + 1] == '*') { expand(mine, board, x, y + 1); } if (board[x + 1][y - 1] == '*') { expand(mine, board, x + 1, y - 1); } if (board[x + 1][y] == '*') { expand(mine, board, x + 1, y); } if (board[x + 1][y + 1] == '*') { expand(mine, board, x + 1, y + 1); } } else { board[x][y] = count; } } } }
判斷勝利
若顯示區最終剩下的*等于雷數,那么玩家勝利
int is_win(char board[ROWS][COLS]) { int count = 0; int i = 0, j = 0; for (i = 1; i <= ROW; i++) { for (j = 1; j <= COL; j++) { if ('*' == board[i][j]) { count++; } } } return count; }
玩家操作
int player(char mine[ROWS][COLS], char board[ROWS][COLS], int count) { int x = 0, y = 0; while (1)//檢測輸入錯誤區 { while (2 != scanf("%d %d", &x, &y)) { while ((getchar() != '\n')) //如果玩家輸入了很多非法字符,那么將他們全部吸收 { NULL; } printf("輸的是啥玩意?\n"); } if (x < 1 || x > ROW || y < 1 || y > COL) { printf("輸入越界\n"); } else if (board[x][y] != '*') { printf("你踩過了!\n"); } else { if (count == 1 && (mine[x][y] == '1')) //!mine[x][y]=='1'這個條件特別重要!!如果玩家沒有踩到雷那么將會使這個位置變成雷!! //雖然這樣并不影響程序完整運行,因為檢驗雷點是通過存在的*來計數的,這個值附上去以后肯定恒為1占去了*,但是嚴謹的玩家肯定說你有BUG //所以我們還是盡量寫通俗易懂的邏輯程序 下面的while循環會讓人感覺是檢測,其實是賦值轉換 { int i = 0, j = 0; while (mine[x][y] == '1') { i = (rand() % 10) + 1; j = (rand() % 10) + 1; mine[x][y] = mine[i][j];//將值為符號零的元素賦給操作數, } mine[i][j] = '1';//賦值如果成功那么便讓他成為1 } } break; } if (mine[x][y] == '1')//檢驗開始 { printf("\n新時代的董存瑞!\n"); return 1; } else { expand(mine, board, x, y); } return is_win(board); }
最后將這些聲明和定義轉入到mine.h
和mine.c
將這些函數功能合理的整個在一起后,在mian函數存在的源文件中創建定義game()函數,將每一步連接在一起。創建menu()函數顯示菜單。
game()
void game() { printf("歡\n"); Sleep(250); printf("迎\n"); Sleep(250); printf("來\n"); Sleep(250); printf("到\n"); Sleep(250); printf("caco\n"); Sleep(250); printf("的\n"); Sleep(250); printf("掃\n"); Sleep(250); printf("雷!\n"); Sleep(250); printf("村"); Sleep(250); printf("!"); Sleep(150); printf("!"); Sleep(150); char mine[ROWS][COLS] = { 0 }; char board[ROWS][COLS] = { 0 }; init(mine, ROWS, COLS, '0'); init(board, ROWS, COLS, '*'); int num = 0; printf("\n要幾個雷\n?"); scanf("%d", &num); setmine(mine, num); display(mine); int count = 1; int ret = 0; while (1) { display(board); ret = player(mine, board, count); count++; if (ret == num) //和玩家輸入得雷數要保持一致 { printf("炸不死得諾貝爾~!\n"); break; } if (ret == 1) { break; //表示直接菜到雷退出 } } }
munu()
void menu() { printf("*******************************************\n"); printf("------ 我可以大口吞下炸彈而不傷身體--------\n"); //label 1. original test. printf("------1. 進村 -------------------------\n-------------------------\n"); printf("------0. 撤退! -------------------------\n"); printf("*******************************************\n"); } int main() { int a = 0; menu(); do { scanf("%d", &a); switch (a) { case 1: game(); menu(); break; case 0: return 0; default: printf("\n進村還是不進?\n"); } } while (a); }
main()函數
int main() { int a = 0; menu(); do { scanf("%d", &a); switch (a) { case 1: game(); menu(); break; case 0: return 0; default: printf("\n進村還是不進?\n"); } } while (a); }
mine.h
#pragma once #define ROW 15 #define COL 15 #define ROWS ROW+2 #define COLS COL+2 void init(char mine[ROWS][COLS], int rows, int cols, char type);//初始化數組 void setmine(char mine[ROWS][COLS], int count);//放置隨機雷 void display(char board[ROWS][COLS]);//顯示界面 int cal_mine(char mine[ROWS][COLS], int x, int y);//統計周圍雷的個數 int player(char mine[ROWS][COLS], char board[ROWS][COLS],int count);//玩家操作 void expand(char mine[ROWS][COLS], char board[ROWS][COLS], int x, int y);//遞歸展開 int is_win(char board[ROWS][COLS]);//判斷勝利
mine.c
前文已展示定義
main.h
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<Windows.h> #include"mine.h" void game() { printf("歡\n"); Sleep(250); printf("迎\n"); Sleep(250); printf("來\n"); Sleep(250); printf("到\n"); Sleep(250); printf("caco\n"); Sleep(250); printf("的\n"); Sleep(250); printf("掃\n"); Sleep(250); printf("雷!\n"); Sleep(250); printf("村"); Sleep(250); printf("!"); Sleep(150); printf("!"); Sleep(150); char mine[ROWS][COLS] = { 0 }; char board[ROWS][COLS] = { 0 }; init(mine, ROWS, COLS, '0'); init(board, ROWS, COLS, '*'); int num = 0; printf("\n要幾個雷\n?"); scanf("%d", &num); setmine(mine, num); display(mine); int count = 1; int ret = 0; while (1) { display(board); ret = player(mine, board, count); count++; if (ret == num) //和玩家輸入得雷數要保持一致 { printf("炸不死得諾貝爾~!\n"); break; } if (ret == 1) { break; //表示直接菜到雷退出 } } } void menu() { printf("*******************************************\n"); printf("------ 我可以大口吞下炸彈而不傷身體--------\n"); //label 1. original test. printf("------1. 進村 -------------------------\n-------------------------\n"); printf("------0. 撤退! -------------------------\n"); printf("*******************************************\n"); } int main() { int a = 0; menu(); do { scanf("%d", &a); switch (a) { case 1: game(); menu(); break; case 0: return 0; default: printf("\n進村還是不進?\n"); } } while (a); }
程序運行
以上就是關于“C語言如何實現自定義掃雷游戲”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。