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