C语言小程序推箱子问题
发布网友
发布时间:2022-04-25 04:16
我来回答
共2个回答
热心网友
时间:2023-10-25 07:31
你好,这是推箱子的全部代码
/*图形模式下的推箱子*/
#define MAX 2 /*游戏中总关数*/
#define STARTX 180
#define STARTY 80
#define BKCOLOR BLACK
#define MANCOLOR RED
#define OBJECTCOLOR YELLOW
#define TIMEINT 2
#define STARNUM 300
#define STEPMAX 5
#include<string.h>
#include<bios.h>
#include<stdio.h>
#include<dos.h>
#include<graphics.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#define Key_R 0x1372
#define Key_Up 0x4800
#define Key_Enter 0x1c0d
#define Key_Down 0x5000
#define Key_P 0x1970
#define Key_Esc 0x11b
#define Key_Right 0x4d00
#define Key_Left 0x4b00
typedef struct star
{
int x;
int y;
int c;
}Star;
Star s[STARNUM];
typedef struct record
{
char name[20];
int second;
struct time t;
struct date d;
}Record;
Record r[MAX];
typedef struct c
{
int x;
int y;
}Add;
typedef struct a
{
int x;
int y;
}Player;
Player p;
char name[20]; /*进入游戏时记录玩家的姓名*/
time_t t1,t2; /*游戏结束时的时间*/
int Ide; /*开始进入游戏时,选择菜单时返的功能号(1,2,3)*/
int MissionNum; /*玩家正在玩的关数*/
int BoxNum; /*目的地的个数*/
int Key; /*玩家按键*/
int map[10][10]; /*地图.(空=0),(人=1),(箱子=2),(墙=3),(目的地=4),(人+目的地=5),(箱子+目的地=6)*/
int StepNum;
int DirectionKey; /*用来表示方向键最后一次按键*/
int BoxMove[STEPMAX];
int Step[STEPMAX];
/*函数定义*/
void InputName();
void Init();
void MainMenu();
void JudgeRecord();
void WriteRecord();
void JudgeIde();
void DrawMenu(int );
void Game();
void InitMission(int );
void NextMission();
void InitPic(int ,int ,int );
int Move(Add );
void DrawWall(int ,int );
void DrawBack(int ,int );
void DrawBox(int ,int );
void DrawObject(int ,int );
void DrawMan(int ,int );
void DrawStar();
int JudgeWin();
void InitMission1();
void InitMission2();
int TimeCome();
void ChangeStar();
void InputName();
void ViewRecords();
void DeleteRecords();
void RegisterStep();
void ReverselyMove();
void MoveBack(Add );
void main()
{
InputName();
Init(); /*驱动显卡*/
srand(time(&t1));
MainMenu(); /*画开始菜单(1.start game 2.view records 3.delete records 4.exit game)*/
}
void InputName()
{
char b;
char c;
do
{
printf("\n\nPlease input your password:");
scanf("%s",&b);
}while(b!='l');
clrscr();
do
{
printf("\n\nPlease input your name:");
scanf("%s",name);
printf("Are you sure the name right(Y/N):");
do
{
c=getch();
}while(c!='Y'&&c!='y'&&c!='N'&&c!='n');
}while(c!='Y'&&c!='y');
}
void Init()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"d:\\tc");
}
void MainMenu()
{
setbkcolor(BKCOLOR);
cleardevice();
DrawStar(); /*画开始菜单的背景画面*/
DrawStar();
Ide=0,Key=0;
DrawMenu(Ide);
do
{
if(bioskey(1)) /*有键按下则处理按键*/
{
Key=bioskey(0);
switch(Key)
{
case Key_Down: {Ide++;Ide=Ide%4;DrawMenu(Ide);break;}
case Key_Up: {Ide--;Ide=(Ide+4)%4;DrawMenu(Ide);break;}
}
}
else {if(TimeCome()) ChangeStar();} /*改变背景*/
}while(Key!=Key_Enter);
JudgeIde(); /*根据Ide运行不同的程序*/
}
void JudgeIde()
{
switch(Ide)
{
case 0:Game();break;
case 1:{ViewRecords();bioskey(0);MainMenu();break;}
case 2:{DeleteRecords();ViewRecords();bioskey(0);MainMenu();break;}
case 3:exit(0);
}
}
void Game()
{
int i,j,flag;
Add ad;
MissionNum=0;
NextMission();
do
{
flag=0;
Key=bioskey(0);
switch(Key)
{
case Key_Enter:{NextMission();time(&t1);break;}
case Key_Up:{ad.x=-1;ad.y=0;flag=1;DirectionKey=Key;break;}
case Key_Down:{ad.x=1;ad.y=0;flag=1;DirectionKey=Key;break;}
case Key_Left:{ad.x=0;ad.y=-1;flag=1;DirectionKey=Key;break;}
case Key_Right:{ad.x=0;ad.y=1;flag=1;DirectionKey=Key;break;}
case Key_R:{MissionNum--;NextMission();break;}
case Key_Esc:{MainMenu();break;}
case Key_P:{ReverselyMove();break;}
}
if(flag==1)
{if(Move(ad)) {RegisterStep(); if(JudgeWin()) {JudgeRecord();NextMission();}}}
}while(1);
}
void InitMission(int n)
{
int i,j;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
map[i][j]=0;
switch(n)
{
case 1:InitMission1();break; /*第一关*/
case 2:InitMission2();break; /*第二关*/
}
}
void InitPic(int n,int i,int j)
{
switch(n)
{
case 0:DrawBack(i,j);break;
case 1:DrawMan(i,j);break;
case 2:DrawBox(i,j);break;
case 3:DrawWall(i,j);break;
case 4:DrawObject(i,j);break;
case 5:DrawMan(i,j);break;
case 6:DrawBox(i,j);break;
}
}
void NextMission()
{
int i,j;
if(MissionNum+1>MAX) MissionNum=1;
else MissionNum++;
InitMission(MissionNum);
setbkcolor(BKCOLOR);
cleardevice();
for(i=0;i<10;i++)
for(j=0;j<10;j++)
InitPic(map[i][j],i,j);
switch(MissionNum)
{
case 1:outtextxy(200,230,"Mission 1");break;
case 2:outtextxy(200,230,"Mission 2");break;
}
time(&t1);
for(i=0;i<STEPMAX;i++)
{Step[i]=BoxMove[i]=0;}
StepNum=0;
}
int Move(Add a)
{
int flag;
int i=StepNum%STEPMAX;
switch(map[p.x+a.x][p.y+a.y]) /*看下一位置为什么*/
{
case 0:{map[p.x][p.y]-=1;InitPic(map[p.x][p.y],p.x,p.y);
p.x=p.x+a.x;p.y=p.y+a.y;
map[p.x][p.y]+=1;InitPic(map[p.x][p.y],p.x,p.y);flag=1;break;}
case 2:{if(map[p.x+2*a.x][p.y+2*a.y]==0||map[p.x+2*a.x][p.y+2*a.y]==4)
{map[p.x][p.y]-=1;map[p.x+a.x][p.y+a.y]=1;map[p.x+2*a.x][p.y+2*a.y]+=2;
InitPic(map[p.x][p.y],p.x,p.y);
InitPic(map[p.x+a.x][p.y+a.y],p.x+a.x,p.y+a.y);
InitPic(map[p.x+2*a.x][p.y+2*a.y],p.x+2*a.x,p.y+2*a.y);
p.x=p.x+a.x;p.y=p.y+a.y;flag=1;BoxMove[i]=1;}
else flag=0;
break;}
case 3:flag=0;break;
case 4:{map[p.x][p.y]-=1;InitPic(map[p.x][p.y],p.x,p.y);
p.x=p.x+a.x;p.y=p.y+a.y;
map[p.x][p.y]+=1;InitPic(map[p.x][p.y],p.x,p.y);flag=1;break;}
case 6:{if(map[p.x+2*a.x][p.y+2*a.y]==0||map[p.x+2*a.x][p.y+2*a.y]==4)
{map[p.x][p.y]-=1;map[p.x+a.x][p.y+a.y]=5;map[p.x+2*a.x][p.y+2*a.y]+=2;
InitPic(map[p.x][p.y],p.x,p.y);
InitPic(map[p.x+a.x][p.y+a.y],p.x+a.x,p.y+a.y);
InitPic(map[p.x+2*a.x][p.y+2*a.y],p.x+2*a.x,p.y+2*a.y);
p.x=p.x+a.x;p.y=p.y+a.y;flag=1;BoxMove[i]=1;}
else flag=0;
break;}
}
return flag;
}
void DrawWall(int i,int j)
{
DrawBack(i,j);
setfillstyle(9,1);
bar(STARTX+20*j-9,STARTY+20*i-9,STARTX+20*j+9,STARTY+20*i+9);
}
void DrawMan(int i,int j)
{
DrawBack(i,j);
setcolor(MANCOLOR);
circle(STARTX+20*j,STARTY+20*i,9);
arc(STARTX+20*j-3,STARTY+20*i-2,20,160,3);
arc(STARTX+20*j+4,STARTY+20*i-2,20,160,3);
arc(STARTX+20*j,STARTY+20*i-2,220,320,7);
}
void DrawBack(int i,int j)
{
setfillstyle(1,BKCOLOR);
bar(STARTX+20*j-9,STARTY+20*i-9,STARTX+20*j+9,STARTY+20*i+9);
}
void DrawObject(int i,int j)
{
DrawBack(i,j);
setcolor(OBJECTCOLOR);
line(STARTX+20*j-9,STARTY+20*i,STARTX+20*j+9,STARTY+20*i);
line(STARTX+20*j-9,STARTY+20*i-9,STARTX+20*j+9,STARTY+20*i+9);
line(STARTX+20*j-9,STARTY+20*i+9,STARTX+20*j+9,STARTY+20*i-9);
}
void DrawBox(int i,int j)
{
DrawBack(i,j);
setfillstyle(9,3);
bar(STARTX+20*j-9,STARTY+20*i-9,STARTX+20*j+9,STARTY+20*i+9);
}
void DrawMenu(int j)
{
int n;
char *s[4]={"1.Start Game","2.View Records","3.Delete Records","4.Exit Game"};
settextstyle(0,0,1);
setcolor(GREEN);
for(n=0;n<4;n++)
outtextxy(250,170+n*20,s[n]);
setcolor(RED);
outtextxy(250,170+j*20,s[j]);
}
void DrawStar()
{
int w,h,i,dotx,doty,color,maxcolor;
w=getmaxx();
h=getmaxy();
maxcolor=getmaxcolor();
for(i=0;i<STARNUM;i++)
{
s[i].x=1+random(w-1);
s[i].y=1+random(h-1);
s[i].c=random(maxcolor);
putpixel(s[i].x,s[i].y,s[i].c);
}
}
void ChangeStar()
{
int i,maxcolor;
maxcolor=getmaxcolor();
for(i=0;i<STARNUM;i++)
{
s[i].c=random(maxcolor);
putpixel(s[i].x,s[i].y,s[i].c);
}
}
int TimeCome()
{
static long tm, old;
tm=biostime(0,tm);
if(tm-old<TIMEINT) return 0;
else
{
old=tm; return 1;
}
}
int JudgeWin()
{
int n=0,i,j;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
if(map[i][j]==6) n++;
if(n==BoxNum) return 1;
else return 0;
}
void InitMission1() /*第九关*/
{
int i,j;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
map[i][j]=0;
for(i=0;i<=5;i++)
map[0][i]=3;
for(i=5;i<=7;i++)
{map[2][i]=map[i-1][1]=3;}
for(i=1;i<=4;i++)
{map[6][i]=map[5][i+3]=map[i][0]=3;}
map[3][7]=map[4][7]=map[1][5]=3;
for(i=2;i<=4;i++)
map[2][i]=2;
map[3][4]=map[4][5]=2;
for(i=2;i<=3;i++)
{map[3][i]=map[4][i]=4;}
map[4][4]=4;
p.x=3;p.y=5;
map[3][5]=1;
BoxNum=5;
}
void InitMission2()
{
int i,j;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
map[i][j]=0;
for(i=1;i<=5;i++)
{map[0][i]=map[6][i]=3;}
for(i=2;i<=4;i++)
{map[1][i+3]=map[i][7]=map[i+2][5]=map[i][0]=3;}
map[1][1]=map[2][1]=map[5][0]=map[5][5]=map[4][6]=map[6][0]=3;
map[2][4]=map[3][3]=map[4][2]=map[4][3]=2;
map[2][3]=map[3][2]=map[3][4]=map[4][4]=4;
p.x=1;p.y=3;
map[1][3]=1;
BoxNum=4;
}
void ViewRecords()
{
FILE *fp;
int i;
setbkcolor(BKCOLOR);
cleardevice();
if((fp=fopen("record","r"))==NULL)
{
printf("\nerror on open file!");
getch();
exit(1);
}
gotoxy(1,1);
printf("\n\t\t\tRecord Information\n");
printf("Record-holder Achievement(s)\t Time(h:m:s)\t\tDate(y/m/d)");
for(i=0;i<MAX;i++)
{fseek(fp,i*sizeof(Record),0);
fread(&r[i],sizeof(Record),1,fp);
printf("\n%-10s\t%d\t\t %02d:%02d:%02d\t\t%02d/%02d/%02d",r[i].name,r[i].second,r[i].t.ti_hour,r[i].t.ti_min,r[i].t.ti_sec,r[i].d.da_year,r[i].d.da_mon,r[i].d.da_day);}
fclose(fp);
gotoxy(10,25);
printf("Press any key to return mainmenu...");
}
void DeleteRecords()
{
int i;
FILE *fp;
fp=fopen("record","w");
for(i=0;i<MAX;i++)
{
strcpy(r[i].name,"nameless");
r[i].second=0;
gettime(&r[i].t);
getdate(&r[i].d);
}
for(i=0;i<MAX;i++)
fwrite(&r[i],sizeof(Record),1,fp);
fclose(fp);
}
void JudgeRecord()
{
int i=MissionNum-1;
time(&t2);
if(r[i].second==0||difftime(t2,t1)<r[i].second)
{
gotoxy(10,3);printf("\t\tYou have broken the record");
r[i].second=difftime(t2,t1);
strcpy(r[i].name,name);
gettime(&r[i].t);
getdate(&r[i].d);
WriteRecord();
}
else
{gotoxy(10,3);printf("\t\tYou have pass this mission");}
gotoxy(10,4);
printf("\t\tpress any key continue...");
getch();
getch();
}
void WriteRecord()
{
FILE *fp;
int i=MissionNum-1;
fp=fopen("record","rt+");
fseek(fp,i*sizeof(Record),0);
fwrite(&r[MissionNum-1],sizeof(Record),1,fp);
fclose(fp);
}
void RegisterStep()
{
int i;
StepNum++;
i=(StepNum-1)%STEPMAX;
Step[i]=DirectionKey;
}
void ReverselyMove()
{
int i;
Add ad;
i=(StepNum-1)%STEPMAX;
if(Step[i]==0) return;
else
{
switch(Step[i])
{
case Key_Up:{ad.x=1;ad.y=0;MoveBack(ad);break;}
case Key_Down:{ad.x=-1;ad.y=0;MoveBack(ad);break;}
case Key_Left:{ad.x=0;ad.y=1;MoveBack(ad);break;}
case Key_Right:{ad.x=0;ad.y=-1;MoveBack(ad);break;}
}
StepNum--;Step[i]=0;BoxMove[i]=0;
}
}
void MoveBack(Add a) /*一定可以移动*/
{
int i=(StepNum-1)%STEPMAX;
if(BoxMove[i]==0)
{
map[p.x][p.y]-=1;InitPic(map[p.x][p.y],p.x,p.y);
p.x=p.x+a.x;p.y=p.y+a.y;
map[p.x][p.y]+=1;InitPic(map[p.x][p.y],p.x,p.y);
}
else if(BoxMove[i]==1)
{
map[p.x-a.x][p.y-a.y]-=2;InitPic(map[p.x-a.x][p.y-a.y],p.x-a.x,p.y-a.y);
map[p.x][p.y]+=1;InitPic(map[p.x][p.y],p.x,p.y);
p.x=p.x+a.x;p.y=p.y+a.y;
map[p.x][p.y]+=1;InitPic(map[p.x][p.y],p.x,p.y);
}
}
热心网友
时间:2023-10-25 07:32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int visit[100][100][100];
int mark[100][100];
int judge(int x,int y,int n,int m,int map[100][100])
{
if(x>=0&&x<m&&y>=0&&y<n&&map[x][y]!=1)
return 1;
return 0;
}
int dfsman(int map[100][100],int n,int m,int startx,int starty,int endx,int endy,int bx,int by)//判断是否能到达箱子的一端
{
int queue[10000][2];
int head=0,tail=1,x,y,xx,yy,i;
memset(queue,0,sizeof(queue));
memset(mark,0,sizeof(mark));
queue[0][0]=startx;
queue[0][1]=starty;
map[bx][by]=-1;
while(head<tail)
{
x=queue[head][0];
y=queue[head][1];
//printf("%d %d\n",x+1,y+1);
if(x==endx&&y==endy)
{
map[bx][by]=0;
return 1;
}
head++;
for(i=0;i<4;i++)
{
xx=x+dx[i];
yy=y+dy[i];
if(mark[xx][yy]==1) continue;
if(judge(xx,yy,n,m,map)==1&&map[xx][yy]!=-1)
{
mark[xx][yy]=1;
queue[tail][0]=xx;
queue[tail][1]=yy;
tail++;
}
}
}
map[bx][by]=0;
return 0;
}
void dfs(int map[100][100],int n,int m,int startx,int starty,int endx,int endy,int boxx,int boxy)
{
int queue[10000][5];
int head=0,tail=1,step,i;
int x,y,bx,by,mx,my;//箱子
int xx,yy;//人
memset(queue,0,sizeof(queue));
queue[0][0]=boxx;//箱子位置
queue[0][1]=boxy;
queue[0][2]=startx;//人的位置
queue[0][3]=starty;
queue[0][4]=0;
while(head<tail)
{
//if(dfsman(map,n,m,startx,starty,boxx,boxy)==0) break;//判断小人是否能到达箱子,如果不能说明小人被围墙困住
x=queue[head][0];//箱子位置
y=queue[head][1];
xx=queue[head][2];//人的位置
yy=queue[head][3];
step=queue[head][4];
//printf("%d %d %d %d %d\n",x+1,y+1,xx+1,yy+1,step);
head++;
if(x==endx&&y==endy)//假如箱子达到目的地打印step
{
printf("%d\n",step);
return ;
}
for(i=0;i<4;i++)
{
bx=x+dx[i]; by=y+dy[i];//箱
mx=x-dx[i]; my=y-dy[i];
if(judge(mx,my,n,m,map)==0||judge(bx,by,n,m,map)==0) continue;
if(visit[bx][by][i]==1) continue;
if(dfsman(map,n,m,xx,yy,mx,my,x,y)==1)//visit[xx][yy][i] i为从那个方向推来的
{
visit[bx][by][i]=1;
queue[tail][0]=bx;
queue[tail][1]=by;
queue[tail][2]=mx;
queue[tail][3]=my;
queue[tail][4]=step+1;
tail++;
}
}
}
printf("-1\n");
}
int main()
{
int map[100][100],n,m,t,startx,starty,endx,endy,boxx,boxy;
int i,j;
scanf("%d",&t);
while(t>=1)
{
memset(visit,0,sizeof(visit));
memset(map,0,sizeof(map));
scanf("%d %d",&m,&n);//m行n列的迷宫
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==4)
startx=i,starty=j;//人的位置
if(map[i][j]==3)
endx=i,endy=j;//箱子的目的地
if(map[i][j]==2)
boxx=i,boxy=j;//箱子的所在位置
}
dfs(map,n,m,startx,starty,endx,endy,boxx,boxy);
t--;
}
// system("pause");
return 0;
}