Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[example] Array example using a grid #74

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ dependencies = [
"dojo",
]

[[package]]
name = "grid_map"
version = "0.0.0"
dependencies = [
"cubit",
"dojo",
"origami",
]

[[package]]
name = "hex_map"
version = "0.0.0"
Expand Down
1 change: 1 addition & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"crates",
"examples/chess",
"examples/hex_map",
"examples/grid_map",
"examples/market",
"examples/matchmaker",
"examples/projectile",
Expand Down
4 changes: 4 additions & 0 deletions crates/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ mod map {
mod hex;
mod types;
}
mod grid {
mod grid;
mod types;
}
}
174 changes: 174 additions & 0 deletions crates/src/map/grid/grid.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
use core::array::ArrayTrait;
use origami::map::grid::{types::{GridTile, Direction, DirectionIntoFelt252}};

trait IGridTile {
fn new(col: u32, row: u32) -> GridTile;
fn neighbor(self: GridTile, direction: Direction) -> GridTile;
fn neighbors(self: GridTile) -> Array<GridTile>;
fn is_neighbor(self: GridTile, other: GridTile) -> bool;
fn tiles_within_range(self: GridTile, range: u32) -> Array<GridTile>;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can use:

#[generate_trait]

to make code cleaner

impl ImplGridTile of IGridTile {
fn new(col: u32, row: u32) -> GridTile {
GridTile { col, row }
}

fn neighbor(self: GridTile, direction: Direction) -> GridTile {
match direction {
Direction::East(()) => GridTile { col: self.col + 1, row: self.row },
Direction::North(()) => GridTile { col: self.col, row: self.row - 1 },
Direction::West(()) => GridTile { col: self.col - 1, row: self.row },
Direction::South(()) => GridTile { col: self.col, row: self.row + 1 },
}
}

fn neighbors(self: GridTile) -> Array<GridTile> {
return array![
self.neighbor(Direction::East(())),
self.neighbor(Direction::North(())),
self.neighbor(Direction::West(())),
self.neighbor(Direction::South(()))
];
}

fn is_neighbor(self: GridTile, other: GridTile) -> bool {
let mut neighbors = self.neighbors();

loop {
if (neighbors.len() == 0) {
break false;
}

let curent_neighbor = neighbors.pop_front().unwrap();

if (curent_neighbor.col == other.col) {
if (curent_neighbor.row == other.row) {
break true;
}
};
}
}

fn tiles_within_range(self: GridTile, range: u32) -> Array<GridTile> {
let mut queue = array![self];
let mut visited = array![self];
let mut moves = 0;

loop {
if moves == range {
break;
}
let mut next_queue = array![];
loop {
if queue.len() == 0 {
break;
}
let tile = queue.pop_front().unwrap();
let mut neighbors = tile.neighbors();

loop {
if neighbors.len() == 0 {
break;
}
let neighbor = neighbors.pop_front().unwrap();
let mut is_visited = false;
let mut index = 0;
let visited_span = visited.span();

loop {
if index == visited_span.len() || is_visited == true {
break;
}
let curr = *visited_span.at(index);
if (curr.col == neighbor.col && curr.row == neighbor.row) {
is_visited = true;
}
index = index + 1;
};
if !is_visited {
next_queue.append(neighbor);
visited.append(neighbor);
}
};
};
queue = next_queue.clone();
moves = moves + 1;
};
return visited;
}
}


// tests ----------------------------------------------------------------------- //

#[cfg(test)]
mod tests {
use super::{IGridTile, ImplGridTile, Direction, GridTile};
#[test]
fn test_row_col() {
let mut grid_tile = ImplGridTile::new(5, 5);

assert(grid_tile.col == 5, 'col should be 5');
assert(grid_tile.row == 5, 'row should be 5');
}


#[test]
fn test_grid_tile_neighbors() {
let mut grid_tile = ImplGridTile::new(5, 5);

let east_neighbor = grid_tile.neighbor(Direction::East(()));

assert(east_neighbor.col == 6, 'col should be 6');
assert(east_neighbor.row == 5, 'row should be 5');

let north_neighbor = grid_tile.neighbor(Direction::North(()));

assert(north_neighbor.col == 5, 'col should be 5');
assert(north_neighbor.row == 4, 'row should be 4');

let west_neighbor = grid_tile.neighbor(Direction::West(()));

assert(west_neighbor.col == 4, 'col should be 4');
assert(west_neighbor.row == 5, 'row should be 5');

let south_neighbor = grid_tile.neighbor(Direction::South(()));

assert(south_neighbor.col == 5, 'col should be 4');
assert(south_neighbor.row == 6, 'row should be 6');
}

#[test]
fn test_is_neighbor() {
let mut grid_tile = ImplGridTile::new(5, 5);

assert(
grid_tile.is_neighbor(GridTile { col: grid_tile.col + 1, row: grid_tile.row }), 'east'
);

assert(
grid_tile.is_neighbor(GridTile { col: grid_tile.col, row: grid_tile.row + 1 }), 'south'
);

assert(
grid_tile.is_neighbor(GridTile { col: grid_tile.col, row: grid_tile.row - 1 }), 'north'
);

assert(
grid_tile.is_neighbor(GridTile { col: grid_tile.col - 1, row: grid_tile.row }), 'west'
);
}

#[test]
fn test_tiles_within_range() {
let grid_tile = ImplGridTile::new(5, 5);
let tiles_range_one = grid_tile.tiles_within_range(1);
let tiles_range_two = grid_tile.tiles_within_range(2);
let tiles_range_three = grid_tile.tiles_within_range(3);
// Including the center tile
assert_eq!(tiles_range_one.len(), 5, "should be 5");
assert_eq!(tiles_range_two.len(), 13, "should be 13");
assert_eq!(tiles_range_three.len(), 25, "should be 25");
}
}
24 changes: 24 additions & 0 deletions crates/src/map/grid/types.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#[derive(Copy, Drop, Serde, Introspect)]
struct GridTile {
col: u32,
row: u32,
}

#[derive(Drop, Copy, Serde)]
enum Direction {
East: (),
North: (),
West: (),
South: (),
}

impl DirectionIntoFelt252 of Into<Direction, felt252> {
fn into(self: Direction) -> felt252 {
match self {
Direction::East => 0,
Direction::North => 1,
Direction::West => 2,
Direction::South => 3,
}
}
}
2 changes: 1 addition & 1 deletion crates/src/map/hex/hex.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ mod tests {

let east_neighbor = hex_tile.neighbor(Direction::East(()));

assert(east_neighbor.col == 6, 'col should be 7');
assert(east_neighbor.col == 6, 'col should be 6');
assert(east_neighbor.row == 5, 'row should be 5');

let north_east_neighbor = hex_tile.neighbor(Direction::NorthEast(()));
Expand Down
10 changes: 10 additions & 0 deletions examples/grid_map/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "grid_map"
version = "0.0.0"
description = "Example Grid Map using Arrays"
homepage = "https://github.com/dojoengine/origami/tree/examples/grid_map"

[dependencies]
cubit.workspace = true
dojo.workspace = true
origami.workspace = true
2 changes: 2 additions & 0 deletions examples/grid_map/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## Grid map using Array

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a brief explanation in the readme

Loading