走迷宫——C++ 算法实现

  这两个看了几个不错的走迷宫算法,然后按照自己的方式写了一个实现,代码如下:

MyMazeMap.cpp

 1 #include <iostream>
 2 #include <Windows.h>
 3 #include "MazeMap.h"
 4 #include "Mazer.h"
 5 using namespace std;
 6
 7 const int SUCCESS = 0;
 8
 9 int main()
10 {
11     int map[8][12] = {
12         { WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL },
13         { ROAD, ROAD, ROAD, ROAD, ROAD, WALL, WALL, ROAD, WALL, WALL, ROAD, WALL },
14         { WALL, WALL, WALL, WALL, ROAD, WALL, WALL, ROAD, WALL, WALL, ROAD, WALL },
15         { WALL, WALL, WALL, WALL, ROAD, WALL, WALL, ROAD, WALL, WALL, ROAD, WALL },
16         { WALL, WALL, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, WALL, ROAD, WALL },
17         { WALL, WALL, ROAD, WALL, WALL, ROAD, WALL, WALL, ROAD, ROAD, ROAD, WALL },
18         { WALL, ROAD, ROAD, WALL, WALL, ROAD, WALL, WALL, WALL, WALL, WALL, WALL },
19         { WALL, ROAD, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL }
20     };
21
22     MyMazeMap maze;
23
24     maze.setMazeMap(*map, 8, 12);//创建map的一个迷宫
25
26     maze.setMazeWall(‘*‘);//墙的表示字符
27     maze.drawMap();//控制台显示迷宫
28
29     Faceto faceto;//人进入迷宫的朝向
30     faceto = _up;
31
32     MyMazer mazer(maze);//走迷宫的人的对象
33
34     mazer.setPersonPosition(7, 1);//迷宫入口位置
35     mazer.setPersonSpeed(FAST);//走迷宫的速度设置
36     mazer.setPersonChar(‘T‘);//人的字符表示
37     mazer.start(faceto);//开始走迷宫
38
39     system("pause");
40     return 0;
41 }

MazeMap.h

 1 #ifndef MAZEMAP_H
 2 #define MAZEMAP_H
 3
 4 #include <Windows.h>
 5
 6 #define WALL 1
 7 #define ROAD 0
 8
 9 class MyMazeMap
10 {
11 public:
12     MyMazeMap();
13     MyMazeMap(const MyMazeMap &_mazeMap);
14     ~MyMazeMap();
15     void setMazeMap(int *map,int row, int col);//设置指向地图二维数组的指针
16     void setMazeWall(char _wall);//设置墙壁字符表示
17     void drawMap();//打印地图
18     int **getMap();//获取地图二维数组的指针
19     int getCol();//获得二维数组的列数
20     int getRow();//获得二维数组的行数
21     void setExitPosition(COORD coo);//设置出口位置
22     COORD getExitPosition();//获得出口位置
23
24 private:
25     char m_cWall;//代表墙的字符
26     char m_cRoad;//代表路的字符
27     int m_iMapRow;//二维数组的行数
28     int m_iMapCol;//二维数组的列数
29     int **m_pMap;//指向地图二维数组的指针
30     COORD m_ExitPosition;//迷宫出口坐标
31 };
32
33 #endif

MazeMap.cpp

#include <iostream>
#include "MazeMap.h"

using namespace std;

MyMazeMap::MyMazeMap()
{
    m_cRoad = ‘ ‘;
    m_cWall = ‘ ‘;
    m_iMapCol = 0;
    m_iMapRow = 0;
    m_ExitPosition.X = 0;
    m_ExitPosition.Y = 0;
    m_pMap = NULL;
}

MyMazeMap::MyMazeMap(const MyMazeMap &_mazeMap)
{
    m_cRoad = _mazeMap.m_cRoad;
    m_cWall = _mazeMap.m_cWall;
    m_iMapCol = _mazeMap.m_iMapCol;
    m_iMapRow = _mazeMap.m_iMapRow;
    m_ExitPosition = _mazeMap.m_ExitPosition;
    m_pMap = _mazeMap.m_pMap;
}

