推箱子游戏
前言
Hello,编程小白的我又回来了,继上次的C语言迷宫文章,我沉寂了两天,这次带来的是用C语言实现小时候的推箱子游戏,中间挺难的,条件写了删,删了写,没头绪的时候都想放弃了,但我坚信写的出迷宫的我也能写出这个推箱子,哈哈,终于功夫不负有心人,在又一个早上后,终于搞定了!
下面我们来聊聊这个玩法简单的推箱子。
一、前期问题
- 推箱子地图的打印
- 箱子,人,终点的坐标显示
- 使箱子和人一起移动
- 当箱子到达终点的时候终止循环
二、程序代码
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;
}
四、疑惑
- 如何用结构体表示坐标
- 如何在主函数外将移动代码写成一个函数,在需要时再调用它
- 如何解决移动后打印时的屏闪问题(也许不能解决)
五、总结
以上便是今天分享的推箱子小游戏代码,也是本人第一个百行代码,(假装不知道括号可以写到上一行,嘿嘿)
写这个程序的两天又是成长的两天,哈哈,身体有点累,但内心无比开心
最后,在这里提前助各位看官新年快乐,新的一年身体健康,万事如意(吧啦吧啦)