迷宫的基本实现

#define SIZE 6/*
  MazeMap是迷宫的地图,数值1表示当前区域可行,数值0表示当前区域不可行,
  nDestRow表示目的行,nDestColumn表示目的列,在这里没有出栈之前,没
  查询栈是否为空,是一个bug,毕竟不是所有的迷宫都有出路
  迷宫的入口大致从座标(1,1)开始,大致的走向如下:

         <3------>1
              |
              |

  */
void FindMazePath(int MazeMap[SIZE][SIZE],int nDestRow,int nDestColumn)
{
    node* pVisit=(node*)malloc(100*sizeof(node));
    memset(pVisit,0x00,100*sizeof(node));
    //根节点进栈 入口座标(1,1),排除零的干扰
    int nBoundRow=SIZE-1;
    int nBoundColumn=SIZE-1;
    const int nEndRow=nDestRow;
    const int nEndColumn=nDestColumn;
    CStack stack;
    //初始化节点进栈的时候,最后的进栈方向应该是0,而不是1,因为它可以走四个方向,如果填写1,意味着不可能往3的方向走
    stack.PushStack(1,1,1,0);
    StoreFoot(pVisit,1,1);
    int nRow,nColumn,nDirections;
    int nNowRow,nNowColumn;
    int nLastDirections;
    while(stack.IsStackNotEmpty())
    {
        stack.PopStack(nRow,nColumn,nDirections,nLastDirections);
        cout<<"start to pop stack and check end:"<<nRow<<"  "<<nColumn<<" "<<nDirections<<endl;
        //如果已经到达出口,退出循环
        if((nRow==nEndRow)&&(nEndColumn==nColumn))
        {
            cout<<"Finish"<<endl;
            break;
        }

        switch(nDirections)
        {
        case 1://向右 nColumn+1
            nNowRow=nRow;
            nNowColumn=nColumn+1;
            if((nNowColumn>nBoundColumn)||(3==nLastDirections))
            {
                nDirections++; //越界,找下一个方向,或者不允许往回走
                cout<<"choose another directions"<<endl;
            }
            else
            {
                //判断当前的区域是否可通行,并且当前区域是没有走过的
                if((0!=MazeMap[nNowRow][nNowColumn])&&(false==IsVisit(pVisit,nNowRow,nNowColumn)))
                {

                    nDirections=1;
                    cout<<"Push Stack1:"<<nRow<<"  "<<nColumn<<endl;
                    stack.PushStack(nRow,nColumn,1,nLastDirections);
                    stack.PushStack(nNowRow,nNowColumn,1,1);
                    cout<<"Push Stack1:"<<nNowRow<<"  "<<nNowColumn<<endl;
                    StoreFoot(pVisit,nNowRow,nNowColumn);
                    break;//退出循环
                }
            }

        case 2://
            nNowRow=nRow+1;
            nNowColumn=nColumn;
            if((nNowRow>nBoundRow)||(4==nLastDirections))
            {
                nDirections++; //越界,找下一个方向
            }
            else
            {
                //判断当前的区域是否可通行,并且当前区域是没有走过的
                 if((0!=MazeMap[nNowRow][nNowColumn])&&(false==IsVisit(pVisit,nNowRow,nNowColumn)))
                {
                    cout<<"start to visit"<<endl;
                    nDirections=2;
                    cout<<"Push Stack:"<<nRow<<"  "<<nColumn<<endl;
                    stack.PushStack(nRow,nColumn,2,nLastDirections);
                    stack.PushStack(nNowRow,nNowColumn,1,2);
                    cout<<"Push Stack:"<<nNowRow<<"  "<<nNowColumn<<endl;
                    StoreFoot(pVisit,nNowRow,nNowColumn);
                    break;//退出循环
                }
            }


        case 3:
            nNowColumn=nColumn-1;
            nNowRow=nRow;
            if((nNowColumn<1)||(1==nLastDirections))
            {
                nDirections++;
            }
            else
            {
                //判断当前的区域是否可通行,并且当前区域是没有走过的
                 if((0!=MazeMap[nNowRow][nNowColumn])&&(false==IsVisit(pVisit,nNowRow,nNowColumn)))
                {
                    nDirections=3;
                    cout<<"Push Stack:"<<nRow<<"  "<<nColumn<<endl;
                    stack.PushStack(nRow,nColumn,2,nLastDirections);
                    stack.PushStack(nNowRow,nNowColumn,1,3);
                    cout<<"Push Stack:"<<nRow<<"  "<<nColumn<<endl;
                    StoreFoot(pVisit,nNowRow,nNowColumn);
                    break;
                }
            }

        case 4:
            nNowRow=nRow-1;
            nNowColumn=nColumn;
            if((nNowRow<1)||2==nLastDirections)
            {
                stack.PopStack(nRow,nColumn,nDirections,nLastDirections);
            }
            else
            {
                //判断当前的区域是否可通行,并且当前区域是没有走过的
                 if((0!=MazeMap[nNowRow][nNowColumn])&&(false==IsVisit(pVisit,nNowRow,nNowColumn)))
                {
                    nDirections=4;
                    cout<<"Push Stack:"<<nRow<<"  "<<nColumn<<endl;
                    stack.PushStack(nRow,nColumn,4,nLastDirections);
                    stack.PushStack(nNowRow,nNowColumn,1,4);
                    cout<<"Push Stack:"<<nRow<<"  "<<nColumn<<endl;
                    StoreFoot(pVisit,nNowRow,nNowColumn);
                    break;
                }
            }

        default:
            break;
        }

    }

    while(stack.IsStackNotEmpty())
    {
        stack.PopStack(nRow,nColumn,nDirections,nLastDirections);
        cout<<"nRow:"<<nRow<<"   "<<"nColumn:"<<nColumn<<endl;

    }

}
如下是栈的定义:
typedef struct SNode{
    int nRow;//行
    int nColumn;//列
    int nDirections;//当前已经走过的方向
    int nLastDirections;//上一个位置走到这个位置的方向,避免往回走
    SNode* pNextNode;
}SNode;

