長(zhǎng)沙外貿(mào)建站vue seo 優(yōu)化方案
目錄
前言
?制作菜單
構(gòu)建游戲選擇框架
實(shí)現(xiàn)游戲功能
模塊化編程:查看前節(jié)三子棋的內(nèi)容
初始化雷區(qū)
?編輯
優(yōu)化棋盤
隨機(jī)埋入地雷
點(diǎn)擊后的決策
?實(shí)現(xiàn)此功能代碼
game();的安排
?
前言
《掃雷》是一款大眾類的益智小游戲,于1992年發(fā)行。游戲目標(biāo)是在最短的時(shí)間內(nèi)根據(jù)點(diǎn)擊格子出現(xiàn)的數(shù)字找出所有非地雷的格子,同時(shí)避免踩到地雷,踩到一個(gè)地雷全盤皆輸。
玩家需要在雷區(qū)中,將所有地雷一一排查出來:9x9規(guī)格
? ? ? test.c ?- - - - ?測(cè)試游戲的邏輯
? ? ? game.c ?- - - - ?游戲代碼的實(shí)現(xiàn)
? ? ? game.h ?- - - - ?游戲代碼的聲明 ( 函數(shù)聲明,符號(hào)定義 )
?制作菜單
? 在玩游戲時(shí),我們?cè)谶M(jìn)入游戲都會(huì)有菜單選項(xiàng),選擇開始游戲,推出游戲等這些指令,說到選擇,那么我們可以依據(jù)我們所學(xué)的循環(huán)和分支語(yǔ)句來先完成基本框架的設(shè)計(jì)。
首先我們進(jìn)入游戲都是先顯示選項(xiàng),做出選擇,并且在玩游戲時(shí)玩一局,還想玩怎么辦(想一想我們前邊的知識(shí)哪種結(jié)構(gòu)符合先進(jìn)入游戲出現(xiàn)菜單再循環(huán)這一需求)那肯定是do…while的循環(huán)結(jié)構(gòu)更符合,那么我們就先使用函數(shù)來打印輸出一個(gè)菜單選項(xiàng)
void menu()
{printf("*****************************\n");printf("*****************************\n");printf("**********1.play^************\n");printf("**********0.exit^************\n");//菜單printf("*****************************\n");printf("*****************************\n");
}int main()
{int a = 0;do{menu();printf("請(qǐng)選擇:");scanf("%d",&a);}while();
return 0;
}
構(gòu)建游戲選擇框架
游戲菜單已在屏幕上顯示完成,現(xiàn)在需要完成選擇,并且在玩游戲時(shí)玩一局,還想玩怎么辦。
這時(shí)候需要應(yīng)用博主之前闡述的switch語(yǔ)句來實(shí)現(xiàn):
int main()
{int input = 0;do{menu();printf("PLEASE SELECT:");scanf("%d", &input);switch(input){case 1:game(); //以上為界面的選擇break;case 0:printf("Exit\n");break;default:printf("ERRO,PLEASE CHOOSE AGAIN\n");break;}} while (input);//while循環(huán)可以利用0為假,其余為來實(shí)現(xiàn)用戶可反復(fù)選擇
//直到選到合適為止return 0;
}
實(shí)現(xiàn)游戲功能
模塊化編程:查看前節(jié)三子棋的內(nèi)容
?test.c:是用來實(shí)現(xiàn)游戲邏輯? ? game.c:用來實(shí)現(xiàn)游戲功能的函數(shù)? ?game.h:用來申明游戲功能函數(shù)(可引用)使用模塊化編程可極大的提高代碼的可閱讀性、可維護(hù)性、可移植性等!
此為game.h的文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS//使用scanf函數(shù)的報(bào)錯(cuò)處理方式
#include <stdio.h>//打印函數(shù)的使用工具箱
#include<Windows.h>//顏色函數(shù)和清屏指令的工具箱
#include<stdlib.h>//在使用rand的時(shí)候需要用到srand, srand((unsigned int)time(NULL))隨機(jī)函數(shù),調(diào)用一次就可以
#include<time.h>
#define row 9//常量
#define col 9
#define cols col+2//定義常量
#define rows row+2
void initboard(char board[rows][cols],int hang, int lie,char set);//形參數(shù)
void displayboard(char board[rows][cols], int hang, int lie);//只設(shè)置9*9格子
void setmine(char board[rows][cols], int hang, int lie);//埋入地雷
void panduan(char show[rows][cols], char mine[rows][cols],int hang, int lie);
后邊會(huì)逐個(gè)剖析 :
用來引用在test.c文件中
初始化雷區(qū)
首先映入眼簾的一定是 9×9 的雷區(qū),這 81 個(gè)被遮蓋的格子,
當(dāng)我們隨機(jī)的點(diǎn)擊其中的格子時(shí),會(huì)出現(xiàn)以下二種情況:
① 當(dāng)翻開的格子是地雷時(shí),玩家被炸“死”,游戲結(jié)束;
② 當(dāng)翻開的格子不是地雷時(shí),該格子會(huì)顯示周圍的 8 個(gè)格子存在的地雷的個(gè)數(shù);
由圖例可以得出結(jié)論,實(shí)現(xiàn) 9×9 的掃雷游戲,創(chuàng)建一個(gè) 9 行 9 列的二維數(shù)組并不合適。
既然對(duì) 9 行 9 列的二維數(shù)組的邊界元素進(jìn)行操作時(shí),會(huì)導(dǎo)致數(shù)組越界訪問,那我們干脆就直接將二維數(shù)組擴(kuò)大一圈,將那些會(huì)導(dǎo)致越界訪問的范圍包括在數(shù)組內(nèi),從源頭上解決問題,這是一個(gè)非常巧妙的辦法!
所以需要設(shè)置兩個(gè)數(shù)組(二維數(shù)組)
(1)一個(gè)為儲(chǔ)存埋雷數(shù)據(jù)的(用于判斷是否踩雷)
(2)一個(gè)為展示給玩家的棋盤(類似于上面的藍(lán)色未知方塊,點(diǎn)開后顯示周圍8格雷數(shù))
需要將兩個(gè)數(shù)組同時(shí)初始化initboard子函數(shù)
void initboard(char board[rows][cols], int hang, int lie,char set)
{int i = 0;int j = 0;for (i = 0; i < hang; i++){for (j = 0; j < lie; j++){board[i][j] = set;}}
}//initboard(mine, rows, cols, '0');//在test.c中引用的函數(shù)
//initboard(show, row, col, '*');
優(yōu)化棋盤
由于雷區(qū)行號(hào)較長(zhǎng),所以需要給每行列標(biāo)注序號(hào)displayboard子函數(shù)
void displayboard(char board[rows][cols], int hang, int lie)
{int i = 0;int j = 0; printf("---------------------------------------\n");for(j = 0; j <=lie; j++){printf("%d ",j);}printf("\n");for (i = 1; i <=hang; i++){printf("%d ", i);for (j = 1; j <=lie; j++){printf("%c ", board[i-1][j-1]);}printf("\n");}printf("---------------------------------------\n");
}
?效果圖
?
隨機(jī)埋入地雷
應(yīng)為此為9x9雷區(qū),故10個(gè)雷足夠。但怎么樣實(shí)現(xiàn)隨機(jī)在合適的區(qū)域內(nèi)埋雷呢
C語(yǔ)言生成隨機(jī)數(shù)的方法:
void setmine(char board[rows][cols], int hang, int lie)//隨機(jī)埋入地雷
{int count = 10;while (count){int x = rand() % hang ;int y = rand() % lie ;if (board[x][y] == '0'){board[x][y] = '1';}count--;}}//srand((unsigned int)time(NULL));//布置雷的隨機(jī)時(shí)間函數(shù),在test.c主函數(shù)
中引用一次就夠
點(diǎn)擊后的決策
展開后周圍多少雷?
在掃雷游戲中,當(dāng)我們點(diǎn)擊的方格不是地雷,且周圍一片區(qū)域都沒有地雷時(shí),會(huì)直接展開一片雷區(qū),具體效果如下圖
?
掃雷游戲中,當(dāng)玩家翻轉(zhuǎn)一個(gè)方格時(shí),若該方格不是地雷則會(huì)顯示該方格周圍 8 個(gè)方格存在的地雷個(gè)數(shù)。如果該方格周圍 8 個(gè)坐標(biāo)都不存在地雷時(shí)會(huì)將這 9 個(gè)方格都展開,以此類推直到遇到一個(gè)方格的周圍 8 個(gè)方格存在地雷時(shí)停止展開,兩種情況如下圖所
?為實(shí)現(xiàn)這一功能,則需要我們遍歷玩家輸入的坐標(biāo)的周圍 8 個(gè)坐標(biāo),統(tǒng)計(jì)該坐標(biāo)周圍所存在的地雷個(gè)數(shù)。
int get_mine(char board[rows][cols],int x, int y)
{return (board[x - 1][y - 1]+ board[x - 1][y]+ board[x - 1][y + 1]+ board[x][y + 1]+ board[x][y - 1]+ board[x + 1][y + 1]+ board[x + 1][y]+ board[x + 1][y - 1] - 8* '0');//周圍8個(gè)坐標(biāo)相加
}
?
?
?實(shí)現(xiàn)此功能代碼
void Mark(char board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;while (1){printf("\n請(qǐng)輸入要標(biāo)記的坐標(biāo)>>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) //判斷玩家輸入坐標(biāo)是否合法{if (board[x][y] == '!') //若坐標(biāo)元素為 '!' 則表示該坐標(biāo)已被標(biāo)記過{printf("\n<該坐標(biāo)已標(biāo)記,無需重復(fù)標(biāo)記,請(qǐng)重新輸入>\n");}else //該坐標(biāo)未被標(biāo)記{board[x][y] = '!'; //將 '!' 賦值給該坐標(biāo)元素DisplayBoard(board, row, col); //將標(biāo)記地雷后的雷區(qū)展示于玩家break;}}else{printf("\n<坐標(biāo)非法,請(qǐng)重新輸入>\n\n");}}
}
game();的安排
void game()
{char mine[rows][cols] = { 0 };//存放雷的信息char show[rows][cols] = { 0 };//顯示給玩家的游戲界面信息initboard(mine, rows, cols, '0');initboard(show, row, col, '*');//displayboard(mine, row, col);setmine(mine, row,col);displayboard(show, row, col);panduan(show,mine, row, col);
}
好了以上內(nèi)容到今天就結(jié)束了希望大家多多支持!
其中一些內(nèi)容借鑒了一些博主的,希望大家諒解。