C语言实现推箱子游戏

推箱子游戏

前言

Hello,编程小白的我又回来了,继上次的C语言迷宫文章,我沉寂了两天,这次带来的是用C语言实现小时候的推箱子游戏,中间挺难的,条件写了删,删了写,没头绪的时候都想放弃了,但我坚信写的出迷宫的我也能写出这个推箱子,哈哈,终于功夫不负有心人,在又一个早上后,终于搞定了!
下面我们来聊聊这个玩法简单的推箱子。


一、前期问题

  1. 推箱子地图的打印
  2. 箱子,人,终点的坐标显示
  3. 使箱子和人一起移动
  4. 当箱子到达终点的时候终止循环

二、程序代码

1.地图打印

我们用#代表墙,@代表人,O代表箱子

地图代码如下:

char a[8][11]={
				"   ###    ", 
				"   # #    ",
				"   # #### ",
				" ###O O # ",
				" #  O@### ",
				" ####O#   ",
				"    # #   ",
				"    ###   "};

2.控制移动

先实现一个方向的移动,,以向上移动为例,这里我们就要知道,一共有三种情况
第一种情况:人上方有空

# #
# #
#@#

针对第一种情况我们可以知道此时按’w’人应该往上移一位,这里有一个if条件

if (a[x-1][y]==' ')
		{
			a[x][y]=' ';
			a[x-1][y]='@';
		}

第二种情况:人上方为箱子

# #
#O#
#@#

针对第二种情况我们可以知道此时按’w’箱子和人应该一起往上移动一位,这里有一个if条件

if(a[x-1][y]=='O'&&a[x-2][y]!='#')
   	{
   		a[x][y]=' ';
   		a[x-2][y]='O';
   		a[x-1][y]='@';
   		m1--;
   	}

应当注意的是箱子往上移动一位后,箱子的纵坐标应该减一

第三种情况:人上方为箱子,箱子上方为墙


###
#O#
#@#

针对第三种情况我们可以知道此时按’w’人和箱子都不会移动了,就要有一个if条件,遇到这种情况直接逃过

if(a[x-1][y]=='O'&&a[x-2][y]=='#')
		{
			continue;
		}

在一次往上移动后,人的纵坐标一定会减一(当然是不碰墙的情况下)
接下来,将这一次往上移动的代码组合起来
完整代码如下:

if (c=='w')
{
	if (a[x-1][y]!='#')	
	{
		if(a[x-1][y]=='O'&&a[x-2][y]=='#')
		{
			continue;
		}
		else if(a[x-1][y]=='O'&&a[x-2][y]!='#')
		{
			a[x][y]=' ';
			a[x-2][y]='O';
			a[x-1][y]='@';
			m1--;
		}
		else if (a[x-1][y]==' ')
		{
			a[x][y]=' ';
			a[x-1][y]='@';
		}
		x--;
	}
}

好了,一次往上移动的代码已经被我们写出来了,其他三种方向的移动也一样,只需要注意坐标表示,这里就不列出了

3.终止循环

当箱子归位后,总不能让人物一直在里面上下左右移动吧,就要有一个终止循环条件,这里我们用while循环,以便于我们阅读
这里有个点需要注意,不能用’&&’,应该用’||’,因为是上下左右移动,每次只有一个坐标移动,另一个坐标不动

代码如下:

while (箱子坐标不等于终点坐标)
{
}

例本题中的终止条件:m1!=1||n1!=4||m2!=3||n2!=7||m3!=4||n3!=2||m4!=6||n4!=5

4.末尾

其他的和上一文迷宫的一样,每次移动需要清屏再打印,最终获胜需要清屏打印"You win."

三、完整程序

