Struct Grid

Source
pub struct Grid<T> {
    pub cells: Vec<T>,
    pub bounds: Rect,
}
Expand description

The core type of this library. A 2D grid of cell type T.

Fields§

§cells: Vec<T>

Row-major, linear storage of cell data.

§bounds: Rect

Implementations§

Source§

impl<T> Grid<T>

Source

pub fn new(bounds: Rect) -> Self
where T: Default + Clone,

Examples found in repository?
examples/dungeon.rs (line 14)
9fn main() {
10    let rect = Rect::new((64, 64));
11    // The minimum distance a partition can get to the edge of a Rect.
12    let min_size = 8;
13
14    let mut grid = Grid::<LifeState>::new(rect);
15    let room_tree = grid
16        .bounds
17        .bsp(Orientation::Horizontal, &|rect, orientation| {
18            let dimension = match orientation {
19                Orientation::Horizontal => rect.width(),
20                Orientation::Vertical => rect.height(),
21            };
22            let max_size = dimension - min_size;
23            // No valid partitions; any cut would make the leaves too small.
24            if max_size - min_size <= 0 {
25                return None;
26            }
27            let partition = rand::thread_rng().gen_range(min_size..=max_size);
28            Some((partition, orientation.orthogonal()))
29        });
30    let room_bounds = room_tree.leaves();
31    let rooms = room_bounds.iter().flat_map(|room| {
32        shrink_randomly(
33            Rect {
34                bottom: room.bottom + 1,
35                left: room.left + 1,
36                top: room.top,
37                right: room.right,
38            },
39            4,
40        )
41        .iter()
42    });
43
44    // room_tree
45
46    let layers = cluster_layers(rooms.collect());
47    for result in grid.selection_iter_mut(layers.interior.into_iter()) {
48        if let Ok((_coord, cell)) = result {
49            *cell = LifeState::Floor;
50        }
51    }
52    for result in grid.selection_iter_mut(layers.internal_border.into_iter()) {
53        if let Ok((_coord, cell)) = result {
54            *cell = LifeState::Wall;
55        }
56    }
57    println!("{}", grid);
58}
Source

pub fn with_generator<C>(bounds: Rect, generator: impl Fn(C) -> T) -> Self
where C: From<Coord>,

Examples found in repository?
examples/life.rs (lines 24-26)
22    fn random<C: Into<Coord>>(dimensions: C) -> Self {
23        Self {
24            grid: Grid::with_generator(Rect::new(dimensions), |(_x, _y)| {
25                rand::random::<LifeState>()
26            }),
27        }
28    }
Source

pub fn get<C: Into<Coord>>(&self, coord: C) -> Option<&T>

Source

pub fn get_mut<C: Into<Coord>>(&mut self, coord: C) -> Option<&mut T>

Source

pub fn set<C: Into<Coord>>(&mut self, coord: C, value: T) -> bool

Source

pub fn replace<C: Into<Coord>>(&mut self, coord: C, value: T) -> Option<T>

Source

pub fn take<C: Into<Coord>>(&mut self, coord: C) -> Option<T>
where T: Default,

Source

pub fn copy<C1, C2>(&mut self, src: C1, dest: C2) -> bool
where T: Copy, C1: Into<Coord>, C2: Into<Coord>,

Source

pub fn swap<C1, C2>(&mut self, coord1: C1, coord2: C2) -> bool
where C1: Into<Coord>, C2: Into<Coord>,

Swaps the contents of two cells.

Source

pub fn mov(&mut self, src: Coord, dest: Coord) -> Option<T>
where T: Default,

Moves the contents of src into dest, returning the previous contents of dest.

Source

