日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

扫雷游戏(进阶版)

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 扫雷游戏(进阶版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

掃雷(簡易版)

掃雷(進階版)【加料】


掃雷(簡易版)

掃雷游戲都玩過吧,童年回憶了屬于是,今天我們就用代碼來實現一下。

首先創建3個文件,分別用來存放 游戲測試(test.c),游戲的頭(game.h) ,游戲具體內容實現(game.c)。

游戲測試(test.c)

?在游戲測試(test.c)中設置游戲入口(具體過程和之前三子棋教程一樣CSDN,有興趣大家可以看看)。

代碼實現:

#include"game.h"void menu() {printf("******************\n");printf("*****1. play *****\n");printf("*****0. exit *****\n");printf("******************\n"); } void game() {; } int main() {int input = 0;do{menu();printf("請選擇\n");scanf("%d", &input);switch (input){case 1:printf("進入游戲\n");game();break;case 0:printf("退出游戲\n");break;default:printf("輸入有誤,請重試\n");break;}} while (input);return 0; }

游戲入口設立好了,接下來就是實現掃雷游戲的函數。

界面分析:

先來看看掃雷游戲的界面:

?這是一個9*9的棋盤,上面布置了10個雷。我們設置有雷處為'1',無雷處為'0',(注意是字符1和0),布置完雷后我們需要排查,排查一個坐標如果是雷就炸死了,不是雷會標出周圍8個坐標雷的個數。

?這里實現時有個問題,標出周圍雷的數字時,如果是1的話,就和前面"是不是雷" 產生沖突了,所以我們再創建一個棋盤,專門用來排查雷。

?還有個問題,像圖一這種排查沒什么問題,但是圖二這樣排查,就超出范圍越界了,所以我們創建數組時,多給兩行兩列,創建成11*11的。展現時給出9*9的就行了。

下面來看代碼實現:

char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };

這里的ROWS代表11*11數組的行,COLS代表列

在頭文件中定義常量ROW,COL(9*9數組的行和列),ROWS,COLS(11*11數組的行和列)

不寫死,方便后期修改。

#define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2

定義棋盤:

然后我們定義棋盤board

void game() {char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };Initboard(mine, ROWS, COLS, '0');//布置雷棋盤Initboard(show, ROWS, COLS, '*');//排查雷棋盤 }

頭文件:

?game.c:

Initboard(char board[ROWS][COLS], int rows, int cols,char set) {int i, j;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set;}} }

這里用一個函數InitBoard將兩種棋盤一起實現了,但是初始化的時候,布置雷棋盤初始為'0’ ,排查雷棋盤初始為'*' ,所以再將各自初始的東西傳參給InitBoard,就方便很多了。

打印棋盤:

接下來打印我們的棋盤來看一下:

寫一個Display函數,為了好看,加上“掃雷游戲”的邊框,以及坐標軸

?代碼實現:

void DisplayBoard(char board[ROWS][COLS], int row, int col) {printf("----掃雷游戲----\n");int i, j;for (j = 0; j <= col; j++){printf("%d ", j);}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("----掃雷游戲----\n"); }

布置雷:

棋盤有了接著該布置雷了。

寫一個SetMine函數,用srand函數放進隨機值。

代碼實現:

void SetMine(char mine[ROWS][COLS], int row, int col) {int count = Count_mine;while (count){int x = rand() % 9 + 1;int y = rand() % 9 + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}} }

Count_mine在頭文件中定義了

?注意調用rand時,在test.c中包含srand函數:

srand((unsigned int)time(NULL));

打印一下棋盤看布置雷的效果:

?確實是隨機布置了10個雷。

排查雷:

布置完雷接下來就是排查雷了。

排查雷先要輸入坐標,那就要判斷坐標的合法性。坐標范圍是1~9,且不能輸入重復坐標。

接著就是利用循環進行排查了,如果碰到雷,那就被炸死。不是雷,就標上周圍雷的個數。

那么這里需要計數,可以用循環計算,也可以將周圍8個坐標相加-'0'*8,就是雷的個數。

代碼實現:

int count_round_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]-'0'*8; //法二:循環/*int count = 0;int i, j;for (i = -1; i <= 1; i++){for (j = -1; j <= 1; j++){if (mine[x+i][y+j] == '1'){count++;}}}return count;*/ } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {while (1){int x, y;scanf("%d%d", &x, &y);int ret = 0;if (x > 0 && x <= row && y > 0 && y <= col){if (show[x][y] == '*'){if (mine[x][y] == '1'){printf("很遺憾,你被炸死了\n");DisplayBoard(show, ROW, COL);}else{ret = count_round_mine(mine, x, y);show[x][y] = '0' + ret;DisplayBoard(show, ROW, COL);}}elseprintf("坐標已被占用,請重新輸入\n");}elseprintf("輸入無效坐標,請重試\n");} }

但是這樣有個問題,我們無法結束游戲,所以需要判斷游戲結束的條件。