组合嵌套,得到最终的完整的程序
最终代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main ()
{
	char a[8][11]={											//定义地图 
					"   ###    ", 
					"   # #    ",
					"   # #### ",
					" ###O O # ",
					" #  O@### ",
					" ####O#   ",
					"    # #   ",
					"    ###   "};								
	int m1=3,m2=3,m3=4,m4=5,								//定义箱子的坐标
	    n1=4,n2=6,n3=4,n4=5;						
	int x=4,y=5,i;											//定义人的坐标 
	char c;													//定义字符,存储从键盘获取的字符 
															
	for (i=0;i<=7;i++)										//打印初步地图 
	{
		system("color f4");
		puts(a[i]);
	}
	
	while (m1!=1||n1!=4||m2!=3||n2!=7||m3!=4||n3!=2||m4!=6||n4!=5)
															//循环终止条件 
	{
		c=getch();											//从键盘获取字符
		
		if (c=='w')											//当按下'w'时 
		{
			if (a[x-1][y]!='#')								//如果坐标a[x-1][y]不为墙 
			{
				if(a[x-1][y]=='O'&&a[x-2][y]=='#')			//如果已经推到终点, 
				{											//执行continue语句 , 
					continue;								//即不对这种情况操作  
				} 
				else if(a[x-1][y]=='O'&&a[x-2][y]!='#')		//如果箱子可以推动
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x-2][y]='O';							//使坐标a[x-2][y]为箱子 
					a[x-1][y]='@';							//使坐标a[x-1][y]为人 
					m1--;									//使箱子的纵坐标减一 
				}
				else if (a[x-1][y]==' ')					//如果坐标a[x-1][y]为' '
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x-1][y]='@';							//使坐标a[x-1][y]为人 
				}
				x--;										//使人的纵坐标减一 
			}
		}
		if (c=='s')											//当按下's'时 
		{
			if (a[x+1][y]!='#')								//如果坐标a[x+1][y]不为墙 
			{
				if (a[x+1][y]=='O'&&a[x+2][y]=='#')			//如果已经推到终点, 
				{											//执行continue语句, 
					continue;								//即不对这种情况操作  
				}
				else if (a[x+1][y]=='O'&&a[x+2][y]!='#')	//如果箱子可以推动
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x+2][y]='O';							//使坐标a[x+2][y]为箱子 
					a[x+1][y]='@';							//使坐标a[x+1][y]为人 
					m4++;									//使箱子的纵坐标加一 
				}
				else if(a[x+1][y]==' ')						//如果坐标a[x+1][y]为' '
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x+1][y]='@';							//使坐标a[x+1][y]为人 
				}
				x++;										//使人的纵坐标加一 
			}
		}
		if (c=='a')											//当按下'a'时 
		{
			if (a[x][y-1]!='#')								//如果坐标a[x][y-1]不为墙 
			{
				if (a[x][y-1]=='O'&&a[x][y-2]=='#')			//如果已经推到终点,
				{											//执行continue语句, 
					continue;								//即不对这种情况操作  
				}
				else if (a[x][y-1]=='O'&&a[x][y-2]!='#')	//如果箱子可以推动
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x][y-2]='O';							//使坐标a[x][y-2]为箱子 
					a[x][y-1]='@';							//使坐标a[x][y-1]为人 
					n3--;									//使箱子的横坐标减一 
				}
				else if(a[x][y-1]==' ')						//如果坐标a[x][y-1]为' '
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x][y-1]='@';							//使坐标a[x][y-1]为人 
				}
				y--;										//使人的横坐标减一 
			}
		}
		if (c=='d')											//当按下'd'时 
		{
			if (a[x][y+1]!='#')								//如果坐标a[x][y+1]不为墙 
			{
				if (a[x][y+1]=='O'&&a[x][y+2]=='#')			//如果已经推到终点,
				{											//执行continue语句, 
					continue;								//即不对这种情况操作  
				}
				else if (a[x][y+1]=='O'&&a[x][y+2]!='#')	//如果箱子可以推动
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x][y+2]='O';							//使坐标a[x][y+2]为箱子 
					a[x][y+1]='@';							//使坐标a[x][y+1]为人 
					n2++;									//使箱子的横坐标加一 
				}
				else if(a[x][y+1]==' ')						//如果坐标a[x][y+1]为' '
				{
					a[x][y]=' ';							//使坐标a[x][y]为' ' 
					a[x][y+1]='@';							//使坐标a[x][y+1]为人 
				}
				y++;										//使人的横坐标加一 
			}
		}
		
		system("cls");										//清屏 
		for (i=0;i<=7;i++)									//再打印移动后的地图 
		{
			system("color f4");
			puts(a[i]);
		}
	}														//以下为修饰部分 
	system("cls");											//清屏 
	Sleep(0.5*1000);
	printf ("\nYou win.\n\n");						//打印结果 
	Sleep(3*1000);
	system("pause");
	return 0;
}

四、疑惑

  1. 如何用结构体表示坐标
  2. 如何在主函数外将移动代码写成一个函数,在需要时再调用它
  3. 如何解决移动后打印时的屏闪问题(也许不能解决)

五、总结

以上便是今天分享的推箱子小游戏代码,也是本人第一个百行代码,(假装不知道括号可以写到上一行,嘿嘿)
写这个程序的两天又是成长的两天,哈哈,身体有点累,但内心无比开心
最后,在这里提前助各位看官新年快乐,新的一年身体健康,万事如意(吧啦吧啦)

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值