MyMazeMap::~MyMazeMap()
{
    //for (int i = 0; i < m_iMapRow; i++)
    //{
    //    delete[]m_pMap[i];
    //    m_pMap[i] = NULL;
    //}
}

void MyMazeMap::setMazeMap(int *map, int row, int col)//设置指向地图二维数组的指针
{
//    m_pMap = map;
    m_iMapCol = col;
    m_iMapRow = row;

    m_pMap = new int*[m_iMapRow];
    for (int i = 0; i < m_iMapRow; i++)
        m_pMap[i] = new int[m_iMapCol];

    int *p = map;
    for (int i = 0; i < m_iMapRow; i++)
    {
        for (int j = 0; j < m_iMapCol; j++)
        {
            m_pMap[i][j] = *p;
            p++;
        }
    }
}

void MyMazeMap::setMazeWall(char _wall)//设置墙壁字符表示
{
    m_cWall = _wall;
}

void MyMazeMap::drawMap()//打印地图
{
    for (int i = 0; i < m_iMapRow; i++)
    {
        for (int j = 0; j < m_iMapCol; j++)
        {
            if (m_pMap[i][j] == WALL)
                cout << m_cWall;
            else
                cout << m_cRoad;
        }
        cout << endl;
    }

}

int **MyMazeMap::getMap()
{
    return m_pMap;
}

int MyMazeMap::getCol()
{
    return m_iMapCol;
}

int MyMazeMap::getRow()
{
    return m_iMapRow;
}

void MyMazeMap::setExitPosition(COORD coo)
{
    m_ExitPosition = coo;
}

COORD MyMazeMap::getExitPosition()//获得出口位置
{
    return m_ExitPosition;
}

Mazer.h

#ifndef MAZER_H
#define MAZER_H

#include <string>
#include <Windows.h>
#include <iostream>
#include "MazeMap.h"

enum Faceto{_up,_down,_left,_right};
enum Speed{LOW,MID,FAST};

class MyMazer
{
public:
    MyMazer();
    MyMazer(MyMazeMap _mazeMap);
    ~MyMazer();
    void setPersonPosition(int x, int y);//人当前位置
    void setPersonSpeed(Speed _speed);//人移动的速度
    void setPersonChar(char person);//表示人的字符
    void start(Faceto _faceto);//游戏开始函数
    void gotoxy(int x, int y);//动画控制
    Faceto turn(Faceto _faceto);//人转向之后的朝向
    int getSteps();//获取步数
    MyMazeMap m_mazeMap;

private:
    char m_cPerson;//表示人的字符
    Faceto m_cFaceto;//表示人的朝向
    COORD m_iNowLocal;//人当前位置
    COORD m_iPreviousLocal;//人的前一个位置
    //int destination[2] = { 0, 0 };
    //int orignPoint[2] = { 0, 0 };
    Speed m_speed;//人的速度
    int m_iSteps;//记录人走了多少步
};

#endif

Mazer.cpp

#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include "Mazer.h"

using namespace std;

MyMazer::MyMazer()
{
    m_cPerson = ‘Y‘;
    m_cFaceto = _up;
    m_speed = LOW;
    m_iNowLocal.X = 0;//行
    m_iNowLocal.Y = 1;//列
    m_iPreviousLocal.X = 0;
    m_iPreviousLocal.Y = 0;
    m_iSteps = 0;
    MyMazeMap m_mazeMap;
    m_mazeMap.getMap();
}

MyMazer::MyMazer(MyMazeMap _mazeMap)
{
    m_cPerson = ‘Y‘;
    m_cFaceto = _up;
    m_speed = LOW;
    m_iNowLocal.X = 0;//行
    m_iNowLocal.Y = 1;//列
    m_iPreviousLocal.X = 0;
    m_iPreviousLocal.Y = 0;
    m_mazeMap = _mazeMap;

    m_mazeMap.getMap();
//    m_mazeMap.getExitPosition();
    //m_mazeMap.detTerpoint(originPoint, destination);
}

