minor refactoring
This commit is contained in:
parent
61dcadbbba
commit
4c68bb4b6d
@ -14,7 +14,7 @@ int main() {
|
||||
DistanceGrid grid(10, 10);
|
||||
Sidewinder::on(grid);
|
||||
|
||||
auto start = grid.getCellRef(0, 0);
|
||||
auto& start = grid.getCellRef(0, 0);
|
||||
grid.setStart(start);
|
||||
|
||||
// run Dijkstra's algorithm to find farthest cell
|
||||
|
@ -2,26 +2,20 @@
|
||||
|
||||
#include "Grid.h"
|
||||
#include "Cell.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
#include "Utils.h"
|
||||
|
||||
void BinaryTree::on(Grid &grid) {
|
||||
for (auto &cell: grid) {
|
||||
std::vector < Cell * > neighbors;
|
||||
std::vector<std::reference_wrapper<Cell>> neighbors;
|
||||
if (cell.hasNorth()) {
|
||||
neighbors.emplace_back(cell.north);
|
||||
neighbors.emplace_back(*cell.north);
|
||||
}
|
||||
if (cell.hasEast()) {
|
||||
neighbors.emplace_back(cell.east);
|
||||
neighbors.emplace_back(*cell.east);
|
||||
}
|
||||
if (!neighbors.empty()) {
|
||||
std::uniform_int_distribution<std::vector<Cell*>::size_type> dist(0, neighbors.size() - 1);
|
||||
auto index = dist(gen);
|
||||
auto neighbor = neighbors[index];
|
||||
cell.link(*neighbor);
|
||||
auto& neighbor = utils::randomElement(neighbors);
|
||||
cell.link(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
add_library(maze STATIC Cell.cpp Grid.cpp BinaryTree.cpp Sidewinder.cpp Distances.cpp AldousBroder.cpp Wilsons.cpp)
|
||||
add_library(maze STATIC Cell.cpp Grid.cpp BinaryTree.cpp Sidewinder.cpp Distances.cpp AldousBroder.cpp Wilsons.cpp Utils.cpp)
|
||||
target_include_directories(maze PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
@ -9,8 +9,8 @@ class Distances {
|
||||
public:
|
||||
Distances(const Cell& root);
|
||||
[[nodiscard]] int getDistance(const Cell& cell) const;
|
||||
[[nodiscard]] std::vector<std::reference_wrapper<const Cell>> getCells() const;
|
||||
void setDistance(const Cell& cell, int distance);
|
||||
[[nodiscard]] std::vector<std::reference_wrapper<const Cell>> getCells() const;
|
||||
[[nodiscard]] bool contains(const Cell& cell) const;
|
||||
[[nodiscard]] Distances pathTo(const Cell& goal) const;
|
||||
[[nodiscard]] std::tuple<const Cell&, int> max() const;
|
||||
|
@ -79,13 +79,13 @@ std::string Grid::toString() const {
|
||||
for (auto& cell : row) {
|
||||
std::string body = contentsOf(cell);
|
||||
std::string east_boundary_text = "|";
|
||||
if (cell.east && cell.isLinked(*cell.east)) {
|
||||
if (cell.hasEast() && cell.isLinked(*cell.east)) {
|
||||
east_boundary_text = " ";
|
||||
}
|
||||
top += body + east_boundary_text;
|
||||
|
||||
std::string south_boundary_text = "---";
|
||||
if (cell.south && cell.isLinked(*cell.south)) {
|
||||
if (cell.hasSouth() && cell.isLinked(*cell.south)) {
|
||||
south_boundary_text = " ";
|
||||
}
|
||||
bottom += south_boundary_text + "+";
|
||||
|
@ -2,33 +2,21 @@
|
||||
|
||||
#include "Grid.h"
|
||||
#include "Cell.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
|
||||
/* from https://stackoverflow.com/questions/43329352/generating-random-boolean-c */
|
||||
bool randomBool() {
|
||||
static auto bdist = std::uniform_int_distribution<>(0,1);
|
||||
return bdist(gen);
|
||||
}
|
||||
#include "Utils.h"
|
||||
|
||||
void Sidewinder::on(Grid &grid) {
|
||||
for (auto row: grid.byRow()) {
|
||||
std::vector<Cell *> run;
|
||||
std::vector<std::reference_wrapper<Cell>> run;
|
||||
for (auto &cell: row) {
|
||||
run.emplace_back(&cell);
|
||||
bool at_eastern_boundary = !cell.east;
|
||||
bool at_northern_boundary = !cell.north;
|
||||
run.emplace_back(cell);
|
||||
bool at_eastern_boundary = !cell.hasEast();
|
||||
bool at_northern_boundary = !cell.hasNorth();
|
||||
|
||||
bool should_close_out = at_eastern_boundary || (!at_northern_boundary && randomBool());
|
||||
bool should_close_out = at_eastern_boundary || (!at_northern_boundary && utils::randomBool());
|
||||
if (should_close_out) {
|
||||
auto dist = std::uniform_int_distribution<std::vector<Cell *>::size_type>(0, run.size() - 1);
|
||||
auto index = dist(gen);
|
||||
auto &member = run[index];
|
||||
if (member->north) {
|
||||
member->link(*member->north);
|
||||
auto& member = utils::randomElement(run);
|
||||
if (member.hasNorth()) {
|
||||
member.link(*member.north);
|
||||
}
|
||||
run.clear();
|
||||
} else {
|
||||
|
38
src/Utils.cpp
Normal file
38
src/Utils.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "Utils.h"
|
||||
#include "Cell.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
|
||||
namespace utils {
|
||||
|
||||
/* from https://stackoverflow.com/questions/43329352/generating-random-boolean-c */
|
||||
bool randomBool() {
|
||||
static auto bdist = std::uniform_int_distribution<>(0, 1);
|
||||
return bdist(gen);
|
||||
}
|
||||
|
||||
Cell& randomElement(std::vector<std::reference_wrapper<Cell>> &v) {
|
||||
if (v.empty()) {
|
||||
throw std::invalid_argument("vector is empty");
|
||||
}
|
||||
std::uniform_int_distribution<std::vector<Cell>::size_type> dist(0, v.size() - 1);
|
||||
auto index = dist(gen);
|
||||
return v[index];
|
||||
}
|
||||
|
||||
bool containsElement(std::vector<std::reference_wrapper<Cell>> &v, Cell &c) {
|
||||
return std::find_if(v.begin(), v.end(), [&c] (const std::reference_wrapper<Cell> target) {
|
||||
return c == target;
|
||||
}) != v.end();
|
||||
}
|
||||
|
||||
void removeElement(std::vector<std::reference_wrapper<Cell>> &v, Cell &c) {
|
||||
v.erase(std::remove_if(v.begin(), v.end(), [&c] (const std::reference_wrapper<Cell> target) {
|
||||
return c == target;
|
||||
}), v.end());
|
||||
}
|
||||
|
||||
}
|
10
src/Utils.h
Normal file
10
src/Utils.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cell.h"
|
||||
|
||||
namespace utils {
|
||||
bool randomBool();
|
||||
Cell& randomElement(std::vector<std::reference_wrapper<Cell>> &v);
|
||||
bool containsElement(std::vector<std::reference_wrapper<Cell>> &v, Cell &c);
|
||||
void removeElement(std::vector<std::reference_wrapper<Cell>> &v, Cell &c);
|
||||
}
|
@ -1,43 +1,18 @@
|
||||
#include "Wilsons.h"
|
||||
#include "Cell.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
|
||||
Cell& randomElement(std::vector<std::reference_wrapper<Cell>> &v) {
|
||||
if (v.empty()) {
|
||||
throw std::invalid_argument("vector is empty");
|
||||
}
|
||||
std::uniform_int_distribution<std::vector<Cell>::size_type> dist(0, v.size() - 1);
|
||||
auto index = dist(gen);
|
||||
return v[index];
|
||||
}
|
||||
|
||||
bool findCell(std::vector<std::reference_wrapper<Cell>> &v, Cell &c) {
|
||||
return std::find_if(v.begin(), v.end(), [&c] (const std::reference_wrapper<Cell> target) {
|
||||
return c == target;
|
||||
}) != v.end();
|
||||
}
|
||||
|
||||
void removeCell(std::vector<std::reference_wrapper<Cell>> &v, Cell &c) {
|
||||
v.erase(std::remove_if(v.begin(), v.end(), [&c] (const std::reference_wrapper<Cell> target) {
|
||||
return c == target;
|
||||
}), v.end());
|
||||
}
|
||||
#include "Utils.h"
|
||||
|
||||
void Wilsons::on(Grid &grid) {
|
||||
std::vector<std::reference_wrapper<Cell>> unvisited(grid.begin(), grid.end());
|
||||
|
||||
auto& first = randomElement(unvisited);
|
||||
removeCell(unvisited, first);
|
||||
auto& first = utils::randomElement(unvisited);
|
||||
utils::removeElement(unvisited, first);
|
||||
|
||||
while (!unvisited.empty()) {
|
||||
std::vector<std::reference_wrapper<Cell>> path;
|
||||
std::reference_wrapper<Cell> cell = randomElement(unvisited);
|
||||
std::reference_wrapper<Cell> cell = utils::randomElement(unvisited);
|
||||
path.emplace_back(cell);
|
||||
while (findCell(unvisited, cell)) {
|
||||
while (utils::containsElement(unvisited, cell)) {
|
||||
cell = cell.get().randomNeighbor();
|
||||
auto it = std::find_if(path.begin(), path.end(),
|
||||
[&](const std::reference_wrapper<Cell> &i)
|
||||
@ -53,7 +28,7 @@ void Wilsons::on(Grid &grid) {
|
||||
}
|
||||
for (int i = 0; i < path.size() - 1; i++) {
|
||||
path[i].get().link(path[i + 1].get());
|
||||
removeCell(unvisited, path[i]);
|
||||
utils::removeElement(unvisited, path[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user