# Game Grid `game-grid` provides a simple 2D grid that can be used to prototype games. ## Key features: * Easy parsing of string literal to typed 2D grid thanks to a derive macro. * Indexing with a 2D vector struct ex: `Point { x: i32, y: i32 }` instead of always writing the usual `i = y * width + x` * std-like iterators and utilities. ## Description The main struct is `Grid` that implements a grid able to contain values of a user `Cell` type. The user cell can be any type but it works best with enums that implement the `GridCell` trait. The `GridCell` derive macro allows to implement automatically conversions to and from `char`, allowing to convert a grid to an from strings. `Grid` provides access to the cells with 2D indexing with user types that implement the `GridPosition` trait. On top of that `Grid` provides iterators and other utilities. ## Reference Reference documentation can be found on docs.rs: https://docs.rs/game-grid/0.1.0/game_grid/ ## Using the Grid with Bevy IVec2 One of the core features of `game-grid` is to be able to index the grid with 2D vector structs that we use to make games. If you are using this with Bevy, the feature `bevy-ivec2` includes a trait implementation of `game_grid::GridPosition` for `IVec2` that allows to use `IVec2` as index. To use it add this line to you `Cargo.toml`: ``` [dependencies] game-grid = { features = ["bevy-ivec2"] } ``` ## Example ``` use game_grid::*; // A custom Cell type deriving the trait GridCell with associated char literals. #[derive(GridCell, Copy, Clone, Debug, PartialEq, Eq, Default)] enum Cell { // Wall cells are represented by '#'. #[cell('#')] Wall, // Empty cells are represented by both ' ' and '.', the former will be used for display. // A default value can be used by some Grid functionalities. #[cell(' '|'.')] #[default] Empty, #[cell('o')] Food, // It is also possible to provide a range, the actual character can be captured. #[cell('A'..='Z')] Player(char), } // A 2D point struct deriving GridPosition in order to be used as index into the grid. #[derive(GridPosition, PartialEq, Eq, Debug)] struct Point { x: i32, y: i32, } // Create a grid of cells by parsing a string literal. let grid: Grid<Cell> = "#####\n\ #A o#\n\ #####".parse().unwrap(); // Use iter() to iterate over the cells with associated position. let food_position: Point = grid.iter().find(|(_, cell)| *cell == Cell::Food).unwrap().0; assert_eq!(food_position, Point{ x: 3, y: 1 }); // Index into the grid with 2D point type and retrieved the enum value captured during parsing. if let Cell::Player(player_char) = grid[Point::new(1, 1)] { println!("Player id: {player_char}"); } // Print the grid. print!("{grid}"); // outputs: // ##### // #A o# // ##### ```