C | 扫雷游戏完整版
啊我摔倒了..有沒有人扶我起來學習....
目錄
- 1. 前言
- 2. 游戲實現
- 2.1 一些建議
- 2.2 游戲整體框架
- 2.3 棋盤的實現
- 2.4 關于雷
- 2.5 贏的實現
- 3. 代碼段
- 3.1 test.c
- 3.2 game.c
- 3.3 game.h
1. 前言
《掃雷》是一款大眾類的益智小游戲,于1992年發(fā)行。游戲目標是在最短的時間內根據點擊格子出現的數字找出所有非雷格子,同時避免踩雷,踩到一個雷即全盤皆輸。
現用C程序簡單實現一下掃雷游戲,對應玩法為:
??????????????
2. 游戲實現
2.1 一些建議
這次來個保姆級教學,希望小白都可以學會~所以我們會一步一步實現各個功能,接下來出現在代碼中注釋掉的部分先不要看,當做我們還沒寫。代碼段也會在下面分塊給出。好了,廢話不多說,我們直接開干!
2.2 游戲整體框架
3.為了實現清屏的效果,可以在每次輸入后邊加上 system(“cls”);
2.3 棋盤的實現
(1)mine數組用來儲存雷,以1為雷,0為空。(如果同時用該數組表示所選坐標周圍雷的個數,那么就會產生沖突,于是多定義一個數組)
(2)show用來展示該坐標周圍的雷個數。
假如數組是[9][9],那么當選中的坐標為棋盤邊上的時候,show數組就會產生越界訪問的錯誤,因為圖中的“2”就是通過計算該坐標周圍八個空格而來。為了不產生越界,我們應該在9×9的基礎上,上下左右各增加一層空位,于是數組得是[11][11]的。
(1)但有一點要特別注意藍色方框部分,雖然我們的數組是11×11的,但是mine埋雷和show展示雷個數的區(qū)域我們希望是9×9,所以傳ROW、COL給打印棋盤的函數,用形參row、col接收。
(2)橙色框表示打印出行號列號。
(3)黑色框要注意i是從1開始而不是0,因為數組mine和show是11×11的,而我們要展示的是9×9。
2.4 關于雷
這部分我想分得更細致一點。
- 布置雷
打印出來檢查一下,果然是10顆雷。同樣的,打印檢查之后記得刪掉這行代碼~
- 排雷
這里是超級無敵重點部分!!!
先大致瀏覽一下排雷代碼
分析排雷函數的大框架
咱們拿出黃色方框部分仔細分析排雷過程:
1)先分析非遞歸部分的實現
2)其中get_mine_count的實現:
把所選坐標(X,Y)附近八個點全加起來就是雷的個數,但是注意紅色方框的目的是把字符轉換成整形。因為mine數組里面的0和1是字符來的并不是數字。而這是怎么轉換的呢?例如‘7’-‘0’=7,不信你翻ASCII表,這就轉過來啦。
3)遞歸部分的實現
? 遞歸展開的條件是:1.所選坐標周圍沒有雷;
??????????2.所選坐標未被排查過。
注:第二點的用意是,不讓遞歸無限循環(huán)下去。那么實現這一點,我們需要再定義一個數組負責標記排查過的地方。
2.5 贏的實現
非常簡單!具體來看看是怎么實現的吧~
利用總的地雷數等于show所剩的星號“*”的個數相等來實現贏的功能,比如一共10顆雷,排雷排到最后還剩10個星號,可不就都是雷,贏了!
3. 代碼段
Gitee倉庫
3.1 test.c
//掃雷游戲 #include "game.h"void game() {char mine[ROWS][COLS] = { 0 };//儲存雷char show[ROWS][COLS] = { 0 };//展示周圍雷個數char contrast[ROWS][COLS] = { 0 };//把排查過的坐標進行標記//初始化棋盤init_board(mine, ROWS, COLS, '0');init_board(show, ROWS, COLS, '*');//打印棋盤display_board(show, ROW, COL);//布置雷set_mine(mine, ROW, COL);//排雷find_mine(mine, show, contrast, ROW, COL); }void menu() {printf("****************\n");printf("****1. play ****\n");printf("****0. exit ****\n");printf("****************\n");//printf("嚶嚶嚶~共有%d顆雷,好害怕!\n", EASY_COUNT); }int main() {srand((unsigned int)time(NULL));int input = 0;do{menu();printf("小伙子請選擇:>");scanf("%d", &input);system("cls");switch (input){case 1:game();break;case 0:printf("不玩了!回家找媽媽~\n");break;default:printf("笨啊,這都能輸錯,請重新輸入!\n");break;}} while (input);return 0; }3.2 game.c
#include "game.h"//統(tǒng)計show中'*'的數量,實現游戲贏的功能 int count_mine(char show[ROWS][COLS], int row,int col) {int count = 0;for (int i = 1; i <= row; i++){for (int j = 1; j <= col; j++){if (show[i][j] == '*')count++;}}return count; }//遞歸擴展排雷 void Extend_board(char mine[ROWS][COLS], char show[ROWS][COLS], char contrast[ROWS][COLS], int x, int y) {if (get_mine_count(mine, x, y) == 0)//get_mine_count函數返回存儲地雷信息的mine數組中x y位置周圍一圈(8個位置)的地雷總和{for (int i = x - 1; i <= x + 1; i++) //不得超出棋盤大小{for (int j = y - 1; j <= y + 1; j++) //不得超出棋盤大小{show[i][j] = (get_mine_count(mine, i, j)+'0'); //將該位置一圈地雷總和信息傳遞到show()函數if (show[i][j] == '0' && contrast[i][j] != '$') //如果該位置周圍沒有地雷且沒有被標記{contrast[i][j] = '$'; //將該位置標記Extend_board(mine, show, contrast, i, j); //調用遞歸函數再次進行判斷}}}}elseshow[x][y] = (get_mine_count(mine, x, y) + '0');return; }//統(tǒng)計雷的數量 int get_mine_count(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 find_mine(char mine[ROWS][COLS], char show[ROWS][COLS],char contrast[ROWS][COLS], int row, int col) {int x, y;int win = 0;while (win != EASY_COUNT){printf("請輸入排雷的坐標:>");scanf("%d %d", &x, &y);system("cls");if (x >= 1 && x <= row && y >= 1 && y <= col){if (show[x][y] == '*'){if (mine[x][y] == '1'){printf("很遺憾,你被炸毛了!\n");break;}else{contrast[x][y] = '$';Extend_board(mine, show, contrast, x, y);display_board(show, ROW, COL);win = count_mine(show, ROW, COL);}}else{printf("該位置坐標已經排查過啦,請重新輸入!\n");display_board(show, ROW, COL);}}else{printf("無效的坐標哦~請重新輸入!\n");display_board(show, ROW, COL);}}if (win == EASY_COUNT)printf("恭喜您,掃雷成功!獎勵一拖鞋~\n"); } //布置雷 void set_mine(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--;}} } //打印棋盤 void display_board(char board[ROWS][COLS], int row, int col) {for (int j = 0; j <= col; j++)printf("%d ", j);printf("\n");for (int i = 1; i <= row; i++){printf("%d ", i);for (int j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");} } //初始化棋盤 void init_board(char board[ROWS][COLS], int row, int col, char set) {for (int i = 0; i < row; i++){for (int j = 0; j < col; j++)board[i][j] = set;} }3.3 game.h
#define _CRT_SECURE_NO_WARNINGS#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 10//初始化棋盤 void init_board(char board[ROWS][COLS], int row, int col, char set); //打印棋盤 void display_board(char board[ROWS][COLS], int row, int col); //布置雷 void set_mine(char mine[ROWS][COLS], int row, int col); //排雷 void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], char contrast[ROWS][COLS], int row, int col); //統(tǒng)計雷的數量 int get_mine_count(char mine[ROWS][COLS], int x, int y); //自動擴展排雷 void Extend_board(char mine[ROWS][COLS], char show[ROWS][COLS], char contrast[ROWS][COLS], int x, int y, int* win); //統(tǒng)計show中'*'的數量,實現游戲贏的功能 int count_mine(char show[ROWS][COLS], int row, int col);總結
以上是生活随笔為你收集整理的C | 扫雷游戏完整版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQL基础:mysql客户端工具
- 下一篇: halcon 单通道图像转成3通道_ha