用C语言编程推箱子小游戏
1、任何一个推箱子小游戏的地图上均有墙壁,箱子,空地,目的地,人这几个因素,我们用相应的数字和符号来代替它,使界面更简单明了。

2、而每一个地图其实都类似于一个二维数组,因此在程序中可以通过创建二维数组来创建游戏地图。在这里,我们分别创建三个地图,分别为简单,一般,困难(三个地图均是在网上寻找,转化为二维数组)下面附上原图和代码,以供参考。





3、由于这个程序拥有三个地图,那么在游戏开始前,我们应当选择地图,这个时候我们定义一个新函数来完成选择地图的功能。

1、关于游戏中人物的移动,我们选择用“↑”,“↓”,“←”,“→”来控制小人的上下左右移动,首先我们需要先定义关于上下左右移动的函数。并且定义计分系统



2、定义好方向键,就应该来定义游戏中各种移动情况。(1)当人前面是空地的时候,人移动后,那么本来人的位置应该由“人”变成“空地”或者“目的地”(当人移动前正好站在目的地上),而移动后人所在的位置状态应该由“空地”变成“人”。

3、(2)当人前面是目的地的时候,人移动后,那么本来人的位置应该由“人”变成“空地”或者“目的地”(当人移动前正好站在目的地上),而移动后人所在的位置状态应该由“目的地”变成“人”。

4、(3)当人前面是箱子且箱子处于空地上。这个时候不仅需要考虑人的移动,还需要考虑箱子的情况,这和时候又要分两种情况:一是箱子前面是空地,二是箱子前面是目的地。人的位置状态与前面类似,而箱子的状态也与人的状态类似,只是由于有加分系统,所以在情况二下我们应该多加一分

5、(4)当人前面是箱子且箱子处于目的地上,这个时候也需要考虑箱子的移动,同样分成箱子前面是目的地和箱子前面是空地两种情况,这个时候与情况三有区别的是,在情况三,箱子前面是空地时分数不变,前面是目的地时加一分;而这时箱子前面是空地时需要减一分,而箱子前面是目的地时,分不变。

1、主要给玩家提供帮助,使玩家能更好的进行游戏,依旧,先进行宏定义,再进行函数定义。