MyMazer::~MyMazer()
{

}

void MyMazer::setPersonPosition(int x, int y)//人当前位置
{
    m_iNowLocal.X = x;
    m_iNowLocal.Y = y;
}

int MyMazer::getSteps()//获取步数
{
    return m_iSteps;
}

void MyMazer::setPersonSpeed(Speed _speed)//人移动的速度
{
    m_speed = _speed;
}

void MyMazer::setPersonChar(char person)//表示人的字符
{
    m_cPerson = person;
}

Faceto MyMazer::turn(Faceto _faceto)//人转向之后的朝向   基于右手算法,定义下一步往哪走
{
    m_cFaceto = _faceto;
    if (m_cFaceto == _up)
    {
        if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y + 1] != WALL)//右边界不是墙
        {
            m_cFaceto = _right;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X - 1][m_iNowLocal.Y] != WALL)//上边界不是墙
        {
            m_cFaceto = _up;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y - 1] != WALL)//左边界不是墙
        {
            m_cFaceto = _left;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X + 1][m_iNowLocal.Y] != WALL)//下边界不是墙
        {
            m_cFaceto = _down;
        }
    }
    else if (m_cFaceto == _right)
    {
        if (m_mazeMap.getMap()[m_iNowLocal.X + 1][m_iNowLocal.Y] != WALL)//下边界不是墙
        {
            m_cFaceto = _down;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y + 1] != WALL)//右边界不是墙
        {
            m_cFaceto = _right;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X - 1][m_iNowLocal.Y] != WALL)//上边界不是墙
        {
            m_cFaceto = _up;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y - 1] != WALL)//左边界不是墙
        {
            m_cFaceto = _left;
        }
    }
    else if (m_cFaceto == _down)
    {
        if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y - 1] != WALL)//左边界不是墙
        {
            m_cFaceto = _left;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X + 1][m_iNowLocal.Y] != WALL)//下边界不是墙
        {
            m_cFaceto = _down;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y + 1] != WALL)//右边界不是墙
        {
            m_cFaceto = _right;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X - 1][m_iNowLocal.Y] != WALL)//上边界不是墙
        {
            m_cFaceto = _up;
        }
    }
    else if (m_cFaceto == _left)
    {
        if (m_mazeMap.getMap()[m_iNowLocal.X - 1][m_iNowLocal.Y] != WALL)//上边界不是墙
        {
            m_cFaceto = _up;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y - 1] != WALL)//左边界不是墙
        {
            m_cFaceto = _left;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X + 1][m_iNowLocal.Y] != WALL)//下边界不是墙
        {
            m_cFaceto = _down;
        }
        else if (m_mazeMap.getMap()[m_iNowLocal.X][m_iNowLocal.Y + 1] != WALL)//右边界不是墙
        {
            m_cFaceto = _right;
        }
    }

    return m_cFaceto;
}

