pub struct Grid { /* private fields */ }
Expand description
Grid
represents the field of Cell
Consists of start: Cell
and end: Cell
fields, alongside with methods implementing
common mathematical operations for safe interactions with cells and other grids
Grid
has two axis: width, and depth:
(0,0) [#] [#] [#] [#] (5,0)
[#] [#] [#] [#] [#] [#]
[#] [#] [#] [#] [#] [#]
[#] [#] [#] [#] [#] [#]
[#] [#] [#] [#] [#] [#]
(0,5) [#] [#] [#] [#] (5,5)
Due to low memory size, Grid
implements Copy
trait, so all methods take self
(copy) as first argument
§Examples
You can create Grid using new(width, depth) or indented(width, depth, indent):
use grid_math::Grid;
let grid = Grid::new(5, 5); // new 5x5 grid, starting at (0,0)
let grid = Grid::indented(5, 5, (1, 2)); // new 5x5 grid, starting at (1,2)
Or use functionality of implemented From
and Into
traits:
use grid_math::{Grid, Cell};
let grid = Grid::from(((1, 2), (5, 6))); // new field where `start` is (1,2), `end` is (5,6)
let grid: Grid = ((1, 2), (5, 6)).into();
//same for (cell, cell):
let grid = Grid::from((Cell::new(1, 2), Cell::new(5, 6)));
let grid: Grid = (Cell::new(1, 2), Cell::new(5, 6)).into();
// backwards:
let (start, end) = grid.into();
assert_eq!((start, end), (Cell::new(1, 2), Cell::new(5, 6)));
let ((w1, d1), (w2, d2)) = grid.into();
assert_eq!(((w1, d1), (w2, d2)), ((1, 2), (5, 6)));
Important:
When creating Grid
from cells, you specify start
and end
cell, not width and depth
This means that if you create grid with start
(1, 2) and end
(5, 6),
this will be 5x5 grid, not 4x4 as you can think (5 - 1 = 4, 6 - 2 = 4)
this is because start
and end
bounds included, they are actual members of grid,
where the start
is the first cell on the grid, and end
is the last cell on grid
To read start
and end
fields, or to calculate other common attributes, use getters:
use grid_math::{Grid, Cell};
let grid = Grid::indented(8, 8, (3, 3)); // 8x8 grid, starting at (3,3)
let (start, end) = (grid.start(), grid.end());
assert_eq!((start, end), (Cell::new(3, 3), Cell::new(10, 10)));
let (width, depth) = (grid.width(), grid.depth());
assert_eq!((width, depth), (8, 8));
let size = grid.size();
assert_eq!(size, 64);
‘Grid’ implements Display
and Debug
trait, so you can easily print it out:
use grid_math::Grid;
let grid = Grid::new(10, 10);
println!("Grid: {grid}"); // Grid: [(0, 0):(9, 9)]
assert_eq!(format!("{grid}"), "[(0, 0):(9, 9)]");
Other advanced operations include interactions with other grids and cells:
Check if cell or subgrid is within grid:
use grid_math::{Grid, Cell};
let grid = Grid::new(10, 10);
let cell = Cell::new(3, 4);
let subgrid = Grid::indented(5, 5, (2, 2));
assert!(subgrid.within(grid));
assert!(cell.within(grid));
Get Cell
from Grid
by relative position:
use grid_math::{Grid, Cell};
let grid = Grid::indented(5, 5, (2, 2));
let member = grid.member(2, 2);
assert_eq!(member, Cell::new(4, 4));
Important:
When creating Grid
, we specify width
and depth
in terms of length
But when we address member of Grid
, we specify width
and depth
in terms of indexes
This means that Grid
with width
5, and start at (0,), will has end
at (4,),
because we have (0,) (1,) (2,) (3,) (4,), which is 5 elements in total
So we used width
5 at Grid
creation and got Grid
with last cell (4,)
But if we use width
5 when indexing member of Grid
, we will get an error, because indexing starts at 0
Get subgrid from Grid
by relative position:
use grid_math::{Grid, Cell};
let grid = Grid::indented(5, 5, (2, 2));
assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
// get subgrid starting at current grid start, with specified width and depth:
let area = grid.area(3, 3);
assert_eq!(format!("{area}"), "[(2, 2):(4, 4)]");
// get subgrid starting at indent from current grid start and specified width and depth:
let slice = grid.slice(3, 3, (1, 1));
assert_eq!(format!("{slice}"), "[(3, 3):(5, 5)]");
Perform some move calculations of Cell
on Grid
:
use grid_math::{Cell, Grid};
let grid = Grid::new(10, 10);
let cell = grid.start(); // get grid's first cell
let next = cell.strict_right(grid, 3); // move to the right by 3, panics if grid bounds overflow occures
assert_eq!(next, Cell::new(3, 0));
let next = cell.saturating_down(grid, 15); // move down by 15, returns grid bound if overflow occures
assert_eq!(next, Cell::new(0, 9));
let next = cell.wrapping_right(grid, 5).strict_left(grid, 2).project_down(grid); // chain of movements
assert_eq!(next, Cell::new(3, 9));
Perform some actually usefull operations, using Iterator
functionality:
use grid_math::{Cell, Grid};
let grid = Grid::new(3, 3);
let grid_string = grid
.rows()
.map(|row| {
row.cells().map(|_| " [#]")
.chain(std::iter::once("\n\n"))
.collect::<String>()
})
.collect::<String>();
assert_eq!(grid_string,
" \
[#] [#] [#]
[#] [#] [#]
[#] [#] [#]
"
);
To get more examples, look at Cell
and Grid
methods documentation.
Implementations§
Source§impl Grid
impl Grid
Sourcepub fn indented(width: u8, depth: u8, indent: (u8, u8)) -> Self
pub fn indented(width: u8, depth: u8, indent: (u8, u8)) -> Self
Creates new Grid
with specified width: u8
and depth: u8
, starting at indent
§Panics
Panics if width
or depth
parameters < 1
§Examples
use grid_math::{Grid, Cell};
let grid = Grid::indented(5, 5, (2, 2));
assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
// use `Cell` as indent:
let cell = Cell::new(2, 2);
let grid = Grid::indented(5, 5, cell.into());
assert_eq!(format!("{grid}"), "[(2, 2):(6, 6)]");
Sourcepub fn within(self, grid: Grid) -> bool
pub fn within(self, grid: Grid) -> bool
Checks if the Grid
is within the another Grid
§Examples
use grid_math::Grid;
let grid = Grid::new(10, 10);
let subgrid = grid.area(5, 5);
assert!(subgrid.within(grid));
let subgrid = Grid::new(10, 12);
assert!(!subgrid.within(grid));
Sourcepub fn within_panic(self, grid: Grid)
pub fn within_panic(self, grid: Grid)
Sourcepub fn member(self, width: u8, depth: u8) -> Cell
pub fn member(self, width: u8, depth: u8) -> Cell
Returns new Cell
by width: u8
and depth: u8
relative to the current Grid
§Panics
Panics if width
or depth
of the requested member exceeds borders of the current Grid
§Examples
use grid_math::{Grid, Cell};
let grid = Grid::indented(5, 5, (2, 2)); // 5x5 grid, starting at (2,2)
let member = grid.member(4, 4);
assert_eq!(member, Cell::new(6, 6));
Sourcepub fn area(self, width: u8, depth: u8) -> Grid
pub fn area(self, width: u8, depth: u8) -> Grid
Returns new Grid
with width: u8
and depth: u8
, which is a subgrid
of current Grid
, starting at current Grid
start
§Panics
Panics if width
or depth
parameters < 1
Panics if width
or depth
of the requested area exceeds borders of the current Grid
§Examples
use grid_math::{Grid, Cell};
let grid = Grid::indented(5, 5, (2, 2)); // 5x5 grid, starting at (2,2)
let area = grid.area(3, 3);
assert_eq!(format!("{area}"), "[(2, 2):(4, 4)]");
Sourcepub fn slice(self, width: u8, depth: u8, indent: (u8, u8)) -> Grid
pub fn slice(self, width: u8, depth: u8, indent: (u8, u8)) -> Grid
Returns new Grid
with width: u8
and depth: u8
, which is a subgrid
of current Grid
, starting at current Grid
start + indent
§Panics
Panics if width
or depth
parameters < 1
Panics if width
or depth
of the requested slice exceeds borders of the current Grid
Panics if indent
of the requested slice exceeds borders of the current Grid
§Examples
use grid_math::{Grid, Cell};
let grid = Grid::new(10, 10);
let slice = grid.slice(3, 3, (2, 2));
assert_eq!(format!("{slice}"), "[(2, 2):(4, 4)]");
// use `Cell` as indent:
let cell = Cell::new(2, 2);
let slice = grid.slice(3, 3, cell.into());
assert_eq!(format!("{slice}"), "[(2, 2):(4, 4)]");
Sourcepub fn start(self) -> Cell
pub fn start(self) -> Cell
Returns start
cell of Grid
§Examples
use grid_math::{Grid, Cell};
let grid = Grid::new(10, 10);
let start = grid.start();
assert_eq!(start, Cell::new(0, 0));
Sourcepub fn end(self) -> Cell
pub fn end(self) -> Cell
Returns end
cell of Grid
§Examples
use grid_math::{Grid, Cell};
let grid = Grid::new(10, 10);
let end = grid.end();
assert_eq!(end, Cell::new(9, 9));
Sourcepub fn width(self) -> u8
pub fn width(self) -> u8
Calculates width
of Grid
§Examples
use grid_math::Grid;
let grid = Grid::new(10, 10);
let width = grid.width();
assert_eq!(width, 10);
Sourcepub fn depth(self) -> u8
pub fn depth(self) -> u8
Calculates depth
of Grid
§Examples
use grid_math::Grid;
let grid = Grid::new(10, 10);
let depth = grid.depth();
assert_eq!(depth, 10);
Sourcepub fn size(self) -> u16
pub fn size(self) -> u16
Calculates size: u16
of Grid
§Examples
use grid_math::Grid;
let grid = Grid::new(10, 10);
let size = grid.size();
assert_eq!(size, 100);
Sourcepub fn cells(self) -> Cells ⓘ
pub fn cells(self) -> Cells ⓘ
Returns Cells
, which is an iterator over every cell of the Grid
§Examples
Get every Cell
on width
and depth
axis:
use grid_math::{Cell, Grid};
let grid = Grid::new(3, 3);
let axis_cells: Vec<Cell> = grid
.cells()
.filter(|cell| {
cell.global_width() == grid.start().global_width() || cell.global_depth() == grid.start().global_depth()
})
.collect();
assert_eq!(axis_cells, vec![
Cell::new(0, 0),
Cell::new(1, 0),
Cell::new(2, 0),
Cell::new(0, 1),
Cell::new(0, 2),
]);
Sourcepub fn rows(self) -> Rows ⓘ
pub fn rows(self) -> Rows ⓘ
Returns Rows
, which is an iterator over every row of the Grid
§Examples
Print out Grid
in custom format:
use grid_math::{Cell, Grid};
let grid = Grid::new(3, 3);
let grid_string = grid
.rows()
.map(|row| {
row.cells().map(|_| " [#]")
.chain(std::iter::once("\n\n"))
.collect::<String>()
})
.collect::<String>();
assert_eq!(grid_string,
" \
[#] [#] [#]
[#] [#] [#]
[#] [#] [#]
"
);
Sourcepub fn columns(self) -> Columns ⓘ
pub fn columns(self) -> Columns ⓘ
Returns Columns
, which is an iterator over every column of the Grid
§Examples
Get every Cell
on the first column of Grid
:
use grid_math::{Cell, Grid};
let grid = Grid::new(3, 3);
let first_column_cells: Vec<Cell> = grid
.columns()
.next()
.unwrap()
.cells()
.collect();
assert_eq!(first_column_cells, vec![
Cell::new(0, 0),
Cell::new(0, 1),
Cell::new(0, 2),
]);