您好,登錄后才能下訂單哦!
這篇文章主要講解了“C語言怎么實現掃雷算法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C語言怎么實現掃雷算法”吧!
從小到大你或許沒玩過但一定聽過的游戲——掃雷
首先我們來分一下“掃雷”的功能
這是一個簡單難度的掃雷,從外觀上,我們可以發現可供用戶操作的棋盤范圍是9×9的范圍,也就是我們建立的棋盤大小至少要為9,但是問題也就來了,我們如果只建立9×9的棋盤,那么在邊緣的格子要進行提示操作的時候就會出現數據越界問題。
為了解決數據越界的問題,我們最好創建一個比可視界面大一圈的數組,即11×11的數組
但是在我們開始做這個小游戲的時候發現了一個問題——一個數組里面包含的數據太多了,可能會發生數據重疊的現象,而且一個數組里面又要放雷,又要存放排雷之后的信息,還要遮掩雷和其他位置,太過麻煩,因此我們可以創建兩個數組,一個數組專門用來放雷,一個數組用來存放排雷的信息,注意,這兩個數組一定要保證大小一樣。
所以我們不妨設置這樣兩個數組
mine[11][11] //存放雷的信息 show[11][11] //存放排除的雷的信息 /*如果我們直接用數字11來初始化數組,局限性太大了,我們后面如果想要 **進行修改也不好改,所以我們可以引用一個全局變量來初始化數組,這樣 **即使我們以后想要玩更大的棋盤掃雷,就能夠做到一步更改。考慮到棋盤 **數組的初始化要比棋盤大一圈,所以可以設置為下面這樣。 */ #define ROW 9 //可視化界面是9×9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 mine[ROWS][COLS] show[ROWS][COLS] //為了和掃雷游戲保持一樣我們在顯示掃雷棋盤的時候用符號將它遮住,這里用的是“*”,所以數組類型就確定了 char mine[ROWS][COLS] char show[ROWS][COLS]
建立好數組之后,我們就開始思考可視化界面的建立,根據前面的信息,我們要創建一個9×9的游戲空間時得擴大一圈,因此創建的函數傳參用ROWS和COLS,并且我們對這兩個的數組初始化也要做出差異,那么要如何來保證一個函數能同時初始化2個數組呢?實現如下:
//將數組初始化的信息作為區分參數,傳入函數即可 InitBoard(mine, ROWS, COLS, '0');//沒有雷的地方存放字符‘0' InitBoard(show, ROWS, COLS, '*');//‘*'遮掩掃雷棋盤 //接收傳參的函數 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; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { printf("%c ",board[i][j]); } printf("\n"); } }
這種顯示乍一看沒什么問題,但是當你要進行輸入的時候,你就難受了,因為你不知道它的行和列,每次輸入都要去數一次,所以,我們可以進行優化
void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; for (i = 0; i <= col; i++) { printf("--");//將整個棋盤布局壓在下面,可以當做分割線 } printf("\n"); for (i = 0; i <= col; 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"); } for (i = 0; i <= col; i++) { printf("--");//將整個棋盤布局頂在上面,可以當做分割線 } printf("\n"); }
效果圖:
當掃雷棋盤可以正常顯示出來之后,我們就可以開始做設置雷了
在設置雷的時候我們需要考慮,設置多少個雷,來形成簡單,普通,困難等難度
因此,雷的數量在以后可能會發生變化,我們也可以將它設置為全局變量
#define easy_count 10
后面我們在放置雷的時候要確保它的隨機性,因此需要用到rand()函數和time()函數
void SetMine(char board[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (board[x][y] != '1')/*確保了它只有在不是‘1'的空位上去放置雷,這樣一來就可以 *避免數據覆蓋而導致雷的數量不夠*/ { board[x][y] = '1'; count--; } } }
排雷和判定勝負
void FindMine(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 = GetMineCount(mine, x, y); show[x][y] = count + '0'; DisplayBoard(show, ROW, COL); win++; } } else { printf("非法坐標,請重新輸入:>\n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功!\n"); } }
效果圖:
#pragma once #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 79 //初始化棋盤 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 board[ROWS][COLS], int row, int col); //排雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
#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; for (i = 0; i <= col; i++) { printf("--"); } printf("\n"); for (i = 0; i <= col; 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"); } for (i = 0; i <= col; i++) { printf("--"); } printf("\n"); } void SetMine(char board[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (board[x][y] != '1') { board[x][y] = '1'; count--; } } } int GetMineCount(char mine[ROWS][COLS], int x, int y) { return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'; } void FindMine(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 = GetMineCount(mine, x, y); show[x][y] = count + '0'; DisplayBoard(show, ROW, COL); win++; } } else { printf("非法坐標,請重新輸入:>\n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功!\n"); } }
#include"game.h" void menu() { printf("***********************************************\n"); printf("************ 1.play *************\n"); printf("************ 0.exit *************\n"); printf("***********************************************\n"); } void game() { printf(" >> >> >>>掃雷<<< << <<\n"); char mine[ROWS][COLS] = {0}; char show[ROWS][COLS] = {0}; InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); SetMine(mine,ROW,COL); DisplayBoard(mine, ROW, COL); DisplayBoard(show, ROW, COL); FindMine(mine,show,ROW,COL); } int main() { int input; 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"); break; } } while (input); return 0; }
感謝各位的閱讀,以上就是“C語言怎么實現掃雷算法”的內容了,經過本文的學習后,相信大家對C語言怎么實現掃雷算法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。