header_utils
Loading...
Searching...
No Matches
square_grid_algorithms.h
1
4
5#pragma once
6
7#include "square_grid.h"
8#include <queue>
9
11{
12 template <typename TILE_DATA, bool RESIZABLE, typename FUNC>
13 void apply_cellular_automata(grid<TILE_DATA, RESIZABLE>& current_iteration, irec2 const& rect, FUNC&& func)
14 {
15 if constexpr (std::invocable<FUNC, TILE_DATA&, std::span<glm::ivec2 const>>)
16 {
17 using iteration_flags = grid<TILE_DATA, RESIZABLE>::iteration_flags;
18 static constexpr enum_flags<iteration_flags> neighbor_iteration_flags = { iteration_flags::only_valid, iteration_flags::diagonals };
19
21
22 std::vector<glm::ivec2> neighbors;
23 current_iteration.for_each_tile_in_rect(rect, [&](glm::ivec2 pos) {
24 neighbors.clear();
25 current_iteration.for_each_neighbor<neighbor_iteration_flags>(pos, [&](glm::ivec2 neighbor_pos) {
26 neighbors.push_back(neighbor_pos);
27 });
28 func(previous_iteration[pos], std::span<glm::ivec2 const>{ neighbors });
29 });
30
32 }
33 else if constexpr (std::invocable<FUNC, TILE_DATA&, std::span<TILE_DATA const* const>>)
34 {
35 apply_cellular_automata(current_iteration, rect, [&, func = std::forward<FUNC>(func)](TILE_DATA& cell, std::span<glm::ivec2 const> neighbors){
36 std::array<TILE_DATA const*, 8> neighbor_cells;
37 for (size_t i = 0; i < neighbors.size(); ++i)
39 func(cell, std::span<TILE_DATA const* const>{&neighbor_cells[0], neighbors.size()});
40 });
41 }
42 else
43 {
44 static_assert(std::is_same_v<TILE_DATA, FUNC>);
45 }
46 }
47
48 template <typename TILE_DATA, bool RESIZABLE, typename FUNC>
49 void apply_cellular_automata(grid<TILE_DATA, RESIZABLE>& current_iteration, FUNC&& func)
50 {
51 apply_cellular_automata(current_iteration, current_iteration.bounds(), std::forward<FUNC>(func));
52 }
53
54
55 template <typename TILE_DATA, bool RESIZABLE, change_tile_callback<TILE_DATA> FLOOD_FUNC, query_tile_callback<TILE_DATA> SHOULD_FLOOD_FUNC>
56 void flood_at(grid<TILE_DATA, RESIZABLE>& grid, glm::ivec2 start, FLOOD_FUNC&& flood, SHOULD_FLOOD_FUNC&& should_flood)
57 {
58 std::queue<glm::ivec2> queue;
59 if (!grid.is_valid(start)) return;
60 if (!should_flood(start, *grid.at(start))) return;
61
62 queue.push(start);
63 while (!queue.empty())
64 {
65 auto n = queue.front();
66 queue.pop();
67
68 auto l = n, r = glm::ivec2{ n.x + 1, n.y };
69
70 while (grid.is_valid(l) && should_flood(l, *grid.at(l)))
71 l.x--;
72 l.x++;
73
74 while (grid.is_valid(r) && should_flood(r, *grid.at(r)))
75 r.x++;
76 r.x--;
77
78 for (int x = l.x; x <= r.x; x++)
79 {
80 glm::ivec2 pos{ x, n.y };
81 flood(pos, *grid.at(pos));
82
83 glm::ivec2 up = { pos.x, pos.y - 1 }, down = { pos.x, pos.y + 1 };
84
85 if (grid.is_valid(up) && should_flood(up, *grid.at(up)))
86 queue.push(up);
87
88 if (grid.is_valid(down) && should_flood(down, *grid.at(down)))
89 queue.push(down);
90 }
91 }
92 }
93
94 template <typename TILE_DATA, bool RESIZABLE, change_tile_callback<TILE_DATA> FLOOD_FUNC>
95 void flood_at(grid<TILE_DATA, RESIZABLE>& grid, glm::ivec2 start, FLOOD_FUNC&& flood)
96 {
97 const auto data_at_start = grid.at(start);
98 flood_at(grid, start, std::forward<FLOOD_FUNC>(flood), [&](glm::ivec2 at, TILE_DATA const& data) { return data == data_at_start; });
99 }
100
101
102 template <typename TILE_DATA, bool RESIZABLE, query_tile_callback<TILE_DATA> SHOULD_FLOOD_FUNC>
103 void flood_at(grid<TILE_DATA, RESIZABLE>& grid, glm::ivec2 start, TILE_DATA const& replace_with, SHOULD_FLOOD_FUNC&& should_flood)
104 {
105 flood_at(grid, start, [&](glm::ivec2 at, TILE_DATA& data) { data = replace_with; }, std::forward<SHOULD_FLOOD_FUNC>(should_flood));
106 }
107
108 template <typename TILE_DATA, bool RESIZABLE>
109 void flood_at(grid<TILE_DATA, RESIZABLE>& grid, glm::ivec2 start, TILE_DATA const& replace_with)
110 {
111 flood_at(grid, start, [&](glm::ivec2 at, TILE_DATA& data) { data = replace_with; });
112 }
113
114}
constexpr auto bit_count
Equal to the number of bits in the type.
Definition bits.h:33
constexpr decltype(auto) at(random_access_range auto &range, std::integral auto index)
Returns a reference to the value at index of range
Definition ranges.h:59