14 std::function<
bool()> rng
19 const auto is_on_left_border =
x == 0;
20 const auto is_on_right_border =
x == world->
get_width() - 1;
21 const auto is_on_up_border =
y == 0;
22 const auto is_on_down_border =
y == world->
get_height() - 1;
24 #define CHECK_BORDER(b, p) \
27 if( b && border_control.p != BorderSetupRule::random) \
28 { return border_control.p == BorderSetupRule::always_wall; } \
56 if (include_self==
false && x == cx && y == cy)
62 auto contains = [&world](
int xx,
int yy)
64 return world.get_indices().contains_inclusive(xx, yy);
85 const auto xrule =
x < 0 ? outside_rule.
left : outside_rule.
right;
94 nx =
keep_within(world.get_indices().get_range_x(), x);
95 DIE(
"Implement this");
98 nx =
wrap(world.get_indices().get_range_x(), x);
101 DIE(
"Unhandled case");
110 const auto yrule =
y < 0 ? outside_rule.
up : outside_rule.
down;
120 ny =
keep_within(world.get_indices().get_range_y(), y);
121 DIE(
"Implement this");
124 ny =
wrap(world.get_indices().get_range_y(), y);
127 DIE(
"Unhandled case");
157 for (
int y = cy - step;
y <= cy + step;
y += 1)
159 for (
int x = cx - step;
x <= cx + step;
x += 1)
162 if(manhattan_distance > step) {
continue; }
164 walls += count_single_walls
194 auto calc_walls = [&](
int x,
int y)
196 walls += count_single_walls
207 for (
int y = cy - step;
y <= cy + step;
y += 1)
211 for (
int x = cx - step;
x <= cx + step;
x += 1)
233 for (
int y = cy - step;
y <= cy + step;
y += 1)
235 for (
int x = cx - step;
x <= cx + step;
x += 1)
237 walls += count_single_walls
287 (world, outside_rule, cx, cy, step, include_self);
290 (world, outside_rule, cx, cy, step, include_self);
293 (world, outside_rule, cx, cy, step, include_self);
296 DIE(
"Unhandled algorithm");
330 std::function<std::optional<bool>(
bool,
const WallCounter&)> smooth_function
335 world->
set_all([¤t, outside_rule, smooth_function](
int x,
int y)
337 const auto value = current[{
x,
y}];
339 const auto smoothed_wall = smooth_function(value, walls);
340 return smoothed_wall.value_or(value);
348 auto ret = std::vector<vec2i>{};
354 if(world[{
x,
y}] ==
false)
356 ret.emplace_back(
x,
y);
378 auto stack = std::vector<vec2i>{};
379 auto ret = std::vector<vec2i>{};
381 auto add_to_stack = [&](
const vec2i&
p)
383 if(
p.x < 0) {
return; }
385 if(
p.y < 0) {
return; }
391 stack.emplace_back(
p);
395 while(stack.empty() ==
false)
397 const auto p = *stack.rbegin();
399 if(world[
p] ==
true) {
continue; }
404 add_to_stack({
p.x + 1,
p.y});
405 add_to_stack({
p.x - 1,
p.y});
406 add_to_stack({
p.x,
p.y + 1});
407 add_to_stack({
p.x,
p.y - 1});
411 add_to_stack({
p.x + 1,
p.y + 1});
412 add_to_stack({
p.x + 1,
p.y - 1});
413 add_to_stack({
p.x - 1,
p.y + 1});
414 add_to_stack({
p.x - 1,
p.y - 1});
421 std::vector<std::vector<vec2i>>
424 auto ret = std::vector<std::vector<vec2i>>{};
434 for(
const auto block: blocks)
436 if(
visited[block] ==
true) {
continue; }
439 ret.emplace_back(island);
440 for(
const auto& island_block: island)
464 std::optional<BorderSettings> border
467 const bool has_alpha =
468 wall_color.
a < 255 ||
469 space_color.
a < 255 ||
470 (border.has_value() ? border->color.a < 255 :
false)
473 const auto image_width = world.
get_width() * scale;
474 const auto image_height = world.
get_height() * scale;
479 image.setup_with_alpha_support(image_width, image_height);
483 image.setup_no_alpha_support(image_width, image_height);
486 auto get_space_color = [&](
int x,
int y) ->
Rgbai
488 if(border.has_value() ==
false) {
return space_color; }
494 const auto walls = wc.count(1,
false, algorithm);
496 if(walls>0) {
return border->color; }
497 else {
return space_color; }
500 clear(&image, space_color);
506 const auto px =
x * scale;
507 const auto py =
y * scale;
508 const auto color = world[{
x,
y}]
510 : get_space_color(
x,
y)
512 draw_square(&image, color, px, py + scale - 1, scale);
void make_smoother(BoolTable *world, Lrud< OutsideRule > outside_rule, std::function< std::optional< bool >(bool, const WallCounter &)> smooth_function)
void clear(Image *image, const Rgbai &color)
int count_walls_manhattan(const BoolTable &world, Lrud< OutsideRule > outside_rule, int cx, int cy, int step, bool include_self)
void set_white_noise(BoolTable *world, Lrud< BorderSetupRule > border_control, std::function< bool()> rng)
int count_walls_box(const BoolTable &world, Lrud< OutsideRule > outside_rule, int cx, int cy, int step, bool include_self)
std::vector< vec2i > find_flood_fill_items(const BoolTable &world, const vec2i &start, bool allow_diagonals)
std::vector< vec2i > find_empty_blocks(const BoolTable &world)
int count_walls_plus(const BoolTable &world, Lrud< OutsideRule > outside_rule, int cx, int cy, int step, bool include_self)
Image draw(const BoolTable &world, Rgbai wall_color, Rgbai space_color, int scale, std::optional< BorderSettings > border)
std::vector< std::vector< vec2i > > find_empty_regions(const BoolTable &world, bool allow_diagonals)
void draw_square(Image *image, const Rgbai &color, int x, int y, int size)
T keep_within(const Range< T > &range, T value)
constexpr float abs(float r)
T wrap(const Range< T > &range, T value)
BorderSettings(const Rgbai &c)
static Table from_width_height(Idx width, Idx height, T d=T())
WallCounter(const BoolTable &w, Lrud< core::OutsideRule > r, int x, int y)
int count(int step, bool include_self, NeighborhoodAlgorithm algorithm) const
Lrud< core::OutsideRule > outside_rule
#define CHECK_BORDER(b, p)