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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

扫雷游戏(进阶版)

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

目錄

掃雷(簡(jiǎn)易版)

掃雷(進(jìn)階版)【加料】


掃雷(簡(jiǎn)易版)

掃雷游戲都玩過(guò)吧,童年回憶了屬于是,今天我們就用代碼來(lái)實(shí)現(xiàn)一下。

首先創(chuàng)建3個(gè)文件,分別用來(lái)存放 游戲測(cè)試(test.c),游戲的頭(game.h) ,游戲具體內(nèi)容實(shí)現(xiàn)(game.c)。

游戲測(cè)試(test.c)

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

代碼實(shí)現(xiàn):

#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("請(qǐng)選擇\n");scanf("%d", &input);switch (input){case 1:printf("進(jìn)入游戲\n");game();break;case 0:printf("退出游戲\n");break;default:printf("輸入有誤,請(qǐng)重試\n");break;}} while (input);return 0; }

游戲入口設(shè)立好了,接下來(lái)就是實(shí)現(xiàn)掃雷游戲的函數(shù)。

界面分析:

先來(lái)看看掃雷游戲的界面:

?這是一個(gè)9*9的棋盤,上面布置了10個(gè)雷。我們?cè)O(shè)置有雷處為'1',無(wú)雷處為'0',(注意是字符1和0),布置完雷后我們需要排查,排查一個(gè)坐標(biāo)如果是雷就炸死了,不是雷會(huì)標(biāo)出周圍8個(gè)坐標(biāo)雷的個(gè)數(shù)。

?這里實(shí)現(xiàn)時(shí)有個(gè)問(wèn)題,標(biāo)出周圍雷的數(shù)字時(shí),如果是1的話,就和前面"是不是雷" 產(chǎn)生沖突了,所以我們?cè)賱?chuàng)建一個(gè)棋盤,專門用來(lái)排查雷。

?還有個(gè)問(wèn)題,像圖一這種排查沒(méi)什么問(wèn)題,但是圖二這樣排查,就超出范圍越界了,所以我們創(chuàng)建數(shù)組時(shí),多給兩行兩列,創(chuàng)建成11*11的。展現(xiàn)時(shí)給出9*9的就行了。

下面來(lái)看代碼實(shí)現(xiàn):

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

這里的ROWS代表11*11數(shù)組的行,COLS代表列

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

不寫死,方便后期修改。

#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;}} }

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

打印棋盤:

接下來(lái)打印我們的棋盤來(lái)看一下:

寫一個(gè)Display函數(shù),為了好看,加上“掃雷游戲”的邊框,以及坐標(biāo)軸

?代碼實(shí)現(xiàn):

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"); }

布置雷:

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

寫一個(gè)SetMine函數(shù),用srand函數(shù)放進(jìn)隨機(jī)值。

代碼實(shí)現(xià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--;}} }

Count_mine在頭文件中定義了

?注意調(diào)用rand時(shí),在test.c中包含srand函數(shù):

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

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

?確實(shí)是隨機(jī)布置了10個(gè)雷。

排查雷:

布置完雷接下來(lái)就是排查雷了。

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

接著就是利用循環(huán)進(jìn)行排查了,如果碰到雷,那就被炸死。不是雷,就標(biāo)上周圍雷的個(gè)數(shù)。

那么這里需要計(jì)數(shù),可以用循環(huán)計(jì)算,也可以將周圍8個(gè)坐標(biāo)相加-'0'*8,就是雷的個(gè)數(shù)。

代碼實(shí)現(xiàn):

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; //法二:循環(huán)/*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("坐標(biāo)已被占用,請(qǐng)重新輸入\n");}elseprintf("輸入無(wú)效坐標(biāo),請(qǐng)重試\n");} }

但是這樣有個(gè)問(wèn)題,我們無(wú)法結(jié)束游戲,所以需要判斷游戲結(jié)束的條件。

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

代碼實(shí)現(xià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;} 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("坐標(biāo)已被占用,請(qǐng)重新輸入\n");}elseprintf("輸入無(wú)效坐標(biāo),請(qǐng)重試\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("請(qǐng)選擇\n");scanf("%d", &input);switch (input){case 1:printf("進(jìn)入游戲\n");game();break;case 0:printf("退出游戲\n");break;default:printf("輸入有誤,請(qǐng)重試\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("坐標(biāo)已被占用,請(qǐng)重新輸入\n");}elseprintf("輸入無(wú)效坐標(biāo),請(qǐng)重試\n");}if (win == 0){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);} }

掃雷(進(jìn)階版)【加料】

?我們可以觀察到網(wǎng)頁(yè)版的掃雷較之我們上面寫的簡(jiǎn)易版有兩個(gè)特點(diǎn):

1、有標(biāo)記功能,可以自行記錄埋藏雷的位置

2、有展開一片功能,如果點(diǎn)開位置附近一片都沒(méi)有雷,會(huì)自行展開。

下面進(jìn)階版主要實(shí)現(xiàn)這兩個(gè)功能。

1、標(biāo)記功能:

我們定義標(biāo)記符號(hào)為‘#’。

在排查雷函數(shù)中寫一個(gè)標(biāo)記雷函數(shù)SignMine,注意一定是在FindMine函數(shù)中寫。

SignMine代碼實(shí)現(xiàn)如下:

void SignMine(char show[ROWS][COLS], int row, int col) {int a = 0;printf("請(qǐng)輸入需要標(biāo)記的次數(shù)\n");scanf("%d", &a);while (a){printf("請(qǐng)輸入需要標(biāo)記的坐標(biāo)\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("該坐標(biāo)已被占用,請(qǐng)重新輸入\n");}elseprintf("無(wú)效標(biāo)記,請(qǐng)重試\n");} }

我們要標(biāo)記幾次,就輸入幾個(gè)標(biāo)記的坐標(biāo)。

2、展開一片功能:

分析:如果一個(gè)坐標(biāo)位置周圍一圈沒(méi)有雷,那么將其展開,再看它周圍一圈坐標(biāo)周圍的坐標(biāo)有沒(méi)有雷,沒(méi)有,繼續(xù)展開,直到碰到周圍有雷,標(biāo)記數(shù)字。

?可以想到用遞歸來(lái)實(shí)現(xiàn),但是注意一點(diǎn),1點(diǎn)判斷完判斷2點(diǎn)時(shí),要排除已經(jīng)判斷過(guò)的1點(diǎn),否則就死遞歸了。

代碼說(shuō)明:

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

2、遍歷坐標(biāo)周圍8個(gè)坐標(biāo),如果沒(méi)有被排查過(guò),遞歸調(diào)用此函數(shù),在最里層表示show數(shù)組的值,就能實(shí)現(xiàn)展開。

代碼如下:

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;} }

這樣就實(shí)現(xiàn)了展開棋盤。

后面就剩下組合代碼了。

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。