void MyMazer::start(Faceto _faceto)//游戏开始函数
{
    char tempcPer = ‘Y‘;
    tempcPer = m_cPerson;
    m_iSteps = 1;

    double speed_num = 0;
    if (m_speed == LOW)
        speed_num = 2;
    else if (m_speed == MID)
        speed_num = 1;
    else if (m_speed == FAST)
        speed_num = 0.5;

    m_cFaceto = _faceto;

    //画第一个点的位置
    setPersonChar(tempcPer);
    gotoxy(m_iNowLocal.Y, m_iNowLocal.X);
    cout << m_cPerson;

    //从二维数组下面的二行输出当前走的步数
    gotoxy(0, m_mazeMap.getRow() + 2);
    cout << "步数统计:" << m_iSteps << endl;
    Sleep(speed_num * 1000);

    while (1)
    {
        m_iPreviousLocal = m_iNowLocal;
        switch (m_cFaceto)
        {
            case 0://_up
            {
                   m_iNowLocal.X = m_iNowLocal.X - 1;
                   break;
            }
            case 1://_down
            {
                       m_iNowLocal.X += 1;
                       break;
            }
            case 2://_left
            {
                       m_iNowLocal.Y = m_iNowLocal.Y - 1;
                       break;
            }
            case 3://_right
            {
                       m_iNowLocal.Y += 1;
                       break;
            }
        }

        m_iSteps++;//记录步长

        //从二维数组下面的二行输出当前走的步数
        gotoxy(0, m_mazeMap.getRow() + 2);
        cout << "步数统计:" << m_iSteps << endl;

        //边界测试,四个边任何一个等于边界值都会退出
        if ((m_iNowLocal.X == 0 || m_iNowLocal.X ==m_mazeMap.getRow()-1 ) || (m_iNowLocal.Y == m_mazeMap.getCol()-1 || (m_iNowLocal.Y == 0)))
        {//判断有没有走到出口的位置,到了,结束循环
            setPersonChar(‘ ‘);
            gotoxy(m_iPreviousLocal.Y, m_iPreviousLocal.X);
            cout << m_cPerson;
            Sleep(0.05 * 1000);
            setPersonChar(tempcPer);
            gotoxy(m_iNowLocal.Y, m_iNowLocal.X);
            cout << m_cPerson;
            Sleep(speed_num * 1000);
            break;
        }

        //当前要走的位置不是出口位置,移动位置,
        m_cFaceto = turn(m_cFaceto);//判断当前位置的下一个位置的方向

        setPersonChar(‘ ‘);
        gotoxy(m_iPreviousLocal.Y, m_iPreviousLocal.X);
        cout << m_cPerson;

        Sleep(0.05 * 1000);

        setPersonChar(tempcPer);
        gotoxy(m_iNowLocal.Y, m_iNowLocal.X);
        cout << m_cPerson;

        //从控制台的第二十行输出当前走的步数
        /*gotoxy(0, m_mazeMap.getRow()+2);
        cout << "步数统计:" << m_iSteps << endl;*/

        Sleep(speed_num * 1000);

    }
    setPersonChar(‘ ‘);
    gotoxy(0, m_mazeMap.getCol());

    cout << endl << endl << endl << endl;
    cout << "走的步数:" << m_iSteps << endl;
    cout << "出口坐标:" << "(" << m_iNowLocal.X << ", " << m_iNowLocal.Y << ")" << endl;
    cout << "Finally the maze!" << endl;

}

void MyMazer::gotoxy(int x, int y)//动画控制
{
    COORD cd;
    cd.X = x;
    cd.Y = y;
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(handle, cd);

}

运行画面:

时间: 2024-10-11 10:20:31

走迷宫——C++ 算法实现的相关文章

Java与算法之(5) - 老鼠走迷宫(深度优先算法)

小老鼠走进了格子迷宫,如何能绕过猫并以最短的路线吃到奶酪呢? 注意只能上下左右移动,不能斜着移动. 在解决迷宫问题上,深度优先算法的思路是沿着一条路一直走,遇到障碍或走出边界再返回尝试别的路径. 首先用一个二维数组来把迷宫"数字化". [java] view plain copy print? int[][] maze = new int[5][4]; 迷宫中每个格子的横纵坐标对应数组的一维和二维索引,例如最左上角的格子是maze[0][0],数组的值表示该格子是否可以通过,0表示可以

c语言-老鼠走迷宫逐步理解

