aboutsummaryrefslogtreecommitdiff
path: root/src/game/cell_helper_impl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/cell_helper_impl.hpp')
-rw-r--r--src/game/cell_helper_impl.hpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/game/cell_helper_impl.hpp b/src/game/cell_helper_impl.hpp
new file mode 100644
index 0000000..ebb35aa
--- /dev/null
+++ b/src/game/cell_helper_impl.hpp
@@ -0,0 +1,106 @@
+#pragma once
+
+#include "cell_helper.hpp"
+
+#include "util/algorithm.hpp"
+
+template <typename MatrixElement>
+constexpr auto has_matrix_value(
+ const IMatrix<MatrixElement> &matrix,
+ const MatrixElement &value) noexcept
+{
+ return [&matrix, &value](const Vector2 &pos)
+ {
+ return matrix.get(pos) == value;
+ };
+}
+
+template <typename MatrixElement>
+CellHelper<MatrixElement>::CellHelper(const IMatrix<MatrixElement> &matrix) noexcept
+ : _matrix(matrix)
+{
+}
+
+template <typename MatrixElement>
+auto CellHelper<MatrixElement>::is_cell_dying(const Vector2 &cell_pos) const noexcept
+ -> bool
+{
+ const auto neighbour_cell_positions =
+ container_filter(find_neighbours(cell_pos), has_matrix_value(_matrix, 'x'));
+
+ const auto neighbour_cell_cnt = neighbour_cell_positions.size();
+
+ return neighbour_cell_cnt < 2 || neighbour_cell_cnt >= 4;
+}
+
+template <typename MatrixElement>
+auto CellHelper<MatrixElement>::get_birth_cell_positions(
+ const std::list<Vector2> &cell_positions) const noexcept -> std::list<Vector2>
+{
+ auto all_empty_neighbour_positions = std::list<Vector2>();
+
+ for (const auto &cell_pos : cell_positions)
+ {
+ const std::list<Vector2> empty_neighbour_positions =
+ container_filter(find_neighbours(cell_pos), has_matrix_value(_matrix, ' '));
+
+ all_empty_neighbour_positions.insert(
+ all_empty_neighbour_positions.end(),
+ empty_neighbour_positions.begin(),
+ empty_neighbour_positions.end());
+ }
+
+ // Remove duplicates
+ all_empty_neighbour_positions.sort();
+ all_empty_neighbour_positions.unique();
+
+ auto birth_cell_positions = container_filter(
+ all_empty_neighbour_positions,
+ [this](const Vector2 &cell_pos)
+ {
+ const auto neighbour_cell_positions = container_filter(
+ find_neighbours(cell_pos),
+ has_matrix_value(_matrix, 'x'));
+
+ return neighbour_cell_positions.size() == 3;
+ });
+
+ return birth_cell_positions;
+}
+
+template <typename MatrixElement>
+auto CellHelper<MatrixElement>::find_neighbours(const Vector2 &cell_pos) const noexcept
+ -> std::list<Vector2>
+{
+ std::list<Vector2> cell_positions = {};
+
+ const auto matrix_size =
+ Bounds({.width = _matrix.get_column_cnt(), .height = _matrix.get_row_cnt()});
+
+ const auto neighbours = _get_position_neighbours(cell_pos);
+
+ for (const auto &neighbour_pos : neighbours)
+ {
+ if (matrix_size.validate_coords(neighbour_pos) == CoordsValidation::VALID)
+ {
+ cell_positions.push_back(neighbour_pos);
+ }
+ }
+
+ return cell_positions;
+}
+
+template <typename MatrixElement>
+auto CellHelper<MatrixElement>::_get_position_neighbours(
+ const Vector2 &position) noexcept -> std::list<Vector2>
+{
+ return {
+ position + Vector2::up(),
+ position + Vector2::down(),
+ position + Vector2::left(),
+ position + Vector2::right(),
+ position + Vector2::up() + Vector2::left(),
+ position + Vector2::up() + Vector2::right(),
+ position + Vector2::down() + Vector2::left(),
+ position + Vector2::down() + Vector2::right()};
+}