迷宫的基本实现

#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;
}

如下是简单构造的调用:
  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);
时间: 2024-11-10 23:15:56

迷宫的基本实现的相关文章

Java小案例-(逃离迷宫)

一,迷宫需求描述: 1,用户输入迷宫图(限制方形):字母1位墙,0为通,e为出口,m为入口,*为已访问的位置,用外围1围住迷宫 2,运行轨迹右,左,下,上 3,判断该迷宫是否能从入口走到出口,并将搜索过程输出 二,迷宫实现: 1,迷宫元素类MazeCell: package smalldemo.maze; class MazeCell { public int x,y; public MazeCell(){ } public MazeCell(int x,int y){ this.x=x; th

洛谷——P1141 01迷宫

https://www.luogu.org/problem/show?pid=1141 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身). 输入输出格式 输入格式: 输入的第1行为两个正整数n,m. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格. 接下来m行,每行2个用空格分隔的正整

NYOJ306 走迷宫(dfs+二分搜索)

题目描述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩,它常常偷偷跑出实验室,在某个游乐场玩之不疲.这天卡多又跑出来了,在SJTL游乐场玩个不停,坐完碰碰车,又玩滑滑梯,这时卡多又走入一个迷宫.整个迷宫是用一个N * N的方阵给出,方阵中单元格中填充了一个整数,表示走到这个位置的难度. 这个迷宫可以向上走,向下走,向右走,向左走,但是不能穿越对角线.走迷宫的取胜规则很有意思,看谁能更快地找到一条路

(hdu step 4.2.7)逃离迷宫(在有转弯次数的限制的情况下,判断一个点是否能到另一个点)

题目: 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 264 Accepted Submission(s): 85   Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍

迷宫探索

/* 5 4 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 4 3 */ #include<iostream> using namespace std; struct node { int x;//横坐标 int y;//纵坐标 int f;//父亲在队列中的编号 int s;//步数 }; int main() { node que[2051]; int a[51][51]={0}; int book[51][51]={0}; //定义一个用于表示走

HDU--1272 小希的迷宫

上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路).小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路.比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8.

FOJ Problem 2256 迷宫

                                                                                                                                                                           Problem 2256 迷宫 Accept: 25    Submit: 52Time Limit: 1500 mSec    Memory Limit :

noip 01迷宫(BFS+记忆化)

题目链接:https://www.luogu.org/problem/show?pid=1141 题意:给出一个仅由数字0与1组成的n×n格迷宫.放0的那一格可以4个方向走到放1那一格,1也是四个方向走到放0的那一格.算上本身的那格.求最多能移动多少格子. 数据比较大,如果直接用bfs搜的话会暴时.所以需要每次搜索完都记录一下. 1 #include <iostream> 2 #include <algorithm> 3 #include <queue> 4 using

P1141 01迷宫

题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身). 输入输出格式 输入格式: 输入的第1行为两个正整数n,m. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格. 接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格. 输出格式

深度优先搜索(迷宫救人最短路径)

1 import java.util.Scanner; 2 3 public class One { 4 //n,m为迷宫的行列范围,p,q是某人迷路所在地点,min用于记录走到终点最小路径的步数 5 public static int n,m,p,q,min=9999; 6 //数组a是迷宫,1代表有障碍物,数组d用于移动方向(右.下.左.上),数组book用于标记当前位置是否在路径中 7 public static int a[][]=new int[51][51],book[][]=new