aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-02-13 20:54:02 +0100
committerHampusM <hampus@hampusmat.com>2022-02-13 20:54:02 +0100
commit176d6141c87a180b251bacaee656808bad17498b (patch)
tree9d3893014eeb8be293cf8928044925c379739d24 /src
parentb0c265ee3d94921f55266a679d3801a4d2b4505b (diff)
refactor: add random number generation abstraction
Diffstat (limited to 'src')
-rw-r--r--src/maze.hpp5
-rw-r--r--src/maze.tpp30
-rw-r--r--src/mazerator.cpp37
-rw-r--r--src/random_generator.cpp20
-rw-r--r--src/random_generator.hpp34
5 files changed, 99 insertions, 27 deletions
diff --git a/src/maze.hpp b/src/maze.hpp
index e525d70..650e60a 100644
--- a/src/maze.hpp
+++ b/src/maze.hpp
@@ -2,8 +2,8 @@
#include "engine/matrix.hpp"
#include "engine/vector2.hpp"
+#include "random_generator.hpp"
#include <memory>
-#include <random>
#include <string>
/**
@@ -16,6 +16,7 @@
*/
template <typename Element>
void matrix_to_maze(Matrix<Element> *matrix, std::shared_ptr<Vector2> start_pos,
- Element space_element, std::mt19937 random_gen);
+ Element space_element,
+ std::shared_ptr<RandomNumberGenerator> random_gen);
#include "maze.tpp"
diff --git a/src/maze.tpp b/src/maze.tpp
index 19390cc..2edb60d 100644
--- a/src/maze.tpp
+++ b/src/maze.tpp
@@ -22,7 +22,9 @@ std::vector<std::shared_ptr<Vector2>> get_neighbours(Matrix<Element> *matrix,
auto pos_down = (*pos - Vector2(0U, 2U)).copy();
if (matrix->get(*pos_down) != space_element)
+ {
neighbours.push_back(pos_down);
+ }
}
if (pos->y() != matrix->rows() - 2U)
@@ -30,7 +32,9 @@ std::vector<std::shared_ptr<Vector2>> get_neighbours(Matrix<Element> *matrix,
auto pos_up = (*pos + Vector2(0U, 2U)).copy();
if (matrix->get(*pos_up) != space_element)
+ {
neighbours.push_back(pos_up);
+ }
}
if (pos->x() != 1U)
@@ -38,7 +42,9 @@ std::vector<std::shared_ptr<Vector2>> get_neighbours(Matrix<Element> *matrix,
auto pos_left = (*pos - Vector2(2U, 0U)).copy();
if (matrix->get(*pos_left) != space_element)
+ {
neighbours.push_back(pos_left);
+ }
}
if (pos->x() != matrix->columns() - 2U)
@@ -46,7 +52,9 @@ std::vector<std::shared_ptr<Vector2>> get_neighbours(Matrix<Element> *matrix,
auto pos_right = (*pos + Vector2(2U, 0U)).copy();
if (matrix->get(*pos_right) != space_element)
+ {
neighbours.push_back(pos_right);
+ }
}
return neighbours;
@@ -75,14 +83,19 @@ void pos_to_between(std::shared_ptr<Vector2> between_pos, unsigned int coord,
unsigned int away_coord, Vector2 diff)
{
if (away_coord > coord)
+ {
*between_pos += diff;
+ }
else
+ {
*between_pos -= diff;
+ }
}
template <typename Element>
void matrix_to_maze(Matrix<Element> *matrix, std::shared_ptr<Vector2> start_pos,
- Element space_element, std::mt19937 random_gen)
+ Element space_element,
+ std::shared_ptr<RandomNumberGenerator> random_gen)
{
Stack<std::shared_ptr<Vector2>> path_stack(get_maze_size(matrix));
@@ -95,13 +108,14 @@ void matrix_to_maze(Matrix<Element> *matrix, std::shared_ptr<Vector2> start_pos,
matrix->set(*pos, space_element);
- std::vector<std::shared_ptr<Vector2>> neighbours =
- get_neighbours(matrix, pos, space_element);
+ auto neighbours = get_neighbours(matrix, pos, space_element);
if (neighbours.empty())
{
if (visited_pos_cnt == get_maze_size(matrix) - 1U)
+ {
break;
+ }
// Go back a step
path_stack.pop();
@@ -110,18 +124,20 @@ void matrix_to_maze(Matrix<Element> *matrix, std::shared_ptr<Vector2> start_pos,
visited_pos_cnt++;
- auto random_dist = std::uniform_int_distribution<unsigned int>(
- 0U, static_cast<unsigned int>(neighbours.size()) - 1U);
-
- auto next_pos = neighbours[random_dist(random_gen)];
+ auto next_pos = neighbours[random_gen->in_range(
+ 0U, static_cast<unsigned int>(neighbours.size()) - 1U)];
auto between_pos = pos->copy();
if (next_pos->y() != pos->y())
+ {
pos_to_between(between_pos, pos->y(), next_pos->y(), Vector2(0U, 1U));
+ }
if (next_pos->x() != pos->x())
+ {
pos_to_between(between_pos, pos->x(), next_pos->x(), Vector2(1U, 0U));
+ }
matrix->set(*between_pos, space_element);
diff --git a/src/mazerator.cpp b/src/mazerator.cpp
index 33ef1b1..b30124f 100644
--- a/src/mazerator.cpp
+++ b/src/mazerator.cpp
@@ -2,10 +2,10 @@
#include "engine/vector2.hpp"
#include "getopt.h"
#include "maze.hpp"
+#include "random_generator.hpp"
#include "utils.hpp"
#include <iostream>
#include <memory>
-#include <random>
#include <string>
void optarg_error(int arg, std::string error)
@@ -19,11 +19,15 @@ void validate_start_coords(unsigned int start_x, unsigned int start_y, unsigned
unsigned int height)
{
if (start_x >= width)
+ {
throw "The x start coordinate cannot be higher than or equal to the maze's width";
+ }
if (start_y >= height)
+ {
throw "The y start coordinate cannot be higher than or equal to the maze's "
"height";
+ }
}
/**
@@ -40,7 +44,9 @@ void parse_uint_arg(unsigned int *num_dst, int arg, bool check_zero = false)
*num_dst = str_to_uint(std::string(optarg));
if (check_zero && *num_dst == 0)
+ {
throw "It should not be 0";
+ }
}
catch (const char *error)
{
@@ -62,10 +68,10 @@ int main(int argc, char *argv[])
unsigned int maze_width = 40U;
unsigned int maze_height = 20U;
- std::shared_ptr<unsigned int> start_x = nullptr;
- std::shared_ptr<unsigned int> start_y = nullptr;
+ std::unique_ptr<unsigned int> start_x = nullptr;
+ std::unique_ptr<unsigned int> start_y = nullptr;
- std::unique_ptr<std::mt19937> random_gen = nullptr;
+ std::shared_ptr<RandomNumberGenerator> random_gen = nullptr;
std::string wall = "█";
@@ -81,11 +87,11 @@ int main(int argc, char *argv[])
parse_uint_arg(&maze_height, arg, true);
break;
case 'x':
- start_x = std::make_shared<unsigned int>();
+ start_x = std::make_unique<unsigned int>();
parse_uint_arg(start_x.get(), arg);
break;
case 'y':
- start_y = std::make_shared<unsigned int>();
+ start_y = std::make_unique<unsigned int>();
parse_uint_arg(start_y.get(), arg);
break;
case 'W':
@@ -95,7 +101,7 @@ int main(int argc, char *argv[])
unsigned int seed;
parse_uint_arg(&seed, arg, true);
- random_gen = std::make_unique<std::mt19937>(seed);
+ random_gen = std::make_shared<RandomNumberGenerator>(seed);
break;
case 0:
std::cout
@@ -126,24 +132,19 @@ int main(int argc, char *argv[])
if (random_gen == nullptr)
{
- std::random_device random_device;
- random_gen = std::make_unique<std::mt19937>(random_device());
+ random_gen = std::make_shared<RandomNumberGenerator>();
}
if (start_x == nullptr)
{
- auto random_dist =
- std::uniform_int_distribution<unsigned int>(0, maze_width - 1U);
-
- start_x = std::make_unique<unsigned int>(random_dist(*random_gen));
+ start_x =
+ std::make_unique<unsigned int>(random_gen->in_range(0, maze_width - 1U));
}
if (start_y == nullptr)
{
- auto random_dist =
- std::uniform_int_distribution<unsigned int>(0, maze_height - 1U);
-
- start_y = std::make_unique<unsigned int>(random_dist(*random_gen));
+ start_y =
+ std::make_unique<unsigned int>(random_gen->in_range(0, maze_height - 1U));
}
try
@@ -162,7 +163,7 @@ int main(int argc, char *argv[])
auto start_pos = std::make_shared<Vector2>(*start_x * 2U + 1U, *start_y * 2U + 1U);
- matrix_to_maze<std::string>(&matrix, start_pos, " ", *random_gen);
+ matrix_to_maze<std::string>(&matrix, start_pos, " ", random_gen);
matrix.print();
}
diff --git a/src/random_generator.cpp b/src/random_generator.cpp
new file mode 100644
index 0000000..1f17a88
--- /dev/null
+++ b/src/random_generator.cpp
@@ -0,0 +1,20 @@
+#include "random_generator.hpp"
+
+RandomNumberGenerator::RandomNumberGenerator(unsigned int seed)
+{
+ this->_generator = std::make_unique<std::mt19937>(seed);
+}
+
+RandomNumberGenerator::RandomNumberGenerator()
+{
+ std::random_device random_device;
+
+ this->_generator = std::make_unique<std::mt19937>(random_device());
+}
+
+unsigned int RandomNumberGenerator::in_range(unsigned int a, unsigned int b)
+{
+ auto random_distribution = std::uniform_int_distribution<unsigned int>(a, b);
+
+ return random_distribution(*this->_generator);
+}
diff --git a/src/random_generator.hpp b/src/random_generator.hpp
new file mode 100644
index 0000000..a4c1331
--- /dev/null
+++ b/src/random_generator.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <memory>
+#include <random>
+
+/**
+ * Pseudo-random unsigned integer generator.
+ */
+class RandomNumberGenerator
+{
+public:
+ /**
+ * Creates a pseudo-random number generator.
+ *
+ * @param seed A number generation seed
+ */
+ RandomNumberGenerator(unsigned int seed);
+
+ /**
+ * Creates a pesudo-random number generator.
+ */
+ RandomNumberGenerator();
+
+ /**
+ * Generates a number in the range of a to b.
+ *
+ * @param a A number lower than b
+ * @param b A number greater than a
+ */
+ unsigned int in_range(unsigned int a, unsigned int b);
+
+private:
+ std::unique_ptr<std::mt19937> _generator;
+};