C语言实现推箱子游戏完整代码

举报
阿童木 发表于 2021/08/29 23:37:24 2021/08/29
【摘要】 C语言实现推箱子游戏完整代码前言自己做的,可能有些代码不够工整,或者有些小问题,但游戏的基本操作是可以实现的 代码效果代码一共分为8个部分,4个控制上下左右移动,2个判断输赢,1个统计归为的个数,一个作图。手动设置地图用’0’表示空格,“1”表示墙,“2”表示箱子,“3”表示人,“4”表示终点这样可以提高代码的移植性如需改为手动输入地图可以直接定义一个二维数组,在给他赋值就可以了int s...

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;
}//主函数 

所有的代码就到这里了,如果需要完整代码可以留言

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。