推箱子游戏

来源:互联网 发布:武汉淘宝客服外包 编辑:程序博客网 时间:2024/04/29 09:11
//推箱子游戏,游戏死亡(当出现一个箱子不在目的地位置且无法移动时游戏死亡,也就是第一时间判断游戏死亡了)代码未给出

#include<stdio.h>



//整个界面用ASCII码显示
#define EMPTY 0//空格子
#define REN 11//人
#define REN_INTO 12//人进入目的地后的图像
#define BOX 1//箱子
#define CELL 15//目的地单元
#define BOX_INTO 2//箱子进入目的地后的图像
#define WALL 35//墙



#define RIGHT 0
#define DOWN 1
#define LEFT 2
#define UP 3



#define N 8//地图的大小



void Init();
void Move();
void Display();
void GameOver();



//界面数组——只给了一幅地图,因此此游戏只有一关,可以自己设计地图,替换本地图,编译后可以运行

//地图的大小可以改变,由于写程序时为了方便,使用的是正方形地图,因此只能是N*N的界面数组

//设计出的地图N不是8时,需要修改上面的#define N 8中N的值

//界面数组
int a[N][N]={{35,35,35,35,35,35,35,35},
{35,35,35,0,0,0,0,35},
{35,11,0,15,1,0,0,35},
{35,0,15,0,0,35,0,35},
{35,35,35,0,1,35,0,35},
{35,35,35,0,0,35,0,35},
{35,35,35,35,35,35,35,35}};

const int d[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//方向数组,分别是右下左上
int dir;//移动方向标志
int gate;//关数
int done;//完成个数
int total;//总共箱子的个数,至少是一个

struct movable
{
int x;
int y;
int flag;//保存当前位置的原始状态,人或箱子是在空格处,还是目的位置,需要标记,因为人或箱子移走后需要显示什么图像有flag指示
}ren,*box;


int main(void)
{
int ch;
int i;
Init();
Display();
while(1)
{
ch=getch();
if(ch>='1'&&ch<='3'||ch=='5')
{
switch(ch)//控制按键是数字键盘的1、2、3、5
{
case '1':dir=LEFT;break;
case '2':dir=DOWN;break;
case '3':dir=RIGHT;break;
case '5':dir=UP;break;
}
Move();
Display();
}
if(done==total)
{
break;
}
}
GameOver();
getch();
free(ren);//内存释放
for(i=0;i<total;i++)
free(box[i]);
return 0;
}



void Init()
{
int i,j;
int number = 0;//箱子的序号,仅仅是为了给每个箱子初始化用的
total = 0;
gate = 1;
done = 0;
//外围是墙,因此i从1开始
for(i=1;i<N-1;i++)//第一次扫描地图,得到箱子总数
{
for(j=1;j<N-1;j++)
{
if(a[i][j]==BOX_INTO||a[i][j]==BOX)//刚开始时,有些箱子已经在目的地了
{
total++;
}
}
}
box = (struct movable *)malloc(total*sizeof(struct movable));//分配所有箱子的内存
if(box==NULL)//内存分配失败
{
printf("箱子内存分配失败");
exit(1);
}
for(i=1;i<N-1;i++)//第二次扫描,找到所有箱子的坐标和人的坐标,并进行flag赋值
{
for(j=1;j<N-1;j++)
{
if(a[i][j]==BOX_INTO||a[i][j]==BOX)
{
box[number].x = i;//得到每个箱子的坐标
box[number].y = j;
//如果箱子一开始就在目的地,就将flag置为CELL,并且done++,表示已经完成的数目,否则置为EMPTY
box[number].flag = (a[box[number].x][box[number].y]==BOX)?EMPTY:(done++,CELL);//使用了一个逗号表达式
number++;
}
else if(a[i][j]==REN||a[i][j]==REN_INTO)
{
ren.x = i;//得到人的坐标
ren.y = j;
ren.flag = (a[ren.x][ren.y]==REN_INTO)?CELL:EMPTY;//如果人一开始就在格子中,就将人flag赋值为CELL
}
}
}
}





void Display()
{
int i,j;
system("cls");
printf("NO:%d\n",gate);//打印当前关卡数
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
printf("%2c",a[i][j]);
}
printf("\n");
}
}





void Move()
{
int i;
int number;//人前面箱子的号码
int k=0,j=0;
struct movable *p;
int dire;//死亡判断时需要的方向
switch(a[ren.x+d[dir][0]][ren.y+d[dir][1]])//根据人前面单元的情况进行相应处理
{
case EMPTY://人前面是空格
case CELL:{//人前面是目的地

//游戏刚开始时已经设置人和箱子的flag
//1.将人当前位置还原成flag标记的图像
//2.将人移动一格
//3.将人当前位置的图像保存到flag中
//4.将人当前位置的图像设置为REN,用于显示
a[ren.x][ren.y]=ren.flag;//将当前位置还原图像
ren.x+=d[dir][0];//改变人的坐标
ren.y+=d[dir][1];
ren.flag=a[ren.x][ren.y];//保存当前位置的原始图像,注意顺序,要先保存,再修改当前单元图像
a[ren.x][ren.y]=(ren.flag==EMPTY)?REN:REN_INTO;//当前位置为空就将当前位置置为REN
break;
}
//人前边是箱子
case BOX_INTO://BOX_INTO和BOX两个中仅仅只有flag不同而已
case BOX:{
switch(a[ren.x+d[dir][0]+d[dir][0]][ren.y+d[dir][1]+d[dir][1]])//判断箱子前面的单元
{
//箱子前面的情况有五种
case WALL:
case BOX:
case BOX_INTO:break;//箱子前面是墙或箱子就不动

//1.通过坐标判断人前面的箱子是几号箱子
//得到是几号箱子就得到了箱子的坐标和箱子的flag(flag只能为CELL或EMPTY)
//2.将箱子单元置为箱子的flag
//3.箱子移动一格
//4.得到当前箱子单元的flag
//5.将当前箱子的状态进行改变
//6.将人所在单元的状态还原成原始状态
//7.人移动一格
//8.得到当前人所在单元的原始状态
//9.将当前人所在的单元进行改改
case EMPTY:
case CELL:{
for(i=0;i<total;i++)//得到人前面的箱子的号码
{
if((box[i].x==ren.x+d[dir][0])&&(box[i].y==ren.y+d[dir][1]))
number = i;
}
if(a[box[number].x][box[number].y]==BOX_INTO)//人前面为BOX_INTO,则要让done减一
{
done--;//done是完成的箱子数目
}
a[box[number].x][box[number].y]=box[number].flag;//将箱子单元还原
box[number].x+=d[dir][0];//改变箱子坐标
box[number].y+=d[dir][1];
box[number].flag=a[box[number].x][box[number].y];//得到当前箱子的flag
//如果箱子的flag是EMPTY,当前位置就显示为BOX,否则done++,显示为BOX_INTO
a[box[number].x][box[number].y]=(box[number].flag==EMPTY)?BOX:(done++,BOX_INTO);
a[ren.x][ren.y]=ren.flag;//将人所在单元还原为人的flag
ren.x+=d[dir][0];//改变人的坐标
ren.y+=d[dir][1];
ren.flag=a[ren.x][ren.y];//保存当前单元的flag
a[ren.x][ren.y]=(ren.flag==EMPTY)?REN:REN_INTO;//将当前人的位置进行显示

break;
}
default:break;
}
break;
}
default:break;
}
}

void GameOver()
{
if(done==total)
{
printf("You win,Congratulate!!!\n");
}
}
原创粉丝点击