22 if constexpr (std::invocable<FUNC, TILE_DATA&, std::span<glm::ivec2 const>>)
24 using iteration_flags = grid<TILE_DATA, RESIZABLE>::iteration_flags;
25 static constexpr enum_flags<iteration_flags> neighbor_iteration_flags = { iteration_flags::only_valid, iteration_flags::diagonals };
29 std::vector<glm::ivec2> neighbors;
32 current_iteration.
for_each_neighbor<neighbor_iteration_flags>(pos, op::push_back_to(neighbors));
33 func(previous_iteration[pos], std::span<glm::ivec2 const>{ neighbors });
36 std::swap(current_iteration, previous_iteration);
38 else if constexpr (std::invocable<FUNC, TILE_DATA&, std::span<TILE_DATA const* const>>)
40 apply_cellular_automata(current_iteration, rect, [&, func = std::forward<FUNC>(func)](TILE_DATA& cell, std::span<glm::ivec2 const> neighbors){
41 std::array<TILE_DATA const*, 8> neighbor_cells;
42 for (
size_t i = 0; i < neighbors.size(); ++i)
43 neighbor_cells[i] = ¤t_iteration[neighbors[i]];
44 func(cell, std::span<TILE_DATA const* const>{&neighbor_cells[0], neighbors.size()});
49 static_assert(std::is_same_v<TILE_DATA, FUNC>);
68 template <
typename TILE_DATA,
bool RESIZABLE, change_tile_callback<TILE_DATA> REPLACE_FUNC, query_tile_callback<TILE_DATA> SHOULD_FLOOD_FUNC>
71 if (!
grid.is_valid(start))
return;
72 if (!
grid.
apply(start, should_flood))
return;
75 if (
grid.
apply(start, should_flood))
return;
77 std::queue<glm::ivec2> queue;
79 while (!queue.empty())
81 auto n = queue.front();
84 auto l = n, r = glm::ivec2{ n.x + 1, n.y };
102 bool span_added =
false;
103 for (
int x = l.x; x <= r.x; x++)
105 glm::ivec2 up = { x, n.y - 1 };
118 if (n.y + 1 <
grid.height())
120 bool span_added =
false;
121 for (
int x = l.x; x <= r.x; x++)
123 glm::ivec2 down = { x, n.y + 1 };
147 static_assert(std::equality_comparable<TILE_DATA>,
"To use this flood fill algorithm, tile data in this grid must be comparable using operator==");
148 const auto* data_at_start =
grid.at(start);
149 flood_at(
grid, start, std::forward<REPLACE_FUNC>(replace), [data_at_start](glm::ivec2
at, TILE_DATA
const& data) {
return data == *data_at_start; });
159 static_assert(std::is_copy_assignable_v<TILE_DATA>,
"To use this flood fill algorithm, tile data in this grid must be copy-assignable");
160 flood_at(
grid, start, [&](glm::ivec2
at, TILE_DATA& data) { data = replace_with; }, std::forward<SHOULD_FLOOD_FUNC>(should_flood));
void flood_at(grid< TILE_DATA, RESIZABLE > &grid, glm::ivec2 start, REPLACE_FUNC &&replace, SHOULD_FLOOD_FUNC &&should_flood)
Performs a flood-fill algorithm on grid.