Grid

Struct Grid 

Source
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

Source

pub fn new(width: u8, depth: u8) -> Self

Creates new Grid with specified width: u8 and depth: u8, starting at (0,0)

§Panics

Panics if width or depth parameters < 1

§Examples
use grid_math::Grid;

let grid = Grid::new(10, 10);
assert_eq!(format!("{grid}"), "[(0, 0):(9, 9)]");
Source

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)]");
Source

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));
Source

pub fn within_panic(self, grid: Grid)

Checks if the Grid is within the another Grid

§Panics

Panics if the Grid is not within the another Grid

§Examples
use grid_math::Grid;

let grid = Grid::new(10, 10);
let subgrid = Grid::new(10, 12);
subgrid.within_panic(grid);
Source

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));
Source

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)]");
Source

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)]");
Source

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));
Source

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));
Source

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);
Source

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);
Source

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);
Source

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),
]);
Source

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,
" \
 [#] [#] [#]

 [#] [#] [#]

 [#] [#] [#]

"
);
Source

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),
]);

Trait Implementations§

Source§

impl Clone for Grid

Source§

fn clone(&self) -> Grid

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Grid

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Display for Grid

Source§

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

implements display for Grid

§Examples
use grid_math::Grid;

let grid = Grid::new(5, 6);
assert_eq!(format!("{grid}"), "[(0, 0):(4, 5)]");
Source§

impl From<((u8, u8), (u8, u8))> for Grid

Source§

fn from(value: ((u8, u8), (u8, u8))) -> Self

implements constructor for Grid from ((u8, u8), (u8, u8))

§Examples
use grid_math::{Cell, Grid};

let vals = ((2, 2), (5, 5));
let grid = Grid::from(vals);
assert_eq!((Cell::from(vals.0), Cell::from(vals.1)), (grid.start(), grid.end()));
Source§

impl From<(Cell, Cell)> for Grid

Source§

fn from(value: (Cell, Cell)) -> Self

implements constructor for Grid from (Cell, Cell)

§Examples
use grid_math::{Cell, Grid};

let cells = (Cell::new(2, 2), Cell::new(5, 5));
let grid = Grid::from(cells);
assert_eq!((cells.0, cells.1), (grid.start(), grid.end()));
Source§

impl From<Grid> for Cells

Source§

fn from(grid: Grid) -> Self

Creates new iterator over every Cell on the Grid

§Examples:
use grid_math::{Grid, Cells};

let grid = Grid::new(5, 5);
let cells = Cells::from(grid);
Source§

impl From<Grid> for Columns

Source§

fn from(grid: Grid) -> Self

Creates new iterator over every column on the Grid

§Examples:
use grid_math::{Grid, Columns};

let grid = Grid::new(5, 5);
let columns = Columns::from(grid);
Source§

impl<V> From<Grid> for GridMap<V>

Source§

fn from(grid: Grid) -> Self

Creates new GridMap from the given Grid with empty HashMap<Cell, V>

§Examples:
use grid_math::{Grid, GridMap};

let grid = Grid::new(5, 5);
let map: GridMap<char> = GridMap::from(grid);
Source§

impl From<Grid> for Rows

Source§

fn from(grid: Grid) -> Self

Creates new iterator over every row on the Grid

§Examples:
use grid_math::{Grid, Rows};

let grid = Grid::new(5, 5);
let rows = Rows::from(grid);
Source§

impl Hash for Grid

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Into<((u8, u8), (u8, u8))> for Grid

Source§

fn into(self) -> ((u8, u8), (u8, u8))

implements conversion from Grid into ((u8, u8), (u8, u8))

§Examples
use grid_math::{Cell, Grid};

let grid = Grid::new(5, 5);
let vals: ((u8, u8), (u8, u8)) = grid.into();
assert_eq!((Cell::from(vals.0), Cell::from(vals.1)), (grid.start(), grid.end()));
Source§

impl Into<(Cell, Cell)> for Grid

Source§

fn into(self) -> (Cell, Cell)

implements conversion from Grid into (Cell, Cell)

§Examples
use grid_math::{Cell, Grid};

let grid = Grid::new(5, 5);
let cells: (Cell, Cell) = grid.into();
assert_eq!((cells.0, cells.1), (grid.start(), grid.end()));
Source§

impl PartialEq for Grid

Source§

fn eq(&self, other: &Grid) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for Grid

Source§

impl Eq for Grid

Source§

impl StructuralPartialEq for Grid

Auto Trait Implementations§

§

impl Freeze for Grid

§

impl RefUnwindSafe for Grid

§

impl Send for Grid

§

impl Sync for Grid

§

impl Unpin for Grid

§

impl UnwindSafe for Grid

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.