迷宮的基本實現

#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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章