⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 walk.c

📁 模拟真人走迷宫的程序原代码
💻 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 + -