在C ++中生成随机Maze

时间:2015-10-07 15:09:09

标签: c++ arrays vector dynamic-arrays maze

正如我在标题中所写,我需要生成一些带有一些限制的随机迷宫。我是C ++的新手,我想问一下在C ++中是否有一种有效的实现方式。我想创建一个二维的int数组(每个[x] [y]都有一个WALL,PASSAGE或VISITED。我也想动态创建数组j:创建一个包含80行和30列的迷宫。所以我想创建一个vec [80] [30]。在C语言中很容易使用malloc并且只需要使用内存。

不知道std::vector是否无用,或者是否有其他指示更合适。我想使用二维数组,因为它更清晰,更直观。我知道我可以使用一维数组。

第二个问题是我想生成和AddNodes(addwalls)到迷宫,直到我无法放置更多或我达到限制。所以我不确切知道如何表达这一点。我想把addnode叫到一个迷宫,最初它没有任何墙(“空迷宫”),并开始在墙上放置墙壁。

想法:

Maze maze; 
maze (80,30,50);
...

所以从一个空的80x30迷宫id开始添加随机墙,直到达到极限。我得到一个随机节点,我测试它是否有效(它在极限上并且它还不是墙),然后我将它添加到迷宫中。如果迷宫已连接,我继续使用更多节点。如果不是,我删除节点并继续。如果我达到随机节点的限制无效,那么我就停止了。结果将是一个连接的迷宫与一些随机的墙壁。我忘了提到墙必须是垂直或水平对称的。我需要一些关于一般想法的帮助,因为我知道我必须阅读很多C ++语法,尽管我用Java编写了好几个月。

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

#define PASSAGE 0
#define WALL 1
#define VISITED 2

#define NORTH 0
#define EAST 1
#define WEST 2
#define SOUTH 3


using namespace std;
// PODEMOS definir las direcciones tambien asi...

enum DIRECTION {
  NORTH = 0, EAST = 1, WEST = 2, SOUTH = 3
};

enum TYPE {
  PASSAGE = 0, WALL = 1, VISITED= 2
};

//http://www.cplusplus.com/forum/general/833/

class Maze { 
  private: 

    int nr; // number of rows
    int nc; // number of columns
    int complex; // complexity of the maze: how hard to leave
    vector< vector<int> > vec; //array bidimensional de enteros
    //vector de dos dimensiones
    /*vector<T> elems;     // elements 
     // Create
    vector< vector<int> > vec(4, vector<int>(4));
    // Write
    vec[2][3] = 10;
    // Read
    int a = vec[2][3];*/
  public: 

    void Maze();
    void Maze( int rows, int columns, int hard);
    void PrintMaze();
    void ShowMaze(vec);
    bool isConnected ();
    void explore (Node posicion);
    bool validMove( Node actual);
    Node RandomNode(); // Obtienes un nodo al azar valido
    Node MirrorNode (Node actual); //devuelve el nodo espejo/mirror de un nodo null en otro caso..
    void reverseExplore();
    int getnr();
    int getnc();
    int getComplex();
    void setnr();
    void setnc();
    void setComplex();
    } 
}; 
void Maze::Maze(void) {
         cout <<"No hace naA"<<"\n\n";
}
void Maze::Maze(int rows, int columns, int hard) {

    //Comprobar numer filas y columnas es par/impar y sino salir dando mensaje correspondiente
    /*
    if (nr %2) != 0) {
        fprintf(stderr, "Error: El numero de filas tiene que ser par/impar.\n");
        exit();
        return 101;
    } else if (nc % 2 != 0) {
        fprintf(stderr, "Error: El numero de filas tiene que ser par/impar", nproc);
        MPI_Finalize();
        return 102;
    }

    if (mr < 20 || nc < 10) {
        fprintf(stderr, "Error: El laberinto tiene que tener al menosu unas medidas\n");
        exit();
        return 103;
    }
*/
    nr=rows;
    nc=columns;
    hard=0;
    bool Final=false;
    Node actualNode;
    setupMaze();   //Inicializar laberinto ( todo a 0, poner los  bordes y casilla inicial)

    do {
        actualNode=randomNode();     //Obtengo un nodo aleatorio valido: que no sea pared y este en los limites
        addNode(actualNode); //Añado el nodo al laberinto
        if ( isConnected();) {
            //hard=0; //opcional para contar solo las veces que intenta en el  "mismo intento", ahora al colocar el nodo bien puedes inicializar los intentos a 0.
            cout << "\nInsercion correcta del nodo\n"; // compruebo si el laberinto es conexo o nodo
        }
        else {
            //Si laberinto resultante no es conexo, tengo que deshacer la inserción del nodoactual e incrementar el valor de hard
            deletenode( actualNode);
            hard++; 
        }
    while ( hard <= complex)

}
bool validMove( Node actual )
{
   // return x >= 0 && x < size && y >= 0 && y < size && maze[x][y] != '#';
    return actual.posx >= 0 && actual.posy < nc && actual.posy >= 0 && actual.posy < nr && vec[actual.posx][actual.posy] == 'PASSAGE';
    //FALTA or de la casilla inicial..
}

    bool coordsAreEdge( Node actual)
{
    return actual.getposx== 0 || actual.getposx== nc - 1 || actual.getposy == 0 || actual.getposy == nr - 1;
}
bool coordsAreEdge( int x, int y )
{
    return x== 0 || x== size - 1 || y == 0 || y== size - 1;
}

bool isConnected();
    {
        Nodo inicial;
        inicial.posx=0; ///inicial.setposx=0
        inicial.posy=1;// inicial.setposy=1
        explore(incial);
        // Si todos nodos son VISITED o WALL exceepto casilla inicial entonces connected es true ( hemos podido visitar todos los nodos pasillo)
        //en otro caso nos quedan nodos por visitar por tanto no es conexo
        reverseExplore();
    }

void explore(Nodo nodoPartida)
    {
    //punto de inicio:siempre el mismo o encontrar el primer 0 del vector

    vec[ nodoPartida.posx ][ nodoPartida.posy ] = 'VISITED';
    printMaze( maze );

    for ( int move = direction, count = 0; count < 4; count++, move++, move %=4 )
        { //seria mas facil pienso como arriba hacer un if para cada movimiento y no un for con los 4 movimientos...
            //int nextX; int nextY;
            switch ( move )
                {
                case WEST: nodoPartida.posx++; break;
                case NORTH: nodoPartida.posy++; break; 
                //nextX = x; nextY = y + 1; break;
                case EAST: nodoPartida.posx--; break;
                case SOUTH: nodoPartida.posy--; break;
                default: ;
                }
            if ( validMove( maze, nextX, nextY )) /// esto me mola mucho porque antes de mover como te dije antes verifica que el movimiento sera correcto
            {
                //Recursion move part 1
                mazeTraverse ( maze,  nextX ,  nextY, (move + 3)%4 ); //igual en vez de move se podria llamar de un if en cada direccion total son solo 4 posibilidades
                return;
            }
        }
void setupMaze(void) {

for ( int x = 0; x < nr; x++)
{
    for ( int y = 0; y < nc; y++)
        vec[x][y]='0';
    cout << endl;
}
cout << endl;
cout << "\nHit return to see next move\n";
cin.get();
}

class Node{
     private: 

    int posx; // position x
    int posy; // position y

    public: 

    void Node();
    void Node( int x, int y);
    void PrintNode(Node x);
    void PrintNode(int x, int y);
    int getPosX();
    int getPosY();
    int setPosX();
    int setPosY();
//  bool validMove();
//  int setConplexetConplex();   
}; 

任何想法或帮助都会被贬低。 Node将是一个有两个成员的类:posx和posy。我添加了类节点只是为了更清晰和可读 主要问题: 1 - 如何声明以及哪个指令更适合二维数组迷宫。如果我使用int迷宫[int] [ìnt];似乎是一个C程序。也许制作一个节点数组会更优雅。 2 - 我如何将迷宫的函数称为randomnode,addnode确实是迷宫的构造函数。 3 - 关于此代码的任何其他建议,这是一个粗略的想法。

0 个答案:

没有答案