diff options
Diffstat (limited to 'src/game/cell_helper_impl.hpp')
-rw-r--r-- | src/game/cell_helper_impl.hpp | 121 |
1 files changed, 63 insertions, 58 deletions
diff --git a/src/game/cell_helper_impl.hpp b/src/game/cell_helper_impl.hpp index bd40794..c03b80c 100644 --- a/src/game/cell_helper_impl.hpp +++ b/src/game/cell_helper_impl.hpp @@ -2,18 +2,15 @@ #include "cell_helper.hpp" -#include "util/algorithm.hpp" - -template <typename MatrixElement> -constexpr auto has_matrix_value( - const std::shared_ptr<IMatrix<MatrixElement>> &matrix, - const MatrixElement &value) noexcept -{ - return [&matrix, &value](const Vector2 &pos) - { - return matrix->get(pos) == value; - }; -} +#include <memory> +#include <range/v3/action/insert.hpp> +#include <range/v3/action/sort.hpp> +#include <range/v3/action/unique.hpp> +#include <range/v3/algorithm/count_if.hpp> +#include <range/v3/algorithm/fold_left.hpp> +#include <range/v3/range/conversion.hpp> +#include <range/v3/view/filter.hpp> +#include <utility> template <typename MatrixElement> CellHelper<MatrixElement>::CellHelper( @@ -26,74 +23,82 @@ 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(); + int64_t neighbour_cell_cnt = ranges::count_if( + find_neighbours(cell_pos), + [this](const Vector2 &pos) + { + return _matrix->get(pos) == 'x'; + }); 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> + const std::vector<Vector2> &cell_positions) const noexcept -> std::vector<Vector2> { - auto all_empty_neighbour_positions = std::list<Vector2>(); - - for (const auto &cell_pos : cell_positions) - { - const std::vector<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; + std::vector<Vector2> empty_neighbour_positions = + ranges::fold_left( + cell_positions, + std::vector<Vector2>(), + [this](std::vector<Vector2> acc, const Vector2 &pos) + { + std::vector<Vector2> neighbours = find_neighbours(pos); + + auto empty_neighbours = + neighbours | ranges::views::filter( + [this](const Vector2 &neighbour_pos) + { + return _matrix->get(neighbour_pos) == ' '; + }); + + ranges::actions::insert(acc, acc.end(), empty_neighbours); + + return acc; + }) | + ranges::actions::sort | ranges::actions::unique; + + auto birth_cell_positions = empty_neighbour_positions | + ranges::views::filter( + [this](const Vector2 &cell_pos) + { + auto neighbours = find_neighbours(cell_pos); + + int64_t neighbour_cell_cnt = ranges::count_if( + neighbours, + [this](const Vector2 &neighbour_pos) + { + return _matrix->get(neighbour_pos) == 'x'; + }); + + return neighbour_cell_cnt == 3; + }); + + return birth_cell_positions | ranges::to<std::vector>(); } template <typename MatrixElement> auto CellHelper<MatrixElement>::find_neighbours(const Vector2 &cell_pos) const noexcept -> std::vector<Vector2> { - std::vector<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; + return neighbours | + ranges::views::filter( + [&matrix_size](const Vector2 &neighbour_pos) + { + return matrix_size.validate_coords(neighbour_pos) == + CoordsValidation::VALID; + }) | + ranges::to<std::vector>(); } template <typename MatrixElement> auto CellHelper<MatrixElement>::_get_position_neighbours(const Vector2 &position) noexcept - -> std::list<Vector2> + -> std::vector<Vector2> { return { position + Vector2::up(), |