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

✨ Add maze order (1 or 0) corresponding to the maze density #101

Merged
merged 4 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
215 changes: 138 additions & 77 deletions crates/map/src/helpers/digger.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ pub impl Digger of DiggerTrait {
/// # Arguments
/// * `width` - The width of the grid
/// * `height` - The height of the grid
/// * `order` - The order of the maze, it must be 0 or 1, the higher the order the less dense
/// the maze will be
/// * `start` - The starting position
/// * `grid` - The original grid
/// * `seed` - The seed to generate the maze
/// # Returns
/// * The grid with the maze to the exit
#[inline]
fn maze(width: u8, height: u8, start: u8, mut grid: felt252, mut seed: felt252) -> felt252 {
fn maze(
width: u8, height: u8, order: u8, start: u8, mut grid: felt252, mut seed: felt252
) -> felt252 {
// [Check] Position is not a corner and is on an edge
Asserter::assert_not_corner(width, height, start);
Asserter::assert_on_edge(width, height, start);
Expand All @@ -39,7 +43,7 @@ pub impl Digger of DiggerTrait {
};
// [Compute] Generate the maze from the exit to the grid
let mut maze = Bitmap::set(0, start);
Mazer::iter(width, height, next, ref grid, ref maze, ref seed);
Mazer::iter(width, height, order, next, ref grid, ref maze, ref seed);
// [Return] The original grid with the maze to the exit
let grid: u256 = grid.into() | maze.into();
grid.try_into().unwrap()
Expand All @@ -49,13 +53,17 @@ pub impl Digger of DiggerTrait {
/// # Arguments
/// * `width` - The width of the grid
/// * `height` - The height of the grid
/// * `order` - The order of the corridor, it must be 0 or 1, the higher the order the less
/// dense the correlated maze will be
/// * `start` - The starting position
/// * `grid` - The original grid
/// * `seed` - The seed to generate the maze
/// # Returns
/// * The grid with the maze to the exit
#[inline]
fn corridor(width: u8, height: u8, start: u8, grid: felt252, mut seed: felt252) -> felt252 {
fn corridor(
width: u8, height: u8, order: u8, start: u8, grid: felt252, mut seed: felt252
) -> felt252 {
// [Check] Position is not a corner and is on an edge
Asserter::assert_not_corner(width, height, start);
Asserter::assert_on_edge(width, height, start);
Expand All @@ -73,7 +81,7 @@ pub impl Digger of DiggerTrait {
// [Compute] Generate the maze from the exit to the grid
let mut maze = Bitmap::set(0, start);
let mut stop = false;
Self::iter(width, height, next, grid, ref stop, ref maze, ref seed);
Self::iter(width, height, order, next, grid, ref stop, ref maze, ref seed);
// [Return] The original grid with the maze to the exit
let grid: u256 = grid.into() | maze.into();
grid.try_into().unwrap()
Expand All @@ -83,6 +91,8 @@ pub impl Digger of DiggerTrait {
/// # Arguments
/// * `width` - The width of the corridor
/// * `height` - The height of the corridor
/// * `order` - The order of the corridor, it must be 0 or 1, the higher the order the less
/// dense the correlated maze will be
/// * `start` - The starting position
/// * `grid` - The original grid
/// * `stop` - The stop criteria
Expand All @@ -92,6 +102,7 @@ pub impl Digger of DiggerTrait {
fn iter(
width: u8,
height: u8,
order: u8,
start: u8,
grid: felt252,
ref stop: bool,
Expand All @@ -110,27 +121,27 @@ pub impl Digger of DiggerTrait {
let mut directions = DirectionTrait::compute_shuffled_directions(seed);
// [Assess] Direction 1
let direction: Direction = DirectionTrait::pop_front(ref directions);
if Self::check(maze, width, height, start, direction, stop) {
if Self::check(maze, width, height, order, start, direction, stop) {
let next = Mazer::next(width, start, direction);
Self::iter(width, height, next, grid, ref stop, ref maze, ref seed);
Self::iter(width, height, order, next, grid, ref stop, ref maze, ref seed);
}
// [Assess] Direction 2
let direction: Direction = DirectionTrait::pop_front(ref directions);
if Self::check(maze, width, height, start, direction, stop) {
if Self::check(maze, width, height, order, start, direction, stop) {
let next = Mazer::next(width, start, direction);
Self::iter(width, height, next, grid, ref stop, ref maze, ref seed);
Self::iter(width, height, order, next, grid, ref stop, ref maze, ref seed);
}
// [Assess] Direction 3
let direction: Direction = DirectionTrait::pop_front(ref directions);
if Self::check(maze, width, height, start, direction, stop) {
if Self::check(maze, width, height, order, start, direction, stop) {
let next = Mazer::next(width, start, direction);
Self::iter(width, height, next, grid, ref stop, ref maze, ref seed);
Self::iter(width, height, order, next, grid, ref stop, ref maze, ref seed);
}
// [Assess] Direction 4
let direction: Direction = DirectionTrait::pop_front(ref directions);
if Self::check(maze, width, height, start, direction, stop) {
if Self::check(maze, width, height, order, start, direction, stop) {
let next = Mazer::next(width, start, direction);
Self::iter(width, height, next, grid, ref stop, ref maze, ref seed);
Self::iter(width, height, order, next, grid, ref stop, ref maze, ref seed);
};
}

Expand All @@ -139,16 +150,24 @@ pub impl Digger of DiggerTrait {
/// * `maze` - The maze
/// * `width` - The width of the maze
/// * `height` - The height of the maze
/// * `order` - The order of the corridor, it must be 0 or 1, the higher the order the less
/// dense the correlated maze will be
/// * `position` - The current position
/// * `direction` - The direction to check
/// * `stop` - The stop criteria
/// # Returns
/// * Whether the position can be visited in the specified direction
#[inline]
fn check(
grid: felt252, width: u8, height: u8, position: u8, direction: Direction, stop: bool
grid: felt252,
width: u8,
height: u8,
order: u8,
position: u8,
direction: Direction,
stop: bool
) -> bool {
!stop && Mazer::check(grid, width, height, position, direction)
!stop && Mazer::check(grid, width, height, order, position, direction)
}
}

Expand All @@ -164,79 +183,121 @@ mod tests {

#[test]
fn test_digger_dig_corridor() {
// Input grid
// 000000000000000000
// 000111111100000000 <-- Start
// 001111111000000000
// 001111101100000000
// 000111111100000000
// 000011110001001000
// 000111110001111100
// 001111111111111110
// 000111101110111110
// 000011111111111110
// 000111111111111110
// 000001111111111110
// 000000111111111110
// 000000000000000000
// Output grid
// 000000000000000000
// 000111111100000111
// 001111111000000100
// 001111101100000110
// 000111111100000010
// 000011110001001010
// 000111110001111110
// 001111111111111110
// 000111101110111110
// 000011111111111110
// 000111111111111110
// 000001111111111110
// 000000111111111110
// 000000000000000000
// Input
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 <-- Start
// 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
// 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
// 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0
// 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0
// 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
// 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// Output
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1
// 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0
// 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0
// 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 1 0
// 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0
// 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
// 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
let width = 18;
let height = 14;
let order = 0;
let mut grid = 0x7F003F800FB001FC003C481F1F0FFFE1EEF83FFE1FFF81FFE03FF80000;
let walk: felt252 = Digger::corridor(width, height, 216, grid, SEED);
let walk: felt252 = Digger::corridor(width, height, order, 216, grid, SEED);
assert_eq!(walk, 0x7F073F810FB061FC083C4A1F1F8FFFE1EEF83FFE1FFF81FFE03FF80000);
}

#[test]
fn test_digger_dig_maze() {
// Input grid
// 000000000000000000
// 000111111100000000 <-- Start
// 001111111000000000
// 001111101100000000
// 000111111100000000
// 000011110001001000
// 000111110001111100
// 001111111111111110
// 000111101110111110
// 000011111111111110
// 000111111111111110
// 000001111111111110
// 000000111111111110
// 000000000000000000
// Output grid
// 000000000000000000
// 000111111101110111
// 001111111011000100
// 001111101101111110
// 000111111100100010
// 000011110001001010
// 000111110001111110
// 001111111111111110
// 000111101110111110
// 000011111111111110
// 000111111111111110
// 000001111111111110
// 000000111111111110
// 000000000000000000
fn test_digger_dig_maze_order_0() {
// Input
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 <-- Start
// 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
// 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
// 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0
// 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0
// 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
// 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// Output
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1
// 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 1 0 0
// 0 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 0 0 1 0 0 0 1 0
// 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 1 0
// 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0
// 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
// 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
let width = 18;
let height = 14;
let order = 0;
let mut grid = 0x7F003F800FB001FC003C481F1F0FFFE1EEF83FFE1FFF81FFE03FF80000;
let walk: felt252 = Digger::maze(width, height, 216, grid, SEED);
let walk: felt252 = Digger::maze(width, height, order, 216, grid, SEED);
assert_eq!(walk, 0x7F773FB10FB7E1FC883C4A1F1F8FFFE1EEF83FFE1FFF81FFE03FF80000);
}

#[test]
fn test_digger_dig_maze_order_1() {
// Input
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 <-- Start
// 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
// 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
// 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0
// 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0
// 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
// 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// Output
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1
// 0 0 1 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0
// 0 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0
// 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 1 0
// 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0
// 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
// 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
let width = 18;
let height = 14;
let order = 1;
let mut grid = 0x7F003F800FB001FC003C481F1F0FFFE1EEF83FFE1FFF81FFE03FF80000;
let walk: felt252 = Digger::maze(width, height, order, 216, grid, SEED);
assert_eq!(walk, 0x7F773F910FB7E1FC083C4A1F1F8FFFE1EEF83FFE1FFF81FFE03FF80000);
}
}
Loading