pub fn iter<'a>(&'a self) -> impl Iterator<Item = (Coord, &'a T)>

Returns an iterator over all cells in the grid.

Examples found in repository?
examples/life.rs (line 33)
30    fn step(&mut self) {
31        let neighbor_counts = self
32            .grid
33            .iter()
34            .map(|cell| self.live_neighbor_count(cell.0))
35            // `collect` to release the borrow on `self`.
36            .collect::<Vec<_>>();
37
38        for (cell, neighbor_count) in self.grid.cell_iter_mut().zip(neighbor_counts) {
39            *cell = LifeBoard::compute_state(*cell, neighbor_count)
40        }
41    }
Source

pub fn cell_iter_mut(&mut self) -> impl Iterator<Item = &mut T>

Examples found in repository?
examples/life.rs (line 38)
30    fn step(&mut self) {
31        let neighbor_counts = self
32            .grid
33            .iter()
34            .map(|cell| self.live_neighbor_count(cell.0))
35            // `collect` to release the borrow on `self`.
36            .collect::<Vec<_>>();
37
38        for (cell, neighbor_count) in self.grid.cell_iter_mut().zip(neighbor_counts) {
39            *cell = LifeBoard::compute_state(*cell, neighbor_count)
40        }
41    }
Source

pub fn selection_iter<I>(&self, coords: I) -> SelectionIter<'_, T, I>
where I: Iterator<Item = Coord>,

Returns an iterator over the cells specified by the coords iterator.

Examples found in repository?
examples/life.rs (line 45)
43    fn live_neighbor_count(&self, coord: Coord) -> usize {
44        self.grid
45            .selection_iter(patterns::neighborhood(coord))
46            .filter(|r_cell| {
47                if let Ok(cell) = r_cell {
48                    *cell.1 == LifeState::Alive
49                } else {
50                    false
51                }
52            })
53            .count()
54    }
Source

pub fn selection_iter_mut<I>(&mut self, coords: I) -> SelectionIterMut<'_, T, I>
where I: Iterator<Item = Coord>,

Returns a mutable iterator over the cells specified by the coords iterator.

If there is an attempt to visit a given cell more than once (which would create multiple simultaneous mutable references to the cell), a GridError::AlreadyVisited will be returned in place of the cell contents.

Examples found in repository?
examples/dungeon.rs (line 47)
9fn main() {
10    let rect = Rect::new((64, 64));
11    // The minimum distance a partition can get to the edge of a Rect.
12    let min_size = 8;
13
14    let mut grid = Grid::<LifeState>::new(rect);
15    let room_tree = grid
16        .bounds
17        .bsp(Orientation::Horizontal, &|rect, orientation| {
18            let dimension = match orientation {
19                Orientation::Horizontal => rect.width(),
20                Orientation::Vertical => rect.height(),
21            };
22            let max_size = dimension - min_size;
23            // No valid partitions; any cut would make the leaves too small.
24            if max_size - min_size <= 0 {
25                return None;
26            }
27            let partition = rand::thread_rng().gen_range(min_size..=max_size);
28            Some((partition, orientation.orthogonal()))
29        });
30    let room_bounds = room_tree.leaves();
31    let rooms = room_bounds.iter().flat_map(|room| {
32        shrink_randomly(
33            Rect {
34                bottom: room.bottom + 1,
35                left: room.left + 1,
36                top: room.top,
37                right: room.right,
38            },
39            4,
40        )
41        .iter()
42    });
43
44    // room_tree
45
46    let layers = cluster_layers(rooms.collect());
47    for result in grid.selection_iter_mut(layers.interior.into_iter()) {
48        if let Ok((_coord, cell)) = result {
49            *cell = LifeState::Floor;
50        }
51    }
52    for result in grid.selection_iter_mut(layers.internal_border.into_iter()) {
53        if let Ok((_coord, cell)) = result {
54            *cell = LifeState::Wall;
55        }
56    }
57    println!("{}", grid);
58}
Source

pub fn flood_iter<C: Into<Coord>>( &self, starting_coord: C, predicate: impl Fn(&T) -> bool + 'static, ) -> FloodIter<'_, T>

Returns an iterator beginning from starting_coord and continuing through all recursively adjacent coords that satisfy the predicate. In other words, this iterates through the cells according to a flood fill algorithm.

Since there is no mut version of this iterator (which would require simultaneous mutable and shared references to most of the cells), the resulting iterator can be collected and then passed into Grid::selection_iter_mut to gain access to mutable cell contents.

Trait Implementations§

Source§

impl<T> Display for Grid<T>
where char: From<T>, T: Copy,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Grid<T>

§

impl<T> RefUnwindSafe for Grid<T>
where T: RefUnwindSafe,

§

impl<T> Send for Grid<T>
where T: Send,

§

impl<T> Sync for Grid<T>
where T: Sync,

§

impl<T> Unpin for Grid<T>
where T: Unpin,

§

impl<T> UnwindSafe for Grid<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.