Facebook
From valva-ro, 1 Month ago, written in C++.
Embed
Download Paste or View Raw
Hits: 42
  1. #include <SFML/Graphics.hpp>
  2. #include <stack>
  3. #include <vector>
  4. #include <random>
  5.  
  6. #include "Cell.hpp"
  7.  
  8. class Maze {
  9.  
  10. private:
  11.     std::vector<std::vector<Cell*>> cells;
  12.     sf::Vector2f size;
  13.     Cell *begin;
  14.     Cell *end;
  15.     Cell *currentCell;
  16.     std::vector<Cell*> stack;
  17.  
  18. public:
  19.     Maze(sf::Vector2f position, sf::Vector2f size, int wallWidth, sf::Vector2f cells, sf::Color backgroundColor, sf::Color wallColor);
  20.     ~Maze();
  21.     void draw(sf::RenderWindow *window);
  22.     sf::Vector2f getSize();
  23.     Cell* getBegin();
  24.     Cell* getEnd();
  25.     Cell* getCell(sf::Vector2f position);
  26.     Cell* getRandomNeighbor(Cell* cell);
  27.     void update();
  28.     void removeWalls(Cell *cell1, Cell *cell2);
  29. };
  30.  
  31. Maze::Maze(sf::Vector2f position, sf::Vector2f size, int wallWidth, sf::Vector2f cells,
  32.            sf::Color backgroundColor, sf::Color wallColor) : size(cells) {
  33.  
  34.     const std::string laptopPath = "../res/textures/laptop.png";
  35.     std::srand(std::time(nullptr));
  36.     sf::Vector2f cellSize = sf::Vector2f(size.x / cells.x, size.y / cells.y);
  37.  
  38.     for(int y = 0; y < cells.y; y++) {
  39.         this->cells.push_back(std::vector<Cell*>());
  40.         for(int x = 0; x < cells.x; x++) {
  41.             sf::Vector2f currentPosition(x * cellSize.x + position.x, y * cellSize.y + position.y);
  42.             Cell *newCell = new Cell(currentPosition, cellSize, x, y, wallWidth, backgroundColor, wallColor);
  43.             this->cells[y].push_back(newCell);
  44.         }
  45.     }
  46.     this->currentCell = this->cells[0][0];
  47.     this->begin = this->cells[0][0];
  48.     this->begin->setBackgroundColor(sf::Color(15,30,10));
  49.     this->end = this->cells[cells.y - 1][cells.x - 1];
  50.     this->end->setTexture(laptopPath);
  51.     this->end->setBackgroundColor(sf::Color::White);
  52.     this->stack.push_back(this->currentCell);
  53. }
  54.  
  55. Maze::~Maze() {
  56.     for(int y = 0; y < cells.size(); y++) {
  57.         for (int x = 0; x < cells[y].size(); ++x) {
  58.             delete cells[y][x];
  59.         }
  60.     }
  61. }
  62.  
  63. void Maze::draw(sf::RenderWindow *window) {
  64.     for(int y = 0; y < this->cells.size(); y++)
  65.         for(int x = 0; x < this->cells[y].size(); x++)
  66.             this->cells[y][x]->draw(window);
  67. }
  68.  
  69. void Maze::update() {
  70.     this->currentCell->isVisited = true;
  71.     Cell *nextCell = this->getRandomNeighbor(this->currentCell);
  72.  
  73.     if (nextCell != nullptr) {
  74.         this->removeWalls(this->currentCell, nextCell);
  75.         this->currentCell = nextCell;
  76.         this->stack.push_back(this->currentCell);
  77.     }
  78.     else {
  79.         if (this->stack.size() > 1) {
  80.             this->stack.pop_back();
  81.             this->currentCell = this->stack[this->stack.size() - 1];
  82.         }
  83.     }
  84. }
  85.  
  86. void Maze::removeWalls(Cell *cell, Cell *neighbor) {
  87.     if (cell->getColumn() == neighbor->getColumn() + 1) {
  88.         cell->removeWalls(LEFT_WALL);
  89.         neighbor->removeWalls(RIGHT_WALL);
  90.     }
  91.     else if (cell->getColumn() == neighbor->getColumn() - 1) {
  92.         cell->removeWalls(RIGHT_WALL);
  93.         neighbor->removeWalls(LEFT_WALL);
  94.     }
  95.     else if (cell->getRow() == neighbor->getRow() + 1) {
  96.         cell->removeWalls(UP_WALL);
  97.         neighbor->removeWalls(DOWN_WALL);
  98.     }
  99.     else  if (cell->getRow() == neighbor->getRow() - 1) {
  100.         cell->removeWalls(DOWN_WALL);
  101.         neighbor->removeWalls(UP_WALL);
  102.     }
  103. }
  104.  
  105. sf::Vector2f Maze::getSize() {
  106.     return this->size;
  107. }
  108.  
  109. Cell* Maze::getBegin() {
  110.     return this->begin;
  111. }
  112.  
  113. Cell* Maze::getEnd() {
  114.     return this->end;
  115. }
  116.  
  117. Cell* Maze::getCell(sf::Vector2f position) {
  118.     if (position.x < 0 || position.y < 0 || position.x >= this->size.x || position.y >= this->size.y)
  119.         return nullptr;
  120.     else
  121.         return this->cells[position.y][position.x];
  122. }
  123.  
  124. Cell* Maze::getRandomNeighbor(Cell* cell) {
  125.  
  126.     int column = cell->getColumn();
  127.     int row = cell->getRow();
  128.     std::vector<Cell*> availableNeighbors;
  129.     Cell *tmpCell;
  130.  
  131.     if (row > 0) {
  132.         tmpCell = this->getCell(sf::Vector2f(column, row - 1));
  133.         if (!tmpCell->isVisited)
  134.             availableNeighbors.push_back(tmpCell);
  135.     }
  136.  
  137.     if (column < this->size.x - 1) {
  138.         tmpCell = this->getCell(sf::Vector2f(column + 1, row));
  139.         if (!tmpCell->isVisited)
  140.             availableNeighbors.push_back(tmpCell);
  141.     }
  142.  
  143.     if (row < this->size.y - 1) {
  144.         tmpCell = this->getCell(sf::Vector2f(column, row + 1));
  145.         if (!tmpCell->isVisited)
  146.             availableNeighbors.push_back(tmpCell);
  147.     }
  148.  
  149.     if (column > 0) {
  150.         tmpCell = this->getCell(sf::Vector2f(column - 1, row));
  151.         if (!tmpCell->isVisited)
  152.             availableNeighbors.push_back(tmpCell);
  153.     }
  154.  
  155.     if (availableNeighbors.size() == 0)
  156.         return nullptr;
  157.     else {
  158.         int random = (int)(std::rand() % availableNeighbors.size());
  159.         return availableNeighbors[random];
  160.     }
  161. }