基于A*算法10*10迷宫

来源:互联网 发布:手机淘宝写追评句子 编辑:程序博客网 时间:2024/06/06 04:40
#include <stdio.h>#include <conio.h>#include <graphics.h>#include <dos.h>#include <time.h>#include <math.h>#define MAX_NUMBER_LENGTH 10 #define ESC 0x011btypedef struct {unsigned char shape;int fx,fy; //father x,yunsigned int g,h,f;} TILE;typedef struct {int x,y;}POINT;TILE maze[10][10];POINT open_list[10*10];int open_count;  //open表中的元素数char mark[10][10];  //标记是否被closestatic int gPath[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {      {0,0,0,0,0,0,0,0,0,0},      {0,1,1,0,1,1,1,0,1,0},      {0,1,1,0,1,1,1,0,1,0},      {0,1,1,1,1,0,0,1,1,0},      {0,1,0,0,0,1,1,1,1,0},      {0,1,1,1,0,1,1,1,1,0},{0,1,0,1,1,1,0,1,1,0},{0,1,0,0,0,1,0,0,1,0},{0,0,1,1,1,1,1,1,2,0},{0,0,0,0,0,0,0,0,0,0}};  //迷宫的分布int Start_Point[1][2] ={1,1};//入口int Exit_Point[1][2] = {8,8}; //出口void print_path(void);   //输出路径void start(void);    //开始,确认游戏模式。void Input_Maze(void) ;   //自定义模式迷宫输入int getKey(void); //获取按键信息,返回有效的操作值void Random(void);// 随机迷宫int in_open_list(int x,int y);//考察是x,y是否在openlist中,是返回1反之返回0int search_best_in_open_list(int *px, int *py);//寻找open list中下一个最优先打开节点int find_way(int x0, int y0, int x1, int y1);  //寻找(x0,y0)到(x1,y1)的最短路径int find_way(int x0, int y0, int x1, int y1){   int k, nx, ny, sx, sy,oldx,oldy;   int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; //四个方向   memset(mark, 0, sizeof(mark));  //清除close list   maze[x0][y0].fx = -1;     maze[x0][y0].fy = -1; //初始化起点   maze[x0][y0].g = 0;   maze[x0][y0].h = abs(x1-x0)+abs(y1-y0);   maze[x0][y0].f = maze[x0][y0].g + maze[x0][y0].h;   sx = x0;   sy = y0;   open_count = 0;  //初始化open list   while(!mark[x1][y1])   {      mark[sx][sy] = 1;  //初始点进入 close list      for(k=0; k<4; k++)  //四个方向搜索      {         nx = sx+d[k][0];         ny = sy+d[k][1]; if(nx <0 || ny < 0 || nx > 9 || ny > 9)            continue;         if(maze[nx][ny].shape == 0 || mark[nx][ny] == 1)  //该方向是非法点或在close list中            continue;         if(in_open_list(nx, ny))  //在open list 中         {            if(maze[sx][sy].g + 1 < maze[nx][ny].g)  //是一个从起点到此处代价更小的节点            {               maze[nx][ny].fx = sx;               maze[nx][ny].fy = sy;               maze[nx][ny].g = maze[sx][sy].g + 1;               maze[nx][ny].f = maze[nx][ny].g + maze[nx][ny].h;            }            continue;         }         maze[nx][ny].fx = sx;  //完成的(nx,ny)节点的属性赋值         maze[nx][ny].fy = sy;         maze[nx][ny].g = maze[sx][sy].g + 1;         maze[nx][ny].h = abs(x1 - nx) + abs(y1 - nx);         maze[nx][ny].f = maze[nx][ny].g + maze[nx][ny].h;         open_list[open_count].x = nx;  //将其列入open list         open_list[open_count].y = ny;         open_count++;      }      if(search_best_in_open_list(&sx, &sy) == 0)  //选择下一个搜索节点,若无法继续搜索则跳出循环         break;   }   nx = x1;   ny = y1;   do   {   gPath[nx][ny] ='#';   oldx=nx;   oldy=ny;   nx = maze[oldx][oldy].fx;   ny = maze[oldx][oldy].fy;   }   while (nx != -1 || ny != -1);   return 1;}int search_best_in_open_list(int *px, int *py){   int i, n;   unsigned int f;//估值函数值   n = open_count - 1;   if(mark[open_list[n].x][open_list[n].y])//判断是否在close list 中      n = -1;   f = -1;      for(i=open_count - 1; i>=0; i--)   //寻找最优节点   {        if(mark[open_list[i].x][open_list[i].y])         continue;       if(maze[open_list[i].x][open_list[i].y].f < f)      {         f = maze[open_list[i].x][open_list[i].y].f;         n = i;      }   }   if(n == -1)//open list中无元素      return 0;   *px = open_list[n].x;   *py = open_list[n].y;   return 1;}int in_open_list(int x,int y){int i;for(i=0;i<open_count;i++){if(mark[open_list[i].x][open_list[i].y]) //节点在close list中continue;if(open_list[i].x ==x && open_list[i].y == y)//节点在open list 中return 1;}return 0;}void Random(void)//随机化迷宫{int i,j;for(i=1;i<=8;i++){for(j=1;j<=8;j++){if(i== 1 && j == 1 || i==8 && j==8)continue;if(random(3) == 1)gPath[i][j] = 0;elsegPath[i][j] = 1;}}i=1;for(j=1;j<=8;j++)gPath[i][j] = 1;j=8;for(i=1;i<=7;i++)gPath[i][j] = 1;}int getKey(void){  while(bioskey(1))  {    int key = bioskey(0);    switch(key)    {      case ESC:return key;    }  }  return 0;}void print_path(void)  {      int outer;      int inner;  int key,i,j;    int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,"");    for(outer = 0; outer < MAX_NUMBER_LENGTH; outer++)//绘制整个迷宫的方块{          for(inner = 0; inner < MAX_NUMBER_LENGTH; inner++){if(gPath[outer][inner] == '#'){setfillstyle(SOLID_FILL,WHITE);}else{if(gPath[outer][inner] == 0)setfillstyle(SOLID_FILL,RED);elsesetfillstyle(SOLID_FILL,BLUE);} bar(inner*20,outer*20,inner*20+20,outer*20+20); setcolor(BLACK); rectangle(inner*20,outer*20,inner*20+20,outer*20+20);        }       }setfillstyle(SOLID_FILL,YELLOW);//绘制起点setcolor(BLACK);fillellipse(Start_Point[0][0]*20+10,Start_Point[0][1]*20+10,5,5);while(1){key=getKey();if(key == ESC){closegraph();break;}}}  void start(void){char key;puts("press 's' enter DIY mode,'R' enter Random mode otherwise enter default mode");key = getch();if(key != 's' && key != 'S'){if(key =='R' || key =='r'){Random();}else    return;}else {Input_Maze();return;}}void Input_Maze(void){int i,j;puts("input a 8*8 maze");puts("0 stands for wall,1 stands for route,2 stands for exit");for(i=1;i<9;i++){for(j=1;j<9;j++)scanf("%d",&gPath[i][j]);}puts("input entrance x,y ");scanf("%d,%d",&Start_Point[0][0],&Start_Point[0][1]);return;}main(){int i,j;clrscr();randomize();start();for(i=0;i<9;i++){for(j=0;j<9;j++){maze[i][j].shape = gPath[i][j];}}for(i=0;i<=9;i++){for(j=0;j<=9;j++){if(gPath[i][j] == 2){Exit_Point[0][1] = j;Exit_Point[0][0] = i;}}}for(i=0;i<=9;i++){for(j=0;j<=9;j++){printf("%d ",gPath[i][j]);}putchar('\n');}delay(2000);while(1){if(find_way(Start_Point[0][0],Start_Point[0][1],Exit_Point[0][0],Exit_Point[0][1]))break;}gPath[Exit_Point[0][0]][Exit_Point[0][1]] ='#';print_path();return 0;}

0 0
原创粉丝点击