1、被炸死?????????? 2、排查完棋盤上所有非雷的位置

代碼實現:

void SetMine(char mine[ROWS][COLS], int row, int col) {int count = Count_mine;while (count){int x = rand() % 9 + 1;int y = rand() % 9 + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}} }int count_round_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]-'0'*8;} void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {int win = row * col - Count_mine;while (win){int x, y;scanf("%d%d", &x, &y);int ret = 0;if (x > 0 && x <= row && y > 0 && y <= col){if (show[x][y] == '*'){if (mine[x][y] == '1'){printf("很遺憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);}else{ret = count_round_mine(mine, x, y);show[x][y] = '0' + ret;DisplayBoard(show, ROW, COL);win--;}}elseprintf("坐標已被占用,請重新輸入\n");}elseprintf("輸入無效坐標,請重試\n");}if (win == 0){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);} }

完整代碼(三部分):

game.h:

#define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define Count_mine 10#include<stdio.h> #include<time.h> #include<stdlib.h>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);

test.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');//布置雷棋盤Initboard(show, ROWS, COLS, '*');//排查雷棋盤DisplayBoard(show, ROW, COL);SetMine(mine, ROW, COL);FindMine(mine, show, ROW, COL); } int main() {srand((unsigned int)time(NULL));int input = 0;do{menu();printf("請選擇\n");scanf("%d", &input);switch (input){case 1:printf("進入游戲\n");game();break;case 0:printf("退出游戲\n");break;default:printf("輸入有誤,請重試\n");break;}} while (input);return 0; }

game.c:

????????

#include"game.h"void Initboard(char board[ROWS][COLS], int rows, int cols,char set) {int i, j;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) {printf("----掃雷游戲----\n");int i, j;for (j = 0; j <= col; j++){printf("%d ", j);}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("----掃雷游戲----\n"); }void SetMine(char mine[ROWS][COLS], int row, int col) {int count = Count_mine;while (count){int x = rand() % 9 + 1;int y = rand() % 9 + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}} }int count_round_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]-'0'*8;*/int count = 0;int i, j;for (i = -1; i <= 1; i++){for (j = -1; j <= 1; j++){if (mine[x+i][y+j] == '1'){count++;}}}return count; } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {int win = row * col - Count_mine;while (win){int x, y;scanf("%d%d", &x, &y);int ret = 0;if (x > 0 && x <= row && y > 0 && y <= col){if (show[x][y] == '*'){if (mine[x][y] == '1'){printf("很遺憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);}else{ret = count_round_mine(mine, x, y);show[x][y] = '0' + ret;DisplayBoard(show, ROW, COL);win--;}}elseprintf("坐標已被占用,請重新輸入\n");}elseprintf("輸入無效坐標,請重試\n");}if (win == 0){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);} }

掃雷(進階版)【加料】

?我們可以觀察到網頁版的掃雷較之我們上面寫的簡易版有兩個特點:

1、有標記功能,可以自行記錄埋藏雷的位置

2、有展開一片功能,如果點開位置附近一片都沒有雷,會自行展開。

下面進階版主要實現這兩個功能。

1、標記功能:

我們定義標記符號為‘#’。

在排查雷函數中寫一個標記雷函數SignMine,注意一定是在FindMine函數中寫。

SignMine代碼實現如下:

void SignMine(char show[ROWS][COLS], int row, int col) {int a = 0;printf("請輸入需要標記的次數\n");scanf("%d", &a);while (a){printf("請輸入需要標記的坐標\n");int x = 0, y = 0;scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (show[x][y] == '*'){show[x][y] = '#';a--;}elseprintf("該坐標已被占用,請重新輸入\n");}elseprintf("無效標記,請重試\n");} }

我們要標記幾次,就輸入幾個標記的坐標。

2、展開一片功能:

分析:如果一個坐標位置周圍一圈沒有雷,那么將其展開,再看它周圍一圈坐標周圍的坐標有沒有雷,沒有,繼續展開,直到碰到周圍有雷,標記數字。

?可以想到用遞歸來實現,但是注意一點,1點判斷完判斷2點時,要排除已經判斷過的1點,否則就死遞歸了。

代碼說明:

1、排查的坐標(x,y)如果不是雷,,看他周圍8個坐標,如果沒有雷,將其標記為空格' ? ' 。

2、遍歷坐標周圍8個坐標,如果沒有被排查過,遞歸調用此函數,在最里層表示show數組的值,就能實現展開。

代碼如下:

void OpenShow(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int x,int y) {int count = count_round_mine(mine, x, y);if (count == 0){show[x][y] == ' ';int i, j;for (i = -1; i <= 1; i++){for (j = -1; j <= 1; j++){if (show[x + i][y + j] == '*'){OpenShow(mine, show, row, col, x + i, y + j);}}}}else{show[x][y] = '0' + count;} }

這樣就實現了展開棋盤。

后面就剩下組合代碼了。

總結

以上是生活随笔為你收集整理的扫雷游戏(进阶版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。