C語(yǔ)言實(shí)現(xiàn)推箱子游戲完整代碼
C語(yǔ)言實(shí)現(xiàn)推箱子游戲完整代碼,供大家參考,具體內(nèi)容如下
前言
自己做的,可能有些代碼不夠工整,或者有些小問(wèn)題,但游戲的基本操作是可以實(shí)現(xiàn)的
代碼效果

代碼一共分為8個(gè)部分,4個(gè)控制上下左右移動(dòng),2個(gè)判斷輸贏,1個(gè)統(tǒng)計(jì)歸為的個(gè)數(shù),一個(gè)作圖。
手動(dòng)設(shè)置地圖
用'0'表示空格,“1”表示墻,“2”表示箱子,“3”表示人,“4”表示終點(diǎn)
這樣可以提高代碼的移植性
如需改為手動(dòng)輸入地圖可以直接定義一個(gè)二維數(shù)組,在給他賦值就可以了
int screen[9][11]={
{0,1,1,1,1,1,1,1,1,0,0},
{0,1,0,0,0,1,0,0,0,1,0},
{0,1,0,2,2,2,2,2,0,1,0},
{0,1,0,2,0,2,0,2,0,1,1},
{0,1,0,0,0,3,0,0,2,0,1},
{1,1,0,1,1,1,1,0,2,0,1},
{1,0,4,4,4,4,4,1,0,0,1},
{1,0,4,4,4,4,4,0,0,1,1},
{1,1,1,1,1,1,1,1,1,1,0}
};//定義為全局變量 (地圖) i表示行,j表示列
計(jì)算地圖中終點(diǎn)的個(gè)數(shù)
這一步主要是為了后面判斷游戲輸贏的
int cum(){
int i,j,k=0;
for(i=0;i<9;i++){
for(j=0;j<11;j++){
if(screen[i][j]==2){
k++;
}
}
}//遍歷整個(gè)二維數(shù)組
return k;
}//計(jì)算地圖中有多少個(gè)終點(diǎn)
打印地圖函數(shù)
通過(guò)switch函數(shù)對(duì)二維數(shù)組中的值進(jìn)行可視化,也就是畫(huà)出地圖
注意:這里還定義出了6和7,是通過(guò)重疊的關(guān)系來(lái)算的,就是箱子在終點(diǎn)上,這個(gè)位置又有箱子又有終點(diǎn)2個(gè)標(biāo)識(shí),所以讓兩個(gè)的數(shù)值加起來(lái),方便理解,也方便后面的計(jì)算
void print(){
int i,j;
printf("請(qǐng)用wsad代表上下左右來(lái)進(jìn)行游戲\n");
for(i=0;i<9;i++){
for(j=0;j<11;j++){
switch(screen[i][j]){
case 0:
printf(" ");//空
break;
case 1:
printf("■");//墻
break;
case 2:
printf("★");//箱子
break;
case 3:
printf("♀");//人
break;
case 4:
printf("○");//終點(diǎn)
break;
case 6:
printf("★");
break;//箱子和終點(diǎn)
case 7://人和終點(diǎn)顯示人
printf("♀");
break;
}
}
printf("\n");
}
}
判斷游戲輸贏
這里我寫(xiě)了2個(gè)函數(shù),一個(gè)判斷贏,一個(gè)判斷輸,并返回值,然后在主函數(shù)的最后面通過(guò)判斷返回值來(lái)確定游戲的輸贏
判斷贏
int win(){
int i,j,k=0;
int t=0;
for(i=0;i<9;i++){
for(j=0;j<11;j++){
if(screen[i][j]==6){
k++;
}
}
}//遍歷整個(gè)二維數(shù)組,計(jì)算箱子在終點(diǎn)上的個(gè)數(shù)
if(k==cum()){
t=1;
}//如果個(gè)數(shù)等于前面計(jì)算出的終點(diǎn)個(gè)數(shù),則說(shuō)明所有終點(diǎn)都放了箱子,說(shuō)明游戲勝利
return t;
} //判斷贏
判斷輸
int lose(){
int i,j;
int k=0;
for(i=0;i<9;i++){
for(j=0;j<11;j++){
if(i>0 && j>0 ){
if(screen[i][j] == 2 || screen[i][j] == 6){
if(((screen[i-1][j] == 1 || screen[i-1][j] == 2 || screen[i-1][j] == 6) && (screen[i][j-1] == 1 || screen[i][j-1] == 2 || screen[i][j-1] == 6))
|| ((screen[i][j-1] == 1 || screen[i][j-1] == 2 || screen[i][j-1] == 6) && (screen[i+1][j] == 1 || screen[i+1][j] == 2 || screen[i+1][j] == 6))
|| ((screen[i+1][j] == 1 || screen[i+1][j] == 2 || screen[i+1][j] == 6) && (screen[i][j+1] == 1 || screen[i][j+1] == 2 || screen[i][j+1] == 6))
|| ((screen[i][j+1] == 1 || screen[i][j+1] == 2 || screen[i][j+1] == 6) && (screen[i-1][j] == 1 || screen[i-1][j] == 2 || screen[i-1][j] == 6))){
k++;
}
}
}
}/*這里也是遍歷了整個(gè)數(shù)組,判斷所有的箱子四個(gè)方向的情況,
如果有三個(gè)方向被堵住了說(shuō)明箱子無(wú)法移動(dòng)了,也表明這個(gè)箱子失效了,
用k來(lái)記錄失效的個(gè)數(shù),當(dāng)全部失效時(shí)游戲失敗
(這是游戲的玩法,其實(shí)有一個(gè)被堵住就已經(jīng)不可能勝利了)*/
}
if(k==cum()){
k=1;
}
return k;//返回1說(shuō)明游戲失敗
}
接下來(lái)是最重要的四個(gè)控制函數(shù)
向上移動(dòng)
通過(guò)數(shù)字的變化來(lái)控制二維數(shù)組的變化,進(jìn)而控制地圖的更新
這里非常重要的就是要理解:加1,加2,加3減3都是什么意思
加1:箱子的值是2,人的值是3,所以箱子的位置變成人需要加1來(lái)實(shí)現(xiàn)
加2:空地的值是0,箱子的值是2,箱子和終點(diǎn)在一起的值是6,所以在推箱子的時(shí)候,前方的空格或者終點(diǎn)放上箱子后數(shù)值會(huì)加2
加3減3:人的值是3,人要?jiǎng)拥脑?,它原先在的格子就?huì)因?yàn)槿俗吡藢?dǎo)致數(shù)值減3,走到的那個(gè)格子就會(huì)因?yàn)檎玖巳硕?
如果這個(gè)理解的話,代碼就非常簡(jiǎn)單了
void movew(){
if(x>0){
if(screen[x-1][y]==1){
return ;/*如果箱子的上面是墻,則地圖不會(huì)發(fā)生變化,因?yàn)?
推不動(dòng)嘛*/
}else if(screen[x-1][y]==0){
screen[x-1][y]+=3;
screen[x][y]-=3;
x--;/*如果前面是空地,則需要向前移動(dòng)一格,也就是原先人的位置
變成空地,前方的空地變成人,空地(0)變成人(3)需要加3,
人變成空地需要減3*/
}else if(screen[x-1][y]==4){
screen[x-1][y]+=3;
screen[x][y]-=3;
x--;
}//一樣的
else if(screen[x-1][y]==2||screen[x-1][y]==6){
if(screen[x-2][y]==0){
screen[x-2][y]+=2;//箱子前面的格變成箱子(2)
screen[x-1][y]+=1;//箱子的位置變成人(3)
screen[x][y]-=3;/*如果前面是空地,則需要向前移動(dòng)
一格,也就是原先是箱子的格子變成人,人的位置變成空
地,原先的空地變成箱子,箱子(2)變成人(3)需要減
3,空地變成人*/
x--;
}else if(screen[x-2][y]==1){
return ;
}else if(screen[x-2][y]==2){
return;//如果箱子的前面是墻或者其他的箱子,則箱子推不動(dòng)
}else if(screen[x-2][y]==4){
screen[x-2][y]+=2;
screen[x-1][y]+=1;
screen[x][y]-=3;
x--;
}//這個(gè)情況別漏了
}
}
}
其他三個(gè)方向的代碼思路和這個(gè)是一樣的
向下移動(dòng)
void moves(){
if(x<9){
if(screen[x+1][y]==1){
return ;
}else if(screen[x+1][y]==0){
screen[x+1][y]+=3;
screen[x][y]-=3;
x++;
}else if(screen[x+1][y]==4){
screen [x+1][y]+=3;
screen[x][y]-=3;
x++;
}
else if(screen[x+1][y]==2||screen[x+1][y]==6){
if(screen[x+2][y]==1){
return;
}else if(screen[x+2][y]==0){
screen[x+2][y]+=2;
screen[x+1][y]+=1;
screen[x][y]-=3;
x++;
}else if(screen[x+2][y]==2){
return ;
}else if(screen[x+2][y]==4){
screen[x+2][y]+=2;
screen[x+1][y]+=1;
screen[x][y]-=3;
x++;
}
}
}
}
向左移動(dòng)
void movea(){
if(y>0){
if(screen[x][y-1]==1){
return;
}else if(screen[x][y-1]==4){
screen[x][y-1]+=3;
screen[x][y]-=3;
y--;
}
else if(screen[x][y-1]==0){
screen[x][y-1]+=3;
screen[x][y]-=3;
y--;
}else if(screen[x][y-1]==2||screen[x][y-1]==6){
if(screen[x][y-2]==0){
screen[x][y-2]+=2;
screen[x][y-1]+=1;
screen[x][y]-=3;
y--;
}else if(screen[x][y-2]==1){
return;
}else if(screen[x][y-2]==2){
return;
}else if(screen[x][y-2]=4){
screen[x][y-2]+=2;
screen[x][y-1]+=1;
screen[x][y]-=3;
y--;
}
}
}
}
向右移動(dòng)
void moved(){
if(y<9){
if(screen[x][y+1]==1){
return;
}else if(screen[x][y+1]==4){
screen[x][y+1]+=3;
screen[x][y]-=3;
y++;
}
else if(screen[x][y+1]==0){
screen[x][y+1]+=3;
screen[x][y]-=3;
y++;
}else
if(screen[x][y+1]==2||screen[x][y+1]==6){
if(screen[x][y+2]==0){
screen[x][y+2]+=2;
screen[x][y+1]+=1;
screen[x][y]-=3;
y++;
}else if(screen[x][y+2]==4){
screen[x][y+2]+=2;
screen[x][y+1]+=1;
screen[x][y]-=3;
y++;
}else if(screen[x][y+2]==2){
return;
}else if(screen[x][y+2]==1){
return;
}
}
}
}
主函數(shù)
這個(gè)主函數(shù)寫(xiě)的有點(diǎn)亂,直接看注釋吧
int main(){
int n,t;
int j,k;
int b=1;
here:
system("cls");//
printf("開(kāi)始游戲請(qǐng)按1\n退出游戲請(qǐng)按2\n");
scanf("%d",&j);
if(j==1){
printf("請(qǐng)用wsad代表上下左右來(lái)進(jìn)行游戲\n");//這個(gè)就引導(dǎo)進(jìn)入游戲
while(1){
system("cls");/*在每一次移動(dòng)過(guò)后都清除上一個(gè)地圖,不然就會(huì)每走
一步生成一個(gè)圖*/
print();//先打印地圖
scanf("%c",&n);//讀入用戶的操作
switch(n){
case 'w':
movew();
break;
case 's':
moves();
break;
case 'a':
movea();
break;
case 'd':
moved();
break;
} //控制人移動(dòng)
t=win();
if(t==1){
goto there;
}//每次操作完先判斷游戲是否勝利,如果勝利了直接跳到函數(shù)最后
if(b == lose()){
system("cls");
print();
printf("游戲失敗");
return 0;
} //游戲失敗提示
}
}else {
system("cls");
printf("您確認(rèn)要退出游戲嗎\n確認(rèn)退出按1\t返回上一層按2\n");
scanf("%d",&k);
if(k==1){
printf("你已退出游戲,期待你的再次到來(lái),謝謝");
return 0;
}else {
goto here;
}
}//這一塊是最前面用戶進(jìn)入游戲那里的,如果用戶選擇退出游戲執(zhí)行的操作
there:
printf("恭喜你通過(guò)了游戲!");
return 0;
}//主函數(shù)
所有的代碼就到這里了,如果需要完整代碼可以留言
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++中高性能內(nèi)存池的實(shí)現(xiàn)詳解
在 C/C++ 中,內(nèi)存管理是一個(gè)非常棘手的問(wèn)題,我們?cè)诰帉?xiě)一個(gè)程序的時(shí)候幾乎不可避免的要遇到內(nèi)存的分配邏輯。本文將通過(guò)C++實(shí)現(xiàn)高性能內(nèi)存池,感興趣的可以了解一下2022-10-10
C語(yǔ)言實(shí)現(xiàn)的統(tǒng)計(jì)php代碼行數(shù)功能源碼(支持文件夾、多目錄)
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)的統(tǒng)計(jì)php代碼行數(shù)功能源碼,支持文件夾、多級(jí)目錄的統(tǒng)計(jì),在一些環(huán)境中會(huì)用到這個(gè)功能,需要的朋友可以參考下2014-08-08
C++實(shí)現(xiàn)對(duì)回收站里的文件進(jìn)行操作的示例代碼
這篇文章主要為大家詳細(xì)介紹了C++如何使用代碼對(duì)回收站里的文件進(jìn)行操作,譬如文件的刪除與恢復(fù)等,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
C++ 將一個(gè)文件讀入數(shù)組再讀出數(shù)組的方法
今天小編就為大家分享一篇C++ 將一個(gè)文件讀入數(shù)組再讀出數(shù)組的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
OpenCV實(shí)現(xiàn)簡(jiǎn)單攝像頭視頻監(jiān)控程序
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)簡(jiǎn)單攝像頭視頻監(jiān)控程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
C/C++經(jīng)典實(shí)例之模擬計(jì)算器示例代碼
最近在看到的一個(gè)需求,本以為比較簡(jiǎn)單,但花了不少時(shí)間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實(shí)例之模擬計(jì)算器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-10-10

