1. 程式人生 > 其它 >C語言實現推箱子游戲完整程式碼

C語言實現推箱子游戲完整程式碼

技術標籤:遊戲c語言遊戲

C語言實現推箱子游戲完整程式碼

前言

自己做的,可能有些程式碼不夠工整,或者有些小問題,但遊戲的基本操作是可以實現的

程式碼效果

在這裡插入圖片描述

程式碼一共分為8個部分,4個控制上下左右移動,2個判斷輸贏,1個統計歸為的個數,一個作圖。

手動設定地圖

用’0’表示空格,“1”表示牆,“2”表示箱子,“3”表示人,“4”表示終點

這樣可以提高程式碼的移植性

如需改為手動輸入地圖可以直接定義一個二維陣列,在給他賦值就可以了

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表示列

計算地圖中終點的個數

這一步主要是為了後面判斷遊戲輸贏的

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++;
			}
		}
}//遍歷整個二維陣列 return k; }//計算地圖中有多少個終點

列印地圖函式

通過switch函式對二維陣列中的值進行視覺化,也就是畫出地圖

注意:這裡還定義出了6和7,是通過重疊的關係來算的,就是箱子在終點上,這個位置又有箱子又有終點2個標識,所以讓兩個的數值加起來,方便理解,也方便後面的計算

void print(){
	int i,j;
	printf("請用wsad代表上下左右來進行遊戲\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("○");//終點 break; case 6: printf("★"); break;//箱子和終點 case 7://人和終點顯示人 printf("♀"); break; } } printf("\n"); } }

判斷遊戲輸贏

這裡我寫了2個函式,一個判斷贏,一個判斷輸,並返回值,然後在主函式的最後面通過判斷返回值來確定遊戲的輸贏

判斷贏

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++;
			}
		}
	}//遍歷整個二維陣列,計算箱子在終點上的個數
	if(k==cum()){
	t=1;
	}//如果個數等於前面計算出的終點個數,則說明所有終點都放了箱子,說明遊戲勝利
	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++;
				}
			}
		}
		}/*這裡也是遍歷了整個陣列,判斷所有的箱子四個方向的情況,
		如果有三個方向被堵住了說明箱子無法移動了,也表明這個箱子失效了,
		用k來記錄失效的個數,當全部失效時遊戲失敗
		(這是遊戲的玩法,其實有一個被堵住就已經不可能勝利了)*/
	}
	if(k==cum()){
		k=1;
	}
	return k;//返回1說明遊戲失敗
}

接下來是最重要的四個控制函式

向上移動

通過數字的變化來控制二維陣列的變化,進而控制地圖的更新

這裡非常重要的就是要理解:加1,加2,加3減3都是什麼意思

加1:箱子的值是2,人的值是3,所以箱子的位置變成人需要加1來實現

加2:空地的值是0,箱子的值是2,箱子和終點在一起的值是6,所以在推箱子的時候,前方的空格或者終點放上箱子後數值會加2

加3減3:人的值是3,人要動的話,它原先在的格子就會因為人走了導致數值減3,走到的那個格子就會因為站了人而加3

如果這個理解的話,程式碼就非常簡單了

void movew(){
	if(x>0){
		if(screen[x-1][y]==1){
			return ;/*如果箱子的上面是牆,則地圖不會發生變化,因為
			推不動嘛*/
		}else if(screen[x-1][y]==0){
			screen[x-1][y]+=3;
			screen[x][y]-=3;
			x--;/*如果前面是空地,則需要向前移動一格,也就是原先人的位置
			變成空地,前方的空地變成人,空地(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;/*如果前面是空地,則需要向前移動
					一格,也就是原先是箱子的格子變成人,人的位置變成空
					地,原先的空地變成箱子,箱子(2)變成人(3)需要減
					3,空地變成人*/
					x--;
				}else if(screen[x-2][y]==1){
					return ;
				}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--;
				}//這個情況別漏了
			}
	}
}

其他三個方向的程式碼思路和這個是一樣的

向下移動

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

向左移動

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

向右移動

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

主函式

這個主函式寫的有點亂,直接看註釋吧


int main(){
	int n,t;
	int j,k;
	int b=1;
	here:
		system("cls");//
	printf("開始遊戲請按1\n退出遊戲請按2\n"); 
	scanf("%d",&j);
	if(j==1){
	printf("請用wsad代表上下左右來進行遊戲\n");//這個就引導進入遊戲
	while(1){
		system("cls");/*在每一次移動過後都清除上一個地圖,不然就會每走
		一步生成一個圖*/
		print();//先列印地圖
		scanf("%c",&n);//讀入使用者的操作
		switch(n){
			case 'w':
				movew();
				break;
			case 's':
				moves();
				break;
			case 'a':
				movea();
				break;
			case 'd':
				moved();
				break;
		} //控制人移動
		t=win(); 
		if(t==1){
		goto there;
	}//每次操作完先判斷遊戲是否勝利,如果勝利了直接跳到函式最後
	if(b == lose()){
		system("cls");
		print();
		printf("遊戲失敗");
		return 0;
	} //遊戲失敗提示
}
}else {
	system("cls");
	printf("您確認要退出遊戲嗎\n確認退出按1\t返回上一層按2\n"); 
	scanf("%d",&k);
		if(k==1){
			printf("你已退出遊戲,期待你的再次到來,謝謝"); 
			return 0;
		}else {
			goto here;
		}
}//這一塊是最前面使用者進入遊戲那裡的,如果使用者選擇退出遊戲執行的操作
	there:
		printf("恭喜你通過了遊戲!");
	return 0;
}//主函式 

所有的程式碼就到這裡了,如果需要完整程式碼可以留言喔.