class CStack
{

private:
    SNode* m_pCStackTop;
    int  m_nNodeCount;

public:
    CStack();

    ~CStack();

    //进栈
    int PushStack(int nRow,int nColumn,int nDirections, int nLastDirections);

    //获取栈顶元素
    int GetTop(int& nRow,int& nColumn,int& nDirections, int nLastDirections);

    //出栈
    int PopStack(int& nRow,int& nColumn,int& nDirections,int nLastDirections);

    int DisplayStack();

    bool IsStackNotEmpty();


};

如下是栈的实现:
#include <stdio.h>#include <stdlib.h>
#include <iostream>
using namespace std;
#include "stack.h"

CStack::CStack()
{
   m_pCStackTop=new SNode;
   if(NULL==m_pCStackTop)
   {
       exit(-1);
   }
   m_pCStackTop->pNextNode=NULL;

}
CStack::~CStack()
{
    SNode* pTmpNode=m_pCStackTop;
    while(NULL!=pTmpNode)
    {
        m_pCStackTop=pTmpNode->pNextNode;
        delete pTmpNode;
        pTmpNode=m_pCStackTop;
    }
}

int CStack::PushStack(int nRow, int nColumn, int nDirections,int nLastDirections)
{
    SNode* pNewNode=new SNode;
    pNewNode->nColumn=nColumn;
    pNewNode->nRow=nRow;
    pNewNode->nDirections=nDirections;
    pNewNode->nLastDirections=nLastDirections;
    pNewNode->pNextNode=NULL;

    if(NULL==pNewNode)
    {
        exit(-1);

    }

    pNewNode->pNextNode=m_pCStackTop->pNextNode;
    m_pCStackTop->pNextNode=pNewNode;
    return 0;
}

int CStack::GetTop(int& nRow, int& nColumn, int& nDirections,int nLastDirections)
{
    if(NULL==m_pCStackTop->pNextNode)
    {
        return -1;
    }

    nRow=m_pCStackTop->pNextNode->nRow;
    nColumn=m_pCStackTop->pNextNode->nColumn;
    nDirections=m_pCStackTop->pNextNode->nDirections;
    nLastDirections=m_pCStackTop->pNextNode->nLastDirections;
    return 0;
}

int CStack::PopStack(int &nRow, int &nColumn, int &nDirections, int nLastDirections)
{
    if(NULL==m_pCStackTop->pNextNode)
    {
        return -1;
    }

    nRow=m_pCStackTop->pNextNode->nRow;
    nColumn=m_pCStackTop->pNextNode->nColumn;
    nDirections=m_pCStackTop->pNextNode->nDirections;
    nLastDirections=m_pCStackTop->pNextNode->nLastDirections;

    SNode* pTmpNode=m_pCStackTop->pNextNode;
    m_pCStackTop->pNextNode=pTmpNode->pNextNode;
    delete pTmpNode;
    return 0;
}

int CStack::DisplayStack()
{
    SNode* pTmpNode=m_pCStackTop->pNextNode;
    while((NULL!=pTmpNode))
    {
        cout<<pTmpNode->nColumn<<endl;
        pTmpNode=pTmpNode->pNextNode;
    }
}

bool CStack::IsStackNotEmpty()
{
    if(NULL!=m_pCStackTop->pNextNode)
    {
        return true;
    }

    return false;
}
保存遍历的足迹:
typedef struct node{
    int nRow;
    int nColumn;
    int nUsed;
}node;

void StoreFoot(node* pVisit,int nRow,int nColumn)
{
    node* pTmp=pVisit;
    for(int i=0;i<100;i++)
    {
        if(false==pTmp[i].nUsed)
        {
            pTmp[i].nColumn=nColumn;
            pTmp[i].nRow=nRow;
            pTmp[i].nUsed=true;
            return ;
        }
    }
    cout<<"can not find enough room to search not use"<<endl;
}

bool IsVisit(node* pVisit,int nRow,int nColumn)
{
    node* pTmp=pVisit;
    for(int i=0;i<100;i++)
    {
        if(true==pTmp[i].nUsed)
        {
            if((nRow==pTmp[i].nRow)&&(nColumn==pTmp[i].nColumn))
            {
                return true;
            }
        }
    }
    return false;

}


如下是简单构造的调用:
  int array[6][6]={0};    array[1][1]=1;
    array[1][3]=1;
    array[2][1]=1;
    array[2][2]=1;
    array[2][3]=1;
    array[2][4]=1;
    array[3][2]=1;
    array[4][2]=1;
    array[4][1]=1;
    array[4][3]=1;
    array[4][4]=1;
    array[5][4]=1;
    array[5][5]=1;


    FindMazePath(array,5,4);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章