c语言实现老鼠走迷宫 在没有智能手机的时代,不少人玩游戏会玩老鼠走迷宫这样的闯关游戏.每一关有着不同的地图场景,可能还会充斥着各种障碍. 老鼠走迷宫是经典的递回求解的算法题 我们用二维数组表示迷宫场景.其中用2代表迷宫的墙壁,0代表可行通道. 我们用7*7的二维数组具体实现,假定我们设置[1][1]是迷宫入口,[5][5]是迷宫出口. #define M 7 int maze[M][M] = { {2,2,2,2,2,2,2}, {2,0,0,0,0,0,2}, {2,0,2,0,2,0,2},

深度优先算法——走迷宫的实现

深度优先搜索算法(Depth-First-Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止.属于盲目搜索. 深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图

算法:老鼠走迷宫问题

算法:老鼠走迷宫问题(初) [写在前面] 老鼠走迷宫问题的递归实现,是对递归思想的一种应用. [问题描述] 给定一个二维数组,数组中2表示墙壁,0表示通路,由此数组可展示为一个迷宫图.给定入口位置和出口位置,判断之间是否存在通路并显示出走出迷宫的道路. [代码] 对题目的描述部分 int migo[7][7]={ {2, 2, 2, 2, 2, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 0, 2, 0, 2, 0, 2}, {2, 0, 0, 0, 0, 2, 2},

【每天一道算法题】走迷宫

输入描述: 输入包含多组数据. 每组数据包含一个10*10,由“#”和“.”组成的迷宫.其中“#”代表墙:“.”代表通路. 入口在第一行第二列:出口在最后一行第九列. 从任意一个“.”点都能一步走到上下左右四个方向的“.”点. 输出描述: 对应每组数据,输出从入口到出口最短需要几步. 输入例子: #.#########........##........##........##........##........##........##........##........#########.#

golang 实现广度优先算法(走迷宫)

maze.go package main import ( "fmt" "os" ) /** * 广度优先算法 */ /** * 从文件中读取数据 */ func readMaze(filename string) [][]int { file, err := os.Open(filename) if err != nil { panic(err) } var cols, rows int fmt.Fscanf(file, "%d %d", &a

C语言算法之老鼠走迷宫

1.Algorithm Gossip: 老鼠走迷官(一) 说明:老鼠走迷宫是递回求解的基本题型,我们在二维阵列中使用2表示迷宫墙壁,使用1来表 示老鼠的行走路径,试以程式求出由入口至出口的路径. 解法:老鼠的走法有上.左.下.右四个方向,在每前进一格之后就选一个方向前进,无法前 进时退回选择下一个可前进方向,如此在阵列中依序测试四个方向,直到走到出口为止,这是 递回的基本题. 代码: #include<stdio.h> #include<stdlib.h> int migo[7][

走迷宫(深度优先遍历)

●问题描述: 给出一个矩阵,其中0表示通路,1表示墙壁,这样就形成了一个迷宫,要求编写算法求出其中路径. ●递归思路: 编写一个走迷宫函数,传入二位数组的下标,先假设该点位于最终路径上(将0置为3)再探测周围四个点是否可以走通(是否为0),如果可以走通则将该点四周能走通的点作为函数参数传入函数进入递归.若四周均不能走通(都不为0时)则将该点置回0表示该点不是最终路径上的点. 在此思路中递归进入时表示了枚举路径,当发现此条路径走到某处再不能走通时就将路径该点置回0并且递归退出(回溯)寻找下一条可走

老鼠走迷宫(2)输出所有路径(C语言)

需求 有一个迷宫,在迷宫的某个出口放着一块奶酪.将一只老鼠由某个入口处放进去,它必须穿过迷宫,找到奶酪.请找出它的行走路径. STEP 1 题目转化 我们用一个二维数组来表示迷宫,用2表示迷宫的墙壁,用0表示通路. 老鼠每走到一个格子的时候就将该位置的值置为1,表示老鼠的行走路径包括这个格子. STEP 2 编程思路 ⑴这个题目可以用递归方法,只需要最后一步走到迷宫出口所在的格子. ⑵每一步测试上.下.左.右四个方向,选择一个方向前进. STEP 3 要点整理 ⑴输出所有路径的算法与输出单条路径