找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4820|回复: 0
打印 上一主题 下一主题
收起左侧

自创的求最短路径走迷宫算法

[复制链接]
跳转到指定楼层
楼主
ID:127229 发表于 2016-6-19 19:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
因为前几天去论坛看到有网友问迷宫算法的问题,所以抽空研究了一下搜索算法.我把很久以前写的
一个走迷宫的程序贴上去了.这个程序比较土,不会判断随机产生的迷宫是否能走通,不是按最短路径搜索,但是,只要是能连通的迷宫就肯定能走出去.呵呵,很土的一个方法,自已瞎琢磨了.
以前的程序算法是这样的:
1.随机产生由0x00和0xff结成的地图
2.从(0,0)点开始进入迷宫
3.因为出口在(MAXX,MAXY),所以搜索方向是 右->下->上->左
4.每走过一个方格把此方格对应的值加1
5.在选择方向时,总是优先选择方格值最小的相邻方格,这样,一个方格走过的次数越多就越不会再次走入, 所以自然而然就会走到(MAXX,MAXY)了
这种算法导致"小人"会在迷宫里不停的走来走去,很多时候是在重复走动,看起来傻傻的(俺喜欢)

为了解决判断迷宫是否能走通问题,和求最短路径问题,我想了很久.
网上有网友说可以用A*算法来探路比较好,我去找了几篇资料,没看太懂,
自已瞎折腾一通,又搞出一个新算法,也不知道学名叫什么,反正结果看起来是对的.呵呵
新的算法是这样的:
1.随机产生由0x00和0xff结成的地图
2.建立一个空的"连通地图方格列表",然后用递归方法去搜索所有与(0,0)相同值的方格,然后把坐格存入"连通地图方格列表"中 在递归时,如果碰到"连通地图方格列表"中已经存在的方格则跳出.这样,就产生了一个"连通地图方格列表",然后只要 判断迷宫入口坐标(0,0)和出口坐标(MAXX,MAXY)是否都在列表时就可以知道是否迷宫能走通了,好简单吧:)
3.把迷宫入口坐标(0,0)的赋值为1,然后用双重循环判断迷宫中每一方格,如果一个方格的值>1且小于255的话,则把相邻 的方格值全部加1,如果某一个相邻方格的值比所在方格值+1还要大的话(因为连通的原因),则把相邻方格设成方格值+1 重复这样做,直到 出口坐标(MAXX,MAXY) 也被赋值为止.
4.现在工作就很简单了,从出口坐标(MAXX,MAXY)开始向上推,逐次递减直到入口坐标(0,0),这样就得到了一个由多个坐标组成的路线表,也就是最短路径了(看起来是的)
5.因为是在老的程序基础上改的,也没有仔细弄,把最短路径经过方格全部设为0,把其它连通的方格则全部设为1, 这样老的程序不做什么修改就OK了.
6.欣赏了几十遍小人走通迷宫的路线,直是简洁,呵呵.


在解决迷宫问题的同时,俺发现判断连通的原理和绘图时填充算法其实是一回事,以后可以自已写填充函数了:)
迷宫问题虽然是小问题,但是扩展开来又可以解决别的问题了,如地图导航之类的.

这个程序及源代码的下载地址在:
  1. /*
  2.     这是一个研究最短迷宫寻路算法程序
  3.    
  4.     mail:szluosj@21cn.com
  5. */

  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <conio.h>
  9. #include <dos.h>
  10. #include <iostream.h>

  11. const int XSIZE = 60;
  12. const int YSIZE = 45;
  13. const int DIE  = 255;
  14. unsigned long count=0;
  15. unsigned char Map[YSIZE][XSIZE];

  16. int g_SameAreaList[YSIZE*XSIZE][2]; //相同区域的列表
  17. int g_iSameAreaCount = 0;

  18. int g_ShortPathList[YSIZE*XSIZE][2]; //最段的路径点列表
  19. int g_iShortPathCount = 0;

  20. int dir[4][2]=
  21. {
  22.     1 , 0,
  23.     0 , 1,
  24.     0 , -1,
  25.     -1, 0
  26. };


  27. int xx=0,yy=0;
  28. int oldxx=xx,oldyy=yy;

  29. //枚举一条线段上的所有点
  30. int LineDDA(int x1,int y1,int x2,int y2,void *p_pData)
  31. {
  32.     int i,p,n,x,y,tn,j;
  33.     int iIndex = 0;
  34.     int *pData = (int *)p_pData;
  35.    
  36.     if( y1==y2 ) //是一横线
  37.     {
  38.         if(x1>x2)
  39.         {
  40.             x=x2; x2=x1; x1=x;
  41.         }
  42.         
  43.         for (j=x1;j<=x2;j++)
  44.         {
  45.             pData[iIndex] = j;
  46.             pData[iIndex+1] = y1;
  47.             iIndex+=2;
  48.         }
  49.         return iIndex;
  50.     }
  51.    
  52.     if( x1==x2 ) //是一竖线
  53.     {
  54.         if(y1>y2)
  55.         {
  56.             y=y2; y2=y1; y1=y;
  57.         }
  58.         
  59.         for (j=y1;j<=y2;j++)
  60.         {
  61.             pData[iIndex] = x1;
  62.             pData[iIndex+1] = j;
  63.             iIndex+=2;
  64.         }
  65.         return iIndex;
  66.     }
  67.    
  68.     if( abs(y2-y1) <= abs(x2-x1) )
  69.     {
  70.         if( (y2<y1&&x2<x1) || (y1<=y2&&x1>x2) )
  71.         {
  72.             x=x2; y=y2; x2=x1; y2=y1; x1=x; y1=y;
  73.         }
  74.         
  75.         if( y2>=y1 && x2>=x1 )
  76.         {
  77.             x=x2-x1;
  78.             y=y2-y1;
  79.             p=2*y;
  80.             n=2*x-2*y;
  81.             tn=x;
  82.             
  83.             while(x1<=x2)
  84.             {
  85.                 if(tn>=0)
  86.                     tn-=p;
  87.                 else
  88.                 {
  89.                     tn+=n;
  90.                     y1++;
  91.                 }
  92.                
  93.                 pData[iIndex] = x1;
  94.                 pData[iIndex+1] = y1;
  95.                 iIndex+=2;
  96.                
  97.                 x1++;
  98.             }
  99.         }
  100.         else
  101.         {
  102.             x=x2-x1;
  103.             y=y2-y1;
  104.             p=-2*y;
  105.             n=2*x+2*y;
  106.             tn=x;
  107.             while(x1<=x2)
  108.             {
  109.                 if(tn>=0)
  110.                     tn-=p;
  111.                 else
  112.                 {
  113.                     tn+=n;
  114.                     y1--;
  115.                 }
  116.                 pData[iIndex] = x1;
  117.                 pData[iIndex+1] = y1;
  118.                 iIndex+=2;
  119.                
  120.                 //        putpixel(x1,y1);
  121.                 x1++;
  122.             }
  123.         }
  124.     }
  125.     else
  126.     {
  127.         x=x1; x1=y2; y2=x; y=y1; y1=x2; x2=y;
  128.         if( (y2<y1&&x2<x1) || (y1<=y2&&x1>x2) )
  129.         {
  130.             x=x2; y=y2; x2=x1; y2=y1; x1=x; y1=y;
  131.         }
  132.         
  133.         if( y2>=y1 && x2>=x1 )
  134.         {
  135.             x=x2-x1; y=y2-y1;
  136.             p=2*y; n=2*x-2*y; tn=x;
  137.             while(x1<=x2)
  138.             {
  139.                 if(tn>=0)
  140.                     tn-=p;
  141.                 else
  142.                 {
  143.                     tn+=n;
  144.                     y1++;
  145.                 }
  146.                 //      putpixel(y1,x1);
  147.                 pData[iIndex] = y1;
  148.                 pData[iIndex+1] = x1;
  149.                 iIndex+=2;
  150.                
  151.                 x1++;
  152.             }
  153.         }
  154.         else
  155.         {
  156.             x=x2-x1; y=y2-y1;
  157.             p=-2*y; n=2*x+2*y; tn=x;
  158.             
  159.             while(x1<=x2)
  160.             {
  161.                 if(tn>=0)
  162.                     tn-=p;
  163.                 else
  164.                 {
  165.                     tn+=n;
  166.                     y1--;
  167.                 }
  168.                 //        putpixel(y1,x1);
  169.                 pData[iIndex] = y1;
  170.                 pData[iIndex+1] = x1;
  171.                 iIndex+=2;
  172.                
  173.                 x1++;
  174.             }
  175.         }
  176.     }
  177.     return iIndex;
  178. }

  179. void ShowXY()
  180. {
  181.     textattr(0x0f);
  182.     gotoxy(70,1);
  183.     cprintf("X=%u",xx);
  184.     gotoxy(70,2);
  185.     cprintf("Y=%u",yy);
  186.     gotoxy(65,4);
  187.     cprintf("Total= %lu",count);
  188. }

  189. void ClearMap()
  190. {
  191.     for (int y=0;y<YSIZE;y++)
  192.     {
  193.         for (int x=0;x<XSIZE;x++)
  194.         {
  195.             Map[y][x]=0;
  196.         }
  197.     }
  198. }

  199. void MakeMap()
  200. {
  201.     int y,x;
  202.     int iData;
  203.    
  204.     ClearMap();
  205.     randomize();
  206.     for (y=0;y<YSIZE;y++)
  207.     {
  208.         for (x=0;x<XSIZE;x++)
  209.         {
  210.             iData = random(1000);
  211.             if ( (iData>0) && (iData<300) )
  212.                 Map[y][x]=DIE;
  213.         }
  214.     }
  215.     for (y=0;y<5;y++)
  216.     {
  217.         for (x=0;x<5;x++)
  218.         {
  219.             Map[y][x]=0;
  220.             Map[YSIZE-y-1][XSIZE-x-1]=0;
  221.         }
  222.     }
  223. }

  224. void DrawBox(int x1,int y1,int x2,int y2)
  225. {
  226.     textattr(0x7);
  227.     for (int i=0;i<x2-x1;i++)
  228.     {
  229.         gotoxy(i+x1,y1);
  230.         cprintf("?);
  231.             gotoxy(i+x1,y2);
  232.         cprintf("?);
  233.     }
  234.     for (i=0;i<y2-y1;i++)
  235.     {
  236.         gotoxy(x1,y1+i);
  237.         cprintf("?);
  238.             gotoxy(x2,y1+i);
  239.         cprintf("?);
  240.     }
  241.    
  242. }

  243. void ShowMan()
  244. {
  245.     gotoxy(oldxx+2+1,oldyy+2+1);
  246.     textattr(14);
  247.     cprintf(".");
  248.    
  249.     gotoxy(xx+2+1,yy+2+1);
  250.     textattr(13);
  251.     cprintf("");
  252. }

  253. void ShowMap()
  254. {
  255.     int X=2,Y=2;
  256.     DrawBox(X,Y,X+XSIZE+1,Y+YSIZE+1);
  257.     gotoxy(X+XSIZE+1,Y+YSIZE);
  258.     cprintf(" ");
  259.     gotoxy(X+1,Y);
  260.     cprintf(" ");
  261.    
  262.     for (int y=0;y<YSIZE;y++)
  263.     {
  264.         for (int x=0;x<XSIZE;x++)
  265.         {
  266.             gotoxy(x+X+1,y+Y+1);
  267.             switch(Map[y][x])
  268.             {
  269.             case DIE:
  270.                 textattr(4);
  271.                 cprintf("?);
  272.                     break;
  273.             case 254:
  274.                 textattr(0x2);
  275.                 cprintf("?);
  276.             case 0:
  277.             case 1:
  278.                 textattr(0x0f);
  279.                 cprintf(" ");
  280.                 break;
  281.             default:
  282.                 textattr(0x0E);
  283.                 cprintf(".");
  284.             }
  285.             
  286.         }
  287.     }
  288. }

  289. int isOver()
  290. { //判断是否死路, 判断是不是所有走过的路周围都没有路了,如果是这样就是死路了
  291.     int y,x;
  292.     //看看是不是还有气
  293.     for (y=0;y<YSIZE;y++)
  294.     {
  295.         for (x=0;x<XSIZE;x++)
  296.         {
  297.             if (Map[y][x]==0)
  298.                 continue;
  299.             
  300.             if (Map[y][x]==DIE)
  301.                 continue;
  302.             
  303.             if (y>1)
  304.                 if (Map[y-1][x]==0)
  305.                     return 0;
  306.                
  307.             if (y<YSIZE-1)
  308.                 if (Map[y+1][x]==0)
  309.                     return 0;
  310.                     
  311.             if (x>1)
  312.                 if (Map[y][x-1]==0)
  313.                     return 0;
  314.                         
  315.             if (x<XSIZE-1)
  316.                 if (Map[y][x+1]==0)
  317.                     return 0;
  318.         }
  319.     }
  320.    
  321.     return 1;
  322. }

  323. int GoToThere()
  324. {
  325.     int tx,ty;
  326.     unsigned char dd[4];
  327.     int i,j,d;
  328.     unsigned char min,data;
  329.    
  330.     for (d=0;d<4;d++)
  331.     {
  332.         tx = xx + dir[d][0];
  333.         ty = yy + dir[d][1];
  334.         if ((tx>=XSIZE)||(tx<0))
  335.         {
  336.             dd[d]=DIE;
  337.             continue;
  338.         }
  339.         if ((ty>=YSIZE)||(ty<0))
  340.         {
  341.             dd[d]=DIE;
  342.             continue;
  343.         }
  344.         dd[d]=Map[ty][tx];
  345.     }
  346.    
  347.     data=dd[0];
  348.     min=0;
  349.    
  350.     for (i=0;i<4;i++)
  351.     {
  352.         if (data>dd[i])
  353.         {
  354.             data=dd[i];
  355.             min = i;
  356.         }
  357.     }
  358.    
  359.     return min;
  360. }

  361. int Go()
  362. {
  363.     int i,d;
  364.     count++;
  365.     d = GoToThere();
  366.     oldxx=xx;
  367.     oldyy=yy;
  368.     xx = xx + dir[d][0];
  369.     yy = yy + dir[d][1];
  370.     Map[oldyy][oldxx]++;
  371.    
  372.     if (Map[oldyy][oldxx]==1)
  373.         Map[oldyy][oldxx] = 2;
  374.    
  375.     return 0;
  376. }

  377. int Success()
  378. {
  379.     if ((xx>=XSIZE-1) && (yy>=YSIZE-1))
  380.     {
  381.         //    do
  382.         //    {
  383.         gotoxy(70,5);
  384.         textattr(0xee);
  385.         cprintf("SUCCESS!"); //SUCCESS!
  386.         gotoxy(70,6);
  387.         textattr(0xee);
  388.         cprintf("Esc to Exit");
  389.         //    } while(getch()!=27);
  390.         return 0;
  391.     }
  392.     return -1;
  393. }

  394. int isExistPosInSameAreaList(int p_iX,int p_iY)
  395. {
  396.     for (int i=0;i<g_iSameAreaCount;i++)
  397.     {
  398.         if ( (g_SameAreaList[i][0] == p_iX) && (g_SameAreaList[i][1] == p_iY) )
  399.             return 1;
  400.     }
  401.    
  402.     return 0;
  403. }

  404. int AddOnePosToSameAreaList(int p_iX,int p_iY)
  405. {
  406.     if (isExistPosInSameAreaList(p_iX,p_iY))
  407.         return 0;
  408.    
  409.     g_SameAreaList[g_iSameAreaCount][0] = p_iX;
  410.     g_SameAreaList[g_iSameAreaCount][1] = p_iY;
  411.     g_iSameAreaCount++;
  412.    
  413.     return g_iSameAreaCount;
  414. }

  415. int GetSameArea(int p_iX,int p_iY)
  416. {
  417.     int iNewX,iNewY;
  418.     int iHasSame = 0;
  419.     for (int d=0;d<4;d++)
  420.     {
  421.         iNewX = p_iX + dir[d][0];
  422.         iNewY = p_iY + dir[d][1];
  423.         
  424.         if ( (iNewX>=0) && (iNewX<XSIZE) && (iNewY>=0) && (iNewY<YSIZE) )
  425.         { //新的位置有效
  426.             if (Map[iNewY][iNewX]==Map[p_iY][p_iX])
  427.             {
  428.                 iHasSame = 1;
  429.                 if (AddOnePosToSameAreaList(iNewX,iNewY)!=0) //追加成功一个新的节点
  430.                     if (GetSameArea(iNewX,iNewY)==0)//再查询下一个节点
  431.                         return 0;
  432.             }
  433.         }
  434.     }
  435.    
  436.     return iHasSame;
  437. }

  438. int GetSameAreaList(int x,int y)
  439. { //从map中得到一片相连的区域,存放到 listSameArea
  440.     g_iSameAreaCount = 0;
  441.     return GetSameArea(x,y);
  442. }

  443. int GetShortStepCount(int x1,int y1,int x2,int y2,int p_iStep)
  444. {
  445.     int iNewX,iNewY;
  446. //   int iStepCount = 0;
  447.     int iTemp;
  448.    
  449.    
  450.    
  451.     for (int d=0;d<4;d++)
  452.     {
  453.         iNewX = x1 + dir[d][0];
  454.         iNewY = y1 + dir[d][1];
  455.         
  456.         if ( (iNewX>=0) && (iNewX<XSIZE) && (iNewY>=0) && (iNewY<YSIZE) ) { //新的位置有效
  457.             if (Map[iNewY][iNewX]==Map[x1][y1]) {
  458.                 if ((iNewX==x2) && (iNewY==y2))
  459.                     return p_iStep;
  460.                
  461.                 iTemp = GetShortStepCount(iNewX,iNewY,XSIZE-1,YSIZE-1,p_iStep);
  462.                 if (iTemp==9999)
  463.                     Map[iNewX][iNewY] = 100;
  464.                
  465.                 p_iStep+=iTemp;
  466.             }
  467.         }
  468.     }
  469.    
  470.     Map[y1][x1] = 100;
  471.     return 9999;
  472. }

  473. int GetShortPathList()
  474. {
  475.     int iNewX,iNewY;
  476.     int iIndex;
  477.     int i,d,x,y;
  478.    
  479.    
  480.     Map[0][0] = 1;
  481.    
  482.     while (Map[YSIZE-1][XSIZE-1]==0) {
  483.         for (y=0;y<YSIZE;y++)
  484.         {
  485.             for (x=0;x<XSIZE;x++)
  486.             {
  487.                 if (Map[y][x]==DIE)
  488.                     continue;
  489.                
  490.                 if (Map[y][x]==0)
  491.                     continue;
  492.                
  493.                 for (d=0;d<4;d++)
  494.                 {
  495.                     iNewX = x + dir[d][0];
  496.                     iNewY = y + dir[d][1];
  497.                     if ( (iNewX>=0) && (iNewX<XSIZE) && (iNewY>=0) && (iNewY<YSIZE) ) { //新的位置有效
  498.                         if (Map[iNewY][iNewX]==DIE)
  499.                             continue;
  500.                         
  501.                         if (Map[iNewY][iNewX]==0)
  502.                             Map[iNewY][iNewX] = Map[y][x] + 1;
  503.                         else if (Map[iNewY][iNewX]>(Map[y][x] + 1))
  504.                             Map[iNewY][iNewX] = Map[y][x] + 1;
  505.                     }
  506.                 }
  507.             }
  508.         }
  509.     }
  510.    
  511.     iIndex = 0;
  512.    
  513.     iIndex = 0;
  514.     x = XSIZE-1;
  515.     y = YSIZE-1;
  516.     g_ShortPathList[iIndex][0] = x;
  517.     g_ShortPathList[iIndex][1] = y;
  518.     iIndex++;
  519.     while(1) {
  520.         if ( (x==0) && (y==0) )
  521.             break;
  522.         
  523.         for (d=0;d<4;d++)
  524.         {
  525.             iNewX = x + dir[d][0];
  526.             iNewY = y + dir[d][1];
  527.             if ( (iNewX>=0) && (iNewX<XSIZE) && (iNewY>=0) && (iNewY<YSIZE) ) { //新的位置有效
  528.                 if (Map[iNewY][iNewX]==(Map[y][x]-1)) {
  529.                     g_ShortPathList[iIndex][0] = iNewX;
  530.                     g_ShortPathList[iIndex][1] = iNewY;
  531.                     iIndex++;
  532.                     x = iNewX;
  533.                     y = iNewY;
  534.                     break;
  535.                 }
  536.             }
  537.         }
  538.     }
  539.    
  540.     g_iShortPathCount = iIndex;
  541.     return g_iShortPathCount;
  542. }

  543. void ShowSameArea()
  544. {
  545.     for (int i=0;i<g_iSameAreaCount;i++)
  546.     {
  547.         Map[g_SameAreaList[i][1]][g_SameAreaList[i][0]] = 10;
  548.     }
  549.    
  550.     ShowMap();
  551. }

  552. int GetPathCount(int p_iX,int p_iY)
  553. {//得到一个节点的通路个数
  554.     int iNewX,iNewY;
  555.     int iPathCount = 0;
  556.     for (int d=0;d<4;d++)
  557.     {
  558.         iNewX = p_iX + dir[d][0];
  559.         iNewY = p_iY + dir[d][1];
  560.         
  561.         if ( (iNewX>=0) && (iNewX<XSIZE) && (iNewY>=0) && (iNewY<YSIZE) ) { //新的位置有效
  562.             if (Map[iNewY][iNewX]==1)
  563.                 iPathCount++;
  564.             else if (Map[iNewY][iNewX]==0)
  565.                 iPathCount++;
  566.         }
  567.     }
  568.     return iPathCount;
  569. }

  570. int DropAllLeaf()
  571. {
  572.     int iCount;
  573.    
  574.     //删除单一叶子结点
  575.     do {
  576.         iCount = 0;
  577.         
  578.         for (int i=0;i<g_iSameAreaCount;i++)
  579.         {
  580.             if (GetPathCount(g_SameAreaList[i][0],g_SameAreaList[i][1])<=1)
  581.             {
  582.                 Map[g_SameAreaList[i][1]][g_SameAreaList[i][0]] = 254;
  583.                 g_SameAreaList[i][0] = 0;
  584.                 g_SameAreaList[i][1] = 0;
  585.                 iCount++;
  586.             }
  587.         }
  588.     } while(iCount>0);
  589.    
  590.     return iCount;
  591.     //删除两个分支的结点
  592. }

  593. int DropDoubleLeaf()
  594. {
  595.     int SameAreaList[YSIZE*XSIZE][2]; //相同区域的列表
  596. //    int iSameAreaCount = 0;

  597.     for (int i=0;i<g_iSameAreaCount;i++)
  598.     {
  599.         memcpy((char *)SameAreaList,g_SameAreaList,YSIZE*XSIZE*2*sizeof(int));
  600. //        iSameAreaCount = g_iSameAreaCount;

  601.         if (GetPathCount(g_SameAreaList[i][0],g_SameAreaList[i][1])==2)
  602.         { //有两条分支
  603.             Map[g_SameAreaList[i][1]][g_SameAreaList[i][0]] = 254;
  604.             g_SameAreaList[i][0] = 0;
  605.             g_SameAreaList[i][1] = 0;
  606.             //     iCount++;
  607.         }
  608.     }

  609.     return 0;
  610. }

  611. void init()
  612. {
  613.     xx=0,yy=0;
  614.     oldxx=xx,oldyy=yy;
  615.     count = 0;
  616.    
  617.    
  618.     //    highvideo(void);
  619.     //    lowvideo(void);
  620.     //    normvideo(void);
  621.     clrscr();
  622.     clrscr();
  623.     _setcursortype(_NOCURSOR);
  624. }

  625. void end()
  626. {
  627.     //    highvideo(void);
  628.     //    lowvideo(void);
  629.     //    normvideo(void);
  630.    
  631.     textattr(0x07);
  632.     clrscr();
  633.     _setcursortype(_NORMALCURSOR);
  634. }

  635. void main()
  636. {
  637.     int i;
  638.     //    highvideo();
  639.     textmode(64);
  640.    
  641.     end();
  642.     init();
  643.    
  644. lab_begin:
  645.    
  646.    
  647.     end();
  648.     init();
  649.     MakeMap();
  650.    
  651.     GetSameAreaList(1,1);
  652.    
  653.     if (!isExistPosInSameAreaList(XSIZE-1,YSIZE-1)) {
  654.         gotoxy(70,5);
  655.         textattr(0xee);
  656.         cprintf("disconnect!");
  657.         gotoxy(70,6);
  658.         textattr(0xee);
  659.         cprintf("Esc to Exit");
  660.         sound(500);
  661.         delay(100);
  662.         sound(250);
  663.         delay(100);
  664.         sound(500);
  665.         delay(100);
  666.         nosound();
  667.         
  668.         ShowSameArea();
  669.         //            ShowMap();
  670.         //            getch();
  671.         delay(1000);
  672.         
  673.         goto lab_begin;
  674.     }
  675.    
  676.     //    ShowSameArea();
  677.    
  678.     for (i=0;i<g_iSameAreaCount;i++)
  679.         Map[g_SameAreaList[i][1]][g_SameAreaList[i][0]] = 0;
  680.         /*
  681.         g_iShortPathCount = LineDDA(0,0,XSIZE-1,YSIZE-1,g_ShortPathList); // 最段的路径点列表
  682.         printf("\n%d\n",g_iShortPathCount);
  683.     */
  684.    
  685.     g_iShortPathCount = 0 ;
  686.     GetShortPathList();
  687.    
  688.     for (i=0;i<g_iSameAreaCount;i++)
  689.         Map[g_SameAreaList[i][1]][g_SameAreaList[i][0]] = 1;
  690.    
  691.     for (i=0;i<g_iShortPathCount;i++) {
  692.         if (Map[g_ShortPathList[i][1]][g_ShortPathList[i][0]]!=DIE)
  693.             Map[g_ShortPathList[i][1]][g_ShortPathList[i][0]] = 0;
  694.     }
  695.    
  696.     /*
  697.     g_iShortPathCount = 0 ;
  698.     //  GetShortPathList();
  699.     g_iShortPathCount = LineDDA(0,0,XSIZE-1,YSIZE-1,g_ShortPathList); // 最段的路径点列表
  700.     for (i=0;i<g_iShortPathCount;i++) {
  701.     if (Map[g_ShortPathList[i][1]][g_ShortPathList[i][0]]!=DIE)
  702.     Map[g_ShortPathList[i][1]][g_ShortPathList[i][0]] = 0;
  703.     }
  704.     */
  705.     //    delay(2000);
  706.     ShowMap();
  707.    
  708.     do
  709.     {
  710.         Go();
  711.         
  712.         //ShowMap();
  713.         ShowMan();
  714.         ShowXY();
  715.         
  716.         if (Success()==0)
  717.         {
  718.             delay(1000);
  719.             end();
  720.             goto lab_begin;
  721.             //      return;
  722.         }
  723.         
  724.         delay(50);
  725.         
  726.     }while(!kbhit());
  727.     if (getch()!=27)
  728.         goto lab_begin;
  729.    
  730.     _setcursortype(_NORMALCURSOR);
  731.     clrscr();
  732.     //    normvideo();
  733.     textmode(-1);
  734. }


  735. /*
  736. 20:05 2005-9-9
  737. 今天是周末,没很多事,抽空研究了一下搜索算法.因为前几天去论坛看到有网友请教迷宫算法的问题,我把很久以前写的
  738. 一个走迷宫的程序贴上去了.这个程序比较土,不会判断随机产生的迷宫是否能走通,不是按最短路径搜索,但是,只要是
  739. 能连通的迷宫就肯定能走出去.呵呵,我的算法没学好,很多时候就搞自已瞎琢磨了.

  740.   以前的程序算法是这样的:
  741.   
  742. 1.随机产生由0x00和0xff结成的地图
  743. 2.从(0,0)点开始进入迷宫
  744. 3.因为出口在(MAXX,MAXY),所以搜索方向是  右->下->上->左
  745. 4.每走过一个方格把此方格对应的值加1
  746. 5.在选择方向时,总是优先选择方格值最小的相邻方格,这样,一个方格走过的次数越多就越不会再次走入,
  747. 所以自然而然就会走到(MAXX,MAXY)了

  748. 这种算法导致"小人"会在迷宫里不停的走来走去,很多时候是在重复走动,看起来傻傻的(俺喜欢)


  749. 为了解决判断迷宫是否能走通问题,和求最短路径问题,我想了很久.
  750. 嫌型阉悼梢杂肁*算法来探路比较好,我去找了几篇资料,没看太懂,
  751. 自已瞎折腾一通,又搞出一个新算法,也不知道学名叫什么,反正结果看起来是对的.呵呵

  752. 新的算法是这样的:

  753. 1.随机产生由0x00和0xff结成的地图

  754. 2.建立一个空的"连通地图方格列表",然后用递归方法去搜索所有与(0,0)相同值的方格,然后把坐格存入"连通地图方格列表"中
  755. 在递归时,如果碰到"连通地图方格列表"中已经存在的方格则跳出.这样,就产生了一个"连通地图方格列表",然后只要
  756. 判断迷宫入口坐标(0,0)和出口坐标(MAXX,MAXY)是否都在列表时就可以知道是否迷宫能走通了,好简单吧:)

  757. 3.把迷宫入口坐标(0,0)的赋值为1,然后用双重循环判断迷宫中每一方格,如果一个方格的值>1且小于255的话,则把相邻
  758. 的方格值全部加1,如果某一个相邻方格的值比所在方格值+1还要大的话(因为连通的原因),则把相邻方格设成方格值+1
  759. 重复这样做,直到  出口坐标(MAXX,MAXY) 也被赋值为止.

  760. 4.现在工作就很简单了,从出口坐标(MAXX,MAXY)开始向上推,逐次递减直到入口坐标(0,0),这样就得到了一个由多个
  761. 坐标组成的路线表,也就是最短路径了(看起来是的)

  762. 5.因为是在老的程序基础上改的,也没有仔细弄,把最短路径经过方格全部设为0,把其它连通的方格则全部设为1,
  763. 这样老的程序不做什么修改就OK了.

  764. 6.欣赏了几十遍小人走通迷宫的路线,直是简洁,呵呵.

  765.   嗯,程序虽然表面上功能是实现了,但不知道这样处理是不是会有漏洞.
  766.   
  767.     算法书上的公式都看不懂,郁闷.
  768. */
复制代码




luosj_mg.rar

52.33 KB, 下载次数: 8, 下载积分: 黑币 -5

评分

参与人数 1黑币 +8 收起 理由
芦苇劫 + 8

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表