1、//文件包含
#include<stdio.h> //标准输入输出函数库
#include<stdlib.h> //标准函数库
#include<string.h> //字符串函数库
#include<conio.h> //控制台输入输出函数库
//系统菜单选项宏定义
#define EXIT 0 //退出系统
#define START 1 //开始游戏
#define HELP 2 //操作说明
#define ABOUT 3 //关于作者
//地图大小宏定义
#define MAP_R 12 //地图行数
#define MAP_C 16 //地图列数
//游戏操作移动方向宏定义
#define DIR_UP 1 //向上移动
#define DIR_DOWN 2 //向下移动
#define DIR_LEFT 3 //向左移动
#define DIR_RIGHT 4 //向右移动
//游戏地图等级选项宏定义
#define LEVEL_EASY 1 //简单
#define LEVEL_MEDIAN 2 //一般
#define LEVEL_HARD 3 //困难
//游戏地图组成宏定义
#define ROAD 0 //"○"——空地
#define WALL 1 //"●"——墙壁
#define DEST 2 //"□"——目的地
#define BOX 3 //"■"——箱子
#define MAN 4 //"♀"——人
#define BOXD 5 //"■"——箱子在目的地上
#define MAND 6 //"♀"——人在目的地上
//0表示可通行道路;1表示墙壁;2表示目的地;3表示箱子;4表示人
//地图1——简单
int map1[12][16]={
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,2,0,2,2,1,1,1,1,1,1},
{1,1,1,1,1,1,2,0,3,2,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,3,1,1,1,1,1,1},
{1,1,1,1,1,0,3,0,0,3,0,1,1,1,1,1},
{1,1,1,1,1,0,1,3,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,0,0,4,0,0,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
//地图2——一般
int map2[12][16]={
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1},
{1,1,1,0,3,3,0,0,3,0,0,0,1,1,1,1},
{1,1,1,0,0,1,2,1,1,0,1,0,1,1,1,1},
{1,1,1,1,0,1,2,2,2,3,4,0,1,1,1,1},
{1,1,1,1,0,2,2,2,1,1,3,1,1,1,1,1},
{1,1,1,0,0,1,1,2,1,1,0,0,1,1,1,1},
{1,1,1,0,3,3,0,0,3,0,0,0,1,1,1,1},
{1,1,1,0,0,1,0,0,0,1,0,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
//地图3——困难
int map3[12][16]={
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1},
{1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1},
{1,1,1,1,1,1,1,0,0,3,0,3,1,0,1,1},
{1,1,1,1,1,1,1,0,0,0,3,0,0,0,1,1},
{1,2,2,1,0,0,1,1,0,3,0,3,1,0,1,1},
{1,2,2,0,0,0,1,1,0,3,0,3,1,0,1,1},
{1,2,2,1,0,0,1,1,0,1,1,1,1,1,1,1},
{1,2,2,1,0,1,0,3,0,3,0,1,1,1,1,1},
{1,2,2,0,0,0,0,0,3,0,0,1,1,1,1,1},
{1,0,0,1,1,1,4,0,0,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
//推箱子游戏函数说明
void ShowMenu(); //人机界面函数
void ChooseMap(int map[MAP_R][MAP_C]); //选择游戏地图
//确定地图中人的初始位置
void FindBoxmanPos(int map[MAP_R][MAP_C], int *xpos, int *ypos);
void DrawMap(int map[MAP_R][MAP_C]);//绘制地图
//游戏移动一步相应的处理函数
void MoveStep(int map[MAP_R][MAP_C], int *xpos, int *ypos, int dir, int *step, int *score);
void PlayGame(); //游戏运行函数
int CheckBoxNum(int map[MAP_R][MAP_C]); //检测箱子总数
void Help(); //游戏帮助说明
void About(); //作者信息
void ShowMenu()
{
int type;
while(1)
{
system("cls"); //清屏
printf("********************************\n");
printf("* 推箱子游戏 *\n");
printf("********************************\n");
printf("* 0-退出系统 \n");
printf("* 1-开始游戏 \n");
printf("* 2-操作说明 \n");
printf("* 3-关于作者 \n");
printf("********************************\n");
printf("->请选择操作:");
scanf("%d",&type);
if(type==EXIT) //退出系统
break;
switch(type)
{
case START: //开始游戏
PlayGame();
system("pasue");
break;
case HELP: //帮助说明
system("cls");
Help();
system("pasue");
break;
case ABOUT: //作者信息
system("cls");
About();
system("pasue");
break;
default:
printf("输入有误!\n");
system("pasue");
break;
}
}
}
void PlayGame()
{
int map[MAP_R][MAP_C];
int step=0,score=0;
int dir,flag=1;
int ch,cl;
int xpos,ypos;
int boxNum;
ChooseMap(map); //选择地图
boxNum=CheckBoxNum(map); //获取箱子个数
DrawMap(map,step,score); //绘制初始地图
FindBoxmanPos(map,&xpos,&ypos); //确定人初始位置
while(flag)
{
dir=-1;
//方向键的ASCII码由两个字符(ch,cl)组成,高位为ch,低位为cl
ch=getch();
if(ch==113||ch==81) //游戏中按字符'Q'或'q'直接退出游戏
break;
cl=getch();
if(ch==224)
{
switch(cl)
{
case 72: //向上移动——方向键↑,ASCII码为(224,72)
dir=DIR_UP;
break;
case 80: //向下移动——方向键↓,ASCII码为(224,80)
dir=DIR_DOWN;
break;
case 75: //向左移动——方向键←,ASCII码为(224,75)
dir=DIR_LEFT;
break;
case 77: //向右移动——方向键→,ASCII码为(224,77)
dir=DIR_RIGHT;
break;
}
}
if(dir>0) //移动
{
MoveStep(map,&xpos,&ypos,dir,&step,&score); //移动处理
DrawMap(map,step,score); //刷新地图
if(score==boxNum) //每移动一步检测游戏是否结束
{
printf("**** You win! ****\n");
printf("********************************\n");
break;
}
}
}
}
void ChooseMap(int map[MAP_R][MAP_C])
{
int level;
int (*p)[MAP_C] = NULL; //数组指针
int x,y;
while(1)
{
printf("********************************\n");
printf("* 1-地图1(简单) \n");
printf("* 2-地图2(一般) \n");
printf("* 3-地图3(困难) \n");
printf("********************************\n");
printf("->选择地图(1~3):");
scanf("%d",&level);
if(level<1 || level>3)
{
printf("输入错误!\n");
system("pause");
}
else
break;
}
switch(level)
{
case LEVEL_EASY: //地图1
p=map1;
break;
case LEVEL_MEDIAN: //地图2
p=map2;
break;
case LEVEL_HARD: //地图3
p=map3;
break;
}
for(y=0;y<MAP_R;y++)
for(x=0;x<MAP_C;x++)
map[y][x]=p[y][x];
}
void FindBoxmanPos(int map[MAP_R][MAP_C], int *xpos, int *ypos)
{
int x,y;
for(y=0;y<MAP_R;y++)
for(x=0;x<MAP_C;x++)
if(map[y][x]==MAN)
{
*xpos=x;
*ypos=y;
}
}
void DrawMap(int map[MAP_R][MAP_C],int step,int score)
{
char *c[]={"○","●","□","■","♀","■","♀"};
int x,y;
system("cls");
for(y=0;y<MAP_R;y++)
{
for(x=0;x<MAP_C;x++)
printf("%s",c[map[y][x]]);
printf("\n");
}
printf("********************************\n");
printf("**移动步数: %d\n",step);
printf("**游戏得分: %d\n",score);
printf("********************************\n");
}
int CheckBoxNum(int map[MAP_R][MAP_C])
{
int x,y,boxNum=0;
for(y=0;y<MAP_R;y++)
for(x=0;x<MAP_C;x++)
if(map[y][x]==BOX) //统计箱子个数
boxNum++;
return boxNum;
}
void MoveStep(int map[MAP_R][MAP_C], int *xpos, int *ypos, int dir, int *step, int *score)
{
int mx,my; //人移动后坐标(m-man)
int bx,by; //人前面箱子移动后坐标(b-box)
switch(dir)
{
case DIR_UP:
mx=*xpos,my=*ypos-1; //人向上移动一步
bx=mx,by=my-1; //箱子向上移动一步
break;
case DIR_DOWN:
mx=*xpos,my=*ypos+1; //人向下移动一步
bx=mx,by=my+1; //箱子向下移动一步
break;
case DIR_LEFT:
mx=*xpos-1,my=*ypos; //人向左移动一步
bx=mx-1,by=my; //箱子向左移动一步
break;
case DIR_RIGHT:
mx=*xpos+1,my=*ypos; //人向右移动一步
bx=mx+1,by=my; //箱子向右移动一步
break;
}
//人已到达地图边界,不能再往前移动
if(mx<0||mx>=MAP_C||my<0||my>=MAP_R)
return;
//case1:人前面是空地
if(map[my][mx]==ROAD)
{
if(map[*ypos][*xpos]==MAN) //人当前站在空地上
map[*ypos][*xpos]=ROAD;
else //人当前站在目标位置上(MAND)
map[*ypos][*xpos]=DEST;
//人移动到前面的空地上
map[my][mx]=MAN;
*ypos=my;
*xpos=mx;
(*step)++; //移动步数加1
}
//case2:人前面是目的地
if(map[my][mx]==DEST)
{
if(map[*ypos][*xpos]==MAN) //人当前站在空地上
map[*ypos][*xpos]=ROAD;
else //人当前站在目标位置上(MAND)
map[*ypos][*xpos]=DEST;
//人移动到前面的目标位置上
map[my][mx]=MAND;
*ypos=my;
*xpos=mx;
(*step)++; //移动步数加1
}
//箱子已到达地图边界,不能再往前移动
if(bx<0||bx>=MAP_C||by<0||by>=MAP_R)
return;
//case3:人前面是箱子且箱子位于空地上
if(map[my][mx]==BOX)
{
//(1)箱子前面是空地,可移动
if(map[by][bx]==ROAD)
{
map[by][bx]=BOX; //箱子移动到前面的空地上
if(map[*ypos][*xpos]==MAN) //人当前站在空地上
map[*ypos][*xpos]=ROAD;
else //人当前站在目标位置上
map[*ypos][*xpos]=DEST;
//人移动到前面的空地上
map[my][mx]=MAN;
*ypos=my;
*xpos=mx;
(*step)++; //移动步数加1
}
//(2)箱子前面是目的地,可移动
if(map[by][bx]==DEST)
{
map[by][bx]=BOXD; //箱子移动到前面的目的地地上
if(map[*ypos][*xpos]==MAN) //人当前站在空地上
map[*ypos][*xpos]=ROAD;
else //人当前站在目标位置上
map[*ypos][*xpos]=DEST;
//人移动到前面的空地上
map[my][mx]=MAN;
*ypos=my;
*xpos=mx;
(*step)++; //移动步数加1
(*score)++; //箱子从空地移动到目的地,得分加1分
}
}
//case4:人前面是箱子且箱子位于目的地上
if(map[my][mx]==BOXD)
{
//(1)箱子前面是空地,可移动
if(map[by][bx]==ROAD)
{
map[by][bx]=BOX; //箱子移动到前面的空地上
if(map[*ypos][*xpos]==MAN) //人当前站在空地上
map[*ypos][*xpos]=ROAD;
else //人当前站在目标位置上
map[*ypos][*xpos]=DEST;
//人移动到前面的目的地上
map[my][mx]=MAND;
*ypos=my;
*xpos=mx;
(*step)++; //移动步数加1
(*score)--; //箱子从目的地移动到空地,得分减1分
}
//(2)箱子前面是目的地,可移动
if(map[by][bx]==DEST)
{
map[by][bx]=BOXD; //箱子移动到前面的目的地地上
if(map[*ypos][*xpos]==MAN) //人当前站在空地上
map[*ypos][*xpos]=ROAD;
else //人当前站在目标位置上
map[*ypos][*xpos]=DEST;
//人移动到前面的目的地上
map[my][mx]=MAND;
*ypos=my;
*xpos=mx;
(*step)++; //移动步数加1
}
}
}
void Help()
{
printf("********************************\n");
printf("* 游戏操作说明 *\n");
printf("********************************\n");
printf("* ○-表示可通行墙壁 *\n");
printf("* ●-表示墙壁 *\n");
printf("* □-表示目的地 *\n");
printf("* ■-表示箱子 *\n");
printf("* ♀-表示人 *\n");
printf("* 方向键↑-向上移动 *\n");
printf("* 方向键↓-向下移动 *\n");
printf("* 方向键←-向左移动 *\n");
printf("* 方向键→-向右移动 *\n");
printf("********************************\n");
system("pause");
}
void About()
{
printf("********************************\n");
printf("* *\n");
printf("*作者:依筱糯流 *\n");
printf("* *\n");
printf("********************************\n");
system("pause");
}
void main()
{
ShowMenu();
}
1、结果如下:






