- #pragma once
- #include <list>
- #include <vector>
- #include "DrawFunctions.h"
- enum DIR
- {
- UP,
- DOWN,
- LEFT,
- RIGHT,
- NRDIR
- };
- static int D2I(DIR dir)
- {
- switch(dir)
- {
- case UP: case RIGHT:
- return -1;
- break;
- case DOWN: case LEFT:
- return 1;
- break;
- default:
- break;
- };
- return 0;
- }
- struct MazeNode
- {
- unsigned int X;
- unsigned int Y;
- bool Open[NRDIR];
- bool Visited;
- MazeNode()
- {
- X = Y = 0;
- Open[UP] = false;
- Open[DOWN] = false;
- Open[LEFT] = false;
- Open[RIGHT] = false;
- Visited = false;
- }
- };
- struct Room
- {
- Room(int x, int y, int w, int h)
- {
- X = x;
- Y = y;
- Width = w;
- Height = h;
- }
- ROOM()
- {
- Width = 1;
- Height = 1;
- X = 0;
- Y = 0;
- }
- int Width;
- int Height;
- int X;
- int Y;
- };
- class Maze
- {
- public:
- Maze(int width, int height, int startx,int starty, bool completeInOneFrame);
- ~Maze();
- void AddRoom(int x, int y, int width, int height);
- int getIndex(int x, int y);
- MazeNode* getMazeNode(int x, int y);
- bool isComplete(){return m_Complete;}
- bool nextIteration();
- void GenerateSurface();
- Surface* getSurface() {return m_Surface;}
- private:
- protected:
- bool m_Complete;
- MazeNode* m_CurrentNode;
- int m_Width;
- int m_Height;
- std::list<MazeNode*> m_Visited;
- std::vector<MazeNode> m_MazeNodes;
- Surface* m_Surface;
- };
Det är även ett litet mål att markera in områden som regioner, där en region är ett antal noder, det ska fungera enligt systemet att man identifierar alla noder med mer än 2 öppna sidor, den markeras som en shared node. Alla noder efter en shared nod läggs i en gemensam lista tills man når en ny shared node. Alla regions med för få antal medlemar läggs till en annan region om det bara är en 2 vägs korsning. Ev lite regler att vissa regions slår ut alla interna väggar och skapar rum. Här är det iaf. Slit den i stycken och klaga. Room gör inget för stunden. Det är bara rakt av kopierat mitt i arbetet men det borde compilera.
Det enda jag fokuserat på är att inte ha minnesläckor, men det finns nog mycket annat dumt kvar där inne.
En stycke maze.h
header
och maze.cpp
- #include "Maze.h"
- int Maze::getIndex(int x, int y)
- {
- return x+y*m_Width;
- }
- Maze::~Maze()
- {
- delete m_Surface;
- }
- MazeNode* Maze::getMazeNode(int x, int y)
- {
- MazeNode* result = NULL;
- if( (x >= 0 && x < m_Width) &&
- (y >= 0 && y < m_Height) )
- {
- result = &m_MazeNodes[getIndex(x,y)];
- }
- return result;
- }
- Maze::Maze(int width, int height, int startx, int starty, bool completeInOneFrame = false)
- {
- m_Complete = completeInOneFrame;
- m_Width = width;
- m_Height = height;
- m_MazeNodes.resize(width*height);
- m_Surface = new Surface((width*2)+1,(height*2)+1);
- clearScreen(m_Surface,rgb(0,0,0));
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- MazeNode* currentNode = getMazeNode(x,y);
- currentNode->X = x;
- currentNode->Y = y;
- currentNode->Visited = false;
- }
- }
- m_CurrentNode = getMazeNode(startx,starty);
- if(completeInOneFrame)
- {
- while(nextIteration());
- }
- }
- bool Maze::nextIteration()
- {
- MazeNode* nextNode = NULL;
- int x = m_CurrentNode->X;
- int y = m_CurrentNode->Y;
- std::vector<MazeNode*> mazenodes;
- MazeNode* currentNode = NULL;
- currentNode = getMazeNode(x+D2I(LEFT),y);
- if(currentNode)
- {
- if(!currentNode->Visited)
- {
- mazenodes.push_back(currentNode);
- }
- }
- currentNode = getMazeNode(x+D2I(RIGHT),y);
- if(currentNode)
- {
- if(!currentNode->Visited)
- {
- mazenodes.push_back(currentNode);
- }
- }
- currentNode = getMazeNode(x,y+D2I(UP));
- if(currentNode)
- {
- if(!currentNode->Visited)
- {
- mazenodes.push_back(currentNode);
- }
- }
- currentNode = getMazeNode(x,y+D2I(DOWN));
- if(currentNode)
- {
- if(!currentNode->Visited)
- {
- mazenodes.push_back(currentNode);
- }
- }
- if(mazenodes.size())
- {
- MazeNode* targetNode = mazenodes[rand()%mazenodes.size()];
- m_Visited.push_back(m_CurrentNode);
- if(m_CurrentNode->X > targetNode->X)
- {
- m_CurrentNode->Open[RIGHT]= true;
- }
- if(m_CurrentNode->Y < targetNode->Y)
- {
- m_CurrentNode->Open[DOWN]= true;
- }
- if(m_CurrentNode->X < targetNode->X)
- {
- m_CurrentNode->Open[LEFT]= true;
- }
- if(m_CurrentNode->Y > targetNode->Y)
- {
- m_CurrentNode->Open[UP]= true;
- }
- m_CurrentNode = targetNode;
- m_CurrentNode->Visited = true;
- }
- else
- {
- if(m_Visited.size())
- {
- if(m_Visited.back())
- {
- m_CurrentNode = m_Visited.back();
- }
- m_Visited.pop_back();
- }
- else
- {
- m_Complete = true;
- }
- }
- return m_Complete;
- }
- void Maze::GenerateSurface()
- {
- if(!m_Surface)
- {
- return;
- }
- for(int y = 0; y < m_Height; y++)
- {
- for(int x = 0; x < m_Width; x++)
- {
- MazeNode* currentNode = getMazeNode(x,y);
- int targetX = x*2;
- int targetY = y*2;
- int white = rgb(255,255,255);
- putPixel(m_Surface,targetX,targetY,white);
- if(currentNode->Open[UP])
- {
- putPixel(m_Surface,targetX,targetY+D2I(UP),white);
- }
- if(currentNode->Open[DOWN])
- {
- putPixel(m_Surface,targetX,targetY+D2I(DOWN),white);
- }
- if(currentNode->Open[LEFT])
- {
- putPixel(m_Surface,targetX+D2I(LEFT),targetY,white);
- }
- if(currentNode->Open[RIGHT])
- {
- putPixel(m_Surface,targetX+D2I(RIGHT),targetY,white);
- }
- }
- }
- for(std::list<MazeNode*>::iterator iter = m_Visited.begin(); iter != m_Visited.end(); iter++)
- {
- MazeNode* currentNode = *iter;
- putPixel(m_Surface,currentNode->X*2,currentNode->Y*2,rgb(0,255,0));
- }
- };

