1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
extern crate wfc;
extern crate coord_2d;
use std::collections::HashSet;
use rand::Rng;
use coord_2d::Coord;
use wfc::{ForbidPattern, Wrap, PatternId, ForbidInterface};
use crate::tile_pattern::TilePattern;
pub struct ForceBorderForbid {
pattern_ids: HashSet<PatternId>,
offset: i32,
}
impl ForbidPattern for ForceBorderForbid {
fn forbid<W: Wrap, R: Rng>(&mut self, fi: &mut ForbidInterface<W>, rng: &mut R) {
let output_size = fi.wave_size();
(0..(output_size.width() as i32))
.map(|x| Coord::new(x, output_size.height() as i32 - self.offset as i32))
.chain(
(0..(output_size.width() as i32)).map(|y| {
Coord::new(output_size.width() as i32 - self.offset as i32, y)
}),
)
.for_each(|coord| {
self.pattern_ids.iter().for_each(|&pattern_id| {
fi.forbid_all_patterns_except(coord, pattern_id, rng)
.unwrap();
});
});
}
}
impl ForceBorderForbid {
pub fn new(pattern: &TilePattern, pattern_size: u32) -> ForceBorderForbid{
let input_size = pattern.overlapping_patterns.grid().size();
let bottom_right_offset = pattern_size - (pattern_size / 2);
let id_grid = pattern.overlapping_patterns.id_grid();
let bottom_right_coord = Coord::new(
input_size.width() as i32 - bottom_right_offset as i32,
input_size.height() as i32 - bottom_right_offset as i32,
);
let bottom_right_ids = id_grid
.get_checked(bottom_right_coord)
.iter()
.cloned()
.collect::<HashSet<_>>();
return ForceBorderForbid {
pattern_ids: bottom_right_ids,
offset: bottom_right_offset as i32,
};
}
}