diff options
Diffstat (limited to 'src/bitmap.rs')
-rw-r--r-- | src/bitmap.rs | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/src/bitmap.rs b/src/bitmap.rs index dc66d73..6aa6b12 100644 --- a/src/bitmap.rs +++ b/src/bitmap.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | collections::HashSet, | ||
2 | convert::{From, Into, TryFrom}, | 3 | convert::{From, Into, TryFrom}, |
3 | ops::{Add, Sub}, | 4 | ops::{Add, Sub}, |
4 | }; | 5 | }; |
@@ -10,7 +11,7 @@ pub struct Pixmap<T> { | |||
10 | pub data: Vec<T>, | 11 | pub data: Vec<T>, |
11 | } | 12 | } |
12 | 13 | ||
13 | #[derive(Copy, Clone, Debug)] | 14 | #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] |
14 | pub struct MapPoint { | 15 | pub struct MapPoint { |
15 | pub x: u32, | 16 | pub x: u32, |
16 | pub y: u32, | 17 | pub y: u32, |
@@ -249,22 +250,26 @@ where | |||
249 | .collect() | 250 | .collect() |
250 | } | 251 | } |
251 | 252 | ||
252 | pub fn flood_fill( | 253 | pub fn flood_fill(&mut self, start: MapPoint, target: T, replacement: T) -> Vec<MapPoint> { |
253 | &mut self, | 254 | let mut queue = vec![start]; |
254 | start: MapPoint, | 255 | let mut area = HashSet::new(); |
255 | target: T, | 256 | loop { |
256 | replacement: T, | 257 | if queue.is_empty() { |
257 | pts: &mut Vec<MapPoint>, | 258 | break area.drain().collect(); |
258 | ) { | 259 | } else { |
259 | if !self.contains(start) || self.get(start) != target || self.get(start) == replacement { | 260 | let last = queue.pop().unwrap(); |
260 | return; | 261 | area.insert(last); |
261 | } else { | 262 | for (x, y) in [(1, 0), (0, 1), (-1, 0), (0, -1)].iter() { |
262 | pts.push(start); | 263 | let dir = MapPoint::try_from((last.x as i64 + x, last.y as i64 + y)); |
263 | self.set(start, replacement); | 264 | if let Ok(pt) = dir { |
264 | for (x, y) in [(1, 0), (0, 1), (-1, 0), (0, -1)].iter() { | 265 | if self.contains(pt) |
265 | let dir = MapPoint::try_from((start.x as i64 - x, start.y as i64 + y)); | 266 | && self.get(pt) == target |
266 | if let Ok(pt) = dir { | 267 | && self.get(pt) != replacement |
267 | self.flood_fill(pt, target, replacement, pts); | 268 | && !area.contains(&pt) |
269 | { | ||
270 | queue.push(pt); | ||
271 | } | ||
272 | } | ||
268 | } | 273 | } |
269 | } | 274 | } |
270 | } | 275 | } |