grafos_tools/
grid.rs

1use crate::adjacency_list::ToAdjacencyList;
2use std::{collections::HashSet, fmt::Debug, hash::Hash};
3
4#[derive(Eq, Hash, PartialEq, Clone, Debug)]
5pub struct Rock(usize, usize);
6
7impl Rock {
8    pub fn x(&self) -> usize {
9        self.0
10    }
11
12    pub fn y(&self) -> usize {
13        self.1
14    }
15
16    pub fn new(x: usize, y: usize) -> Self {
17        Self(x, y)
18    }
19
20    pub fn new_multi(positions: Vec<(usize, usize)>) -> Vec<Rock> {
21        positions
22            .iter()
23            .map(|pos| Rock::new(pos.0, pos.1))
24            .collect()
25    }
26}
27
28pub struct Grid {
29    width: usize,
30    height: usize,
31    rocks: HashSet<Rock>,
32}
33
34impl Grid {
35    pub fn width(&self) -> usize {
36        self.width
37    }
38    pub fn height(&self) -> usize {
39        self.height
40    }
41
42    pub fn new_empty(width: usize, height: usize) -> Self {
43        Self {
44            width,
45            height,
46            ..Default::default()
47        }
48    }
49
50    pub fn new(width: usize, height: usize, rocks: Vec<Rock>) -> Self {
51        let mut grid = Self {
52            width,
53            height,
54            ..Default::default()
55        };
56        let _ = grid.add_rocks(rocks);
57        grid
58    }
59
60    pub fn checked_new(width: usize, height: usize, rocks: Vec<Rock>) -> Result<Self, Vec<Rock>> {
61        let mut grid = Self {
62            width,
63            height,
64            ..Default::default()
65        };
66        let failed = grid.add_rocks(rocks);
67        match failed {
68            None => Ok(grid),
69            Some(failed) => Err(failed),
70        }
71    }
72
73    /**
74        Rocks that cannot be inserted are returned
75    */
76    pub fn add_rocks(&mut self, rocks: Vec<Rock>) -> Option<Vec<Rock>> {
77        let mut failed: Vec<Rock> = Vec::new();
78        for rock in rocks {
79            if rock.x() < self.width() && rock.y() < self.height() {
80                self.rocks.insert(rock);
81            } else {
82                failed.push(rock);
83            }
84        }
85        if failed.len() > 0 {
86            Some(failed)
87        } else {
88            None
89        }
90    }
91
92    pub fn remove_rocks(&mut self, rocks: &Vec<Rock>) {
93        for rock in rocks {
94            self.rocks.remove(rock);
95        }
96    }
97
98    pub fn is_rock(&self, x: usize, y: usize) -> bool {
99        self.rocks.contains(&Rock::new(x, y))
100    }
101
102    pub fn capacity(&self) -> Option<usize> {
103        self.width().checked_mul(self.height())
104    }
105}
106
107impl Default for Grid {
108    fn default() -> Self {
109        Self {
110            width: 10,
111            height: 10,
112            rocks: HashSet::new(),
113        }
114    }
115}
116
117impl<T> ToAdjacencyList<T> for Grid
118where
119    T: PartialOrd + Debug + Eq + Clone + Hash,
120{
121    fn to_adjacency_list(&self) -> crate::adjacency_list::AdjacencyList<T> {
122        todo!();
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129
130    #[test]
131    fn create_grid() {
132        let width = 347;
133        let height = 149;
134        let grid = Grid::new_empty(width, height);
135
136        assert_eq!(width, grid.width());
137        assert_eq!(height, grid.height());
138    }
139
140    #[test]
141    fn create_grid_with_rocks() {
142        let width = 40;
143        let height = 100;
144        let rocks = Rock::new_multi(vec![(1, 0), (2, 0), (3, 0)]);
145        let grid = Grid::new(width, height, rocks.clone());
146        for rock in rocks {
147            assert!(grid.is_rock(rock.x(), rock.y()));
148        }
149    }
150
151    #[test]
152    #[should_panic]
153    fn fail_when_rock_out_of_place() {
154        let width = 1;
155        let height = 1;
156        let rocks = Rock::new_multi(vec![
157            // this one is ok
158            (0, 0),
159            // this one fails
160            (2, 0),
161        ]);
162        Grid::checked_new(width, height, rocks).unwrap();
163    }
164}