📄 walk.c
字号:
#include "graphics.h"
#include "stdio.h"
#define N 10
#define M N*N-4+1 /*堆栈最大值,用来保存路口信息*/
#define UP 1
#define DOWN -1
#define LEFT 2
#define RIGHT -2
#define UP_M man.x-1>=0&&a[man.x-1][man.y] /*人当前位置的上一个位置*/
#define DOWN_M man.x+1<N&&a[man.x+1][man.y]
#define LEFT_M man.y-1>=0&&a[man.x][man.y-1]
#define RIGHT_M man.y+1<N&&a[man.x][man.y+1]
#define ENTER 3 /*岔路的入口*/
#define HAVE 2 /*某条路已经走过*/
struct cross{int up,down,left,right,x,y;} across,stack[M]={0};
int top=1;
int PX=70,PY=40;
struct {int x,y,s;}man;
/*迷宫定义,1表示路,可自行更改迷宫的路径,可使全为1,看效果等*/
int a[N][N]={0,0,0,1,1,0,1,1,1,0,
1,1,0,1,0,1,1,0,1,0,
0,1,1,1,1,0,1,1,1,1,
1,0,1,0,1,1,1,0,1,0,
1,1,1,1,0,0,1,1,1,1,
1,0,1,0,1,1,1,0,1,0,
0,0,1,1,1,0,1,1,1,0,
1,1,1,0,1,0,1,0,1,0,
0,0,1,0,1,1,1,0,1,1,
0,1,1,0,0,1,0,0,0,0};
void init_man() /*初始化人的状态,要求迷宫入口须在左侧*/
{int i;setcolor(WHITE);
for(i=0;i<N;i++)
if(a[i][0]) {man.x=i;man.y=0;
if(a[i][1]) man.s=RIGHT;
else if(i+1<N&&a[i+1][0]) man.s=DOWN;
else if(i-1>=0&&a[i-1][0]) man.s=UP;
else {outtextxy(500,300,"no way!");getch();exit(0);}
return ;}
if(i==N) {outtextxy(500,300,"no enter!");getch();exit(0);}
}
void show_map() /*显示迷宫*/
{int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(a[i][j]) {setfillstyle(1,WHITE);
bar(PX+j*20,PY+i*20,PX+j*20+20,PY+i*20+20);}
else {setfillstyle(1,LIGHTBLUE);
bar(PX+j*20,PY+i*20,PX+j*20+20,PY+i*20+20);}
setcolor(BLACK);
for(i=0;i<N;i++)
{line(PX+i*20,PY,PX+i*20,PY+20*N);
line(PX,PY+i*20,PX+20*N,PY+i*20);}
}
void show_man(int color)
{
setfillstyle(1,color);
bar(PX+man.y*20+5,PY+man.x*20+5,PX+man.y*20+20-5,PY+man.x*20+20-5);
}
int cross() /*岔路判断*/
{int count=0;
if(UP_M) count++;
if(DOWN_M) count++;
if(LEFT_M) count++;
if(RIGHT_M) count++;
return count;}
void move() /*依据人的移动状态而移动到新位置*/
{
show_man(GREEN);
switch(man.s)
{case UP:man.x-=1;break;
case DOWN:man.x+=1;break;
case LEFT:man.y-=1;break;
case RIGHT:man.y+=1;break;
}
show_man(LIGHTRED);
}
void back() /*回头走*/
{switch(man.s)
{case UP:man.s=DOWN;move();break;
case DOWN:man.s=UP;move();break;
case LEFT:man.s=RIGHT;move();break;
case RIGHT:man.s=LEFT;move();break;
}
}
void go_on() /*为通路且不是岔路时,继续向前走*/
{switch(man.s)
{case UP:if(UP_M) move();
else if(LEFT_M) {man.s=LEFT;move();}
else if(RIGHT_M) {man.s=RIGHT;move();}
break;
case DOWN:if(DOWN_M) move();
else if(LEFT_M){man.s=LEFT;move();}
else if(RIGHT_M) {man.s=RIGHT;move();}
break;
case LEFT:if(LEFT_M) move();
else if(UP_M) {man.s=UP;move();}
else if(DOWN_M) {man.s=DOWN;move();}
break;
case RIGHT:if(RIGHT_M) move();
else if(UP_M) {man.s=UP;move();}
else if(DOWN_M) {man.s=DOWN;move();}
break;
}
}
int xin() /*判断人当前位置是否是新岔路口*/
{int i;
for(i=1;i<top;i++)
if(man.x==stack[i].x&&man.y==stack[i].y) return i;
return 0;
}
void copy() /*拷贝岔路信息到across结构体*/
{across.x=man.x;
across.y=man.y;
if(UP_M==1) across.up=1;
else across.up=0;
if(DOWN_M==1) across.down=1;
else across.down=0;
if(LEFT_M==1) across.left=1;
else across.left=0;
if(RIGHT_M==1) across.right=1;
else across.right=0;
}
void rukou() /*为岔路设置一个入口*/
{switch(man.s)
{case UP:across.down=ENTER;break;
case DOWN:across.up=ENTER;break;
case LEFT:across.right=ENTER;break;
case RIGHT:across.left=ENTER;break;
}
}
void xuanlu(struct cross *p) /*在岔路时,为人选一条路行走*/
{switch(man.s)
{case UP:if(p->up==1) p->up=HAVE;
else if(p->left==1) {man.s=LEFT;p->left=HAVE;}
else if(p->right==1) {man.s=RIGHT;p->right=HAVE;}
else {man.s=DOWN;p->down=HAVE;}
break;
case DOWN:if(p->down==1) p->down=HAVE;
else if(p->left==1) {man.s=LEFT;p->left=HAVE;}
else if(p->right==1) {man.s=RIGHT;p->right=HAVE;}
else {man.s=UP;p->up=HAVE;}
break;
case LEFT:if(p->left==1) p->left=HAVE;
else if(p->up==1) {man.s=UP;p->up=HAVE;}
else if(p->down==1) {man.s=DOWN;p->down=HAVE;}
else {man.s=RIGHT;p->right=HAVE;}
break;
case RIGHT:if(p->right==1) p->right=HAVE;
else if(p->up==1) {man.s=UP;p->up=HAVE;}
else if(p->down==1) {man.s=DOWN;p->down=HAVE;}
else {man.s=LEFT;p->left=HAVE;}
break;
}
}
push(struct cross *p) /*把新岔路口入栈*/
{stack[top].left=p->left;
stack[top].right=p->right;
stack[top].up=p->up;
stack[top].down=p->down;
stack[top].x=p->x;
stack[top].y=p->y;
top++;
}
int wan(struct cross *p) /*当前人所在的岔路口走完否?*/
{int count=0;
if(p->left==1) count++;
if(p->right==1) count++;
if(p->up==1) count++;
if(p->down==1) count++;
if(count>0) return 0;
return 1;
}
void chukou(struct cross *p) /*人从出口出来*/
{if(p->up==ENTER) man.s=UP;
else if(p->down==ENTER) man.s=DOWN;
else if(p->left==ENTER) man.s=LEFT;
else man.s=RIGHT;
}
main()
{int c,k;
int gdriver=DETECT,gmode;
registerbgidriver(EGAVGA_driver);
initgraph(&gdriver,&gmode,"");
cleardevice();
show_map();
init_man();show_man(LIGHTRED);getch();delay(65000);
do{
switch(c=cross())
{case 1:switch(man.s)
{case UP:if(UP_M) move();
else back();break;
case DOWN:if(DOWN_M) move();
else back();break;
case LEFT:if(LEFT_M) move();
else back();break;
case RIGHT:if(RIGHT_M) move();
else back();break;}
break;
case 2:go_on();break;
case 3:
case 4:k=xin();
if(!k) {copy();rukou();xuanlu(&across);push(&across);}
else {if(wan(&stack[k])) chukou(&stack[k]);
else xuanlu(&stack[k]);}
move();
break;
}
delay(65000);
}while(!kbhit());
closegraph();}
/*请大家注意:按任意键开始走(电脑自动模拟的),在按一次键则退出程序,它可以走遍所有的岔路寻找迷宫出口,由于我并未编写走出迷宫胜利的条件,所以,最后它会返回到入口处来回的“震荡”,为清楚看到它的行程,我使得每次走过的路都用绿色示意。*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -