diff --git a/frontend/src/Algorithms/AStar.jsx b/frontend/src/Algorithms/AStar.jsx new file mode 100644 index 0000000..4ad3369 --- /dev/null +++ b/frontend/src/Algorithms/AStar.jsx @@ -0,0 +1,88 @@ +import { getNeighbors } from "./algoFunctions.jsx"; + + +import { RpcProvider, shortString, Contract, cairo, CallData } from "starknet"; + +async function a_star(grid, startCell, endCell) { + + const height = grid.length; + const witdh = grid[0].length; + + let tiles = []; + for (let col = 0; col < grid.length; col++) { + for (let row = 0; row < grid[col].length; row++) { + const tile = {id: row * witdh + col, x: col, y: row, is_walkable: !grid[col][row].wall}; + tiles.push(tile); + } + } + + const provider = new RpcProvider({ nodeUrl: "https://starknet-sepolia.public.blastapi.io/rpc/v0_6" }); // only for starknet-devnet-rs + + const JPSClassAt = await provider.getClassAt("0x07921148721b727726ff737f9c65e411c730ab7dd9667f323dd449067daa0c8f"); + + const jpsContract = new Contract(JPSClassAt.abi, "0x07921148721b727726ff737f9c65e411c730ab7dd9667f323dd449067daa0c8f", provider); + const callData = new CallData(JPSClassAt.abi); + + const myCallData = callData.compile("a_star", { + tiles: tiles, + map_width: witdh, + map_height: height, + start: cairo.tuple(startCell.col, startCell.row), + goal: cairo.tuple( endCell.col, endCell.row) + }); + + let path; + try { + path = await jpsContract.call("jps", myCallData); + } catch(error) { + throw new Error('Contract error: No remaining steps available.'); + } + + console.log("path", path); + if (path.length == 0) { + throw new Error('Could not find a valid path on the provided map.'); + } + + const parsedJumpPoints = []; + path.forEach(obj => { + const col = cairo.uint256(obj[0]); + const row = cairo.uint256(obj[1]); + const cell = { + row: row.low, + col: col.low, + start: false, + end: false, + jumpPoint: true + }; + parsedJumpPoints.push(cell); + }); + + // Completa el camino con los puntos intermedios + const completedPath = []; + for (let i = 0; i < parsedJumpPoints.length - 1; i++) { + const currentCell = parsedJumpPoints[i] ; + const nextCell = parsedJumpPoints[i + 1]; + + // Agrega el punto actual al camino completado + completedPath.push(currentCell); + + // Calcula los puntos intermedios en lĂ­nea recta entre las celdas actual y siguiente + const deltaX = nextCell.col - currentCell.col; + const deltaY = nextCell.row - currentCell.row; + const distance = Math.max(Math.abs(deltaX), Math.abs(deltaY)); + + for (let j = 1; j < distance; j++) { + const col = parseInt(currentCell.col, 10); + const row = parseInt(currentCell.row, 10); + + const x = Math.floor(col + deltaX * (j / distance)).toString(); + const y = Math.floor(row + deltaY * (j / distance)).toString(); + completedPath.push({ col: x, row: y, start: false, end: false, jumpPoint: false }); + } + } + // Agrega la celda final al camino compSletado + completedPath.push(parsedJumpPoints[parsedJumpPoints.length - 1]); + return completedPath; +} + +export default a_star; diff --git a/frontend/src/Algorithms/JPS.jsx b/frontend/src/Algorithms/JPS.jsx index 4a7c11c..679895d 100644 --- a/frontend/src/Algorithms/JPS.jsx +++ b/frontend/src/Algorithms/JPS.jsx @@ -16,11 +16,11 @@ async function jps(grid, startCell, endCell) { } } - const provider = new RpcProvider({ nodeUrl: "https://starknet-testnet.public.blastapi.io" }); // only for starknet-devnet-rs + const provider = new RpcProvider({ nodeUrl: "https://starknet-sepolia.public.blastapi.io/rpc/v0_6" }); // only for starknet-devnet-rs - const JPSClassAt = await provider.getClassAt("0x04d12d8652db5311bc38ad36ac82b2f3ae41fcbbb4ae7e991bd368b43e7ab3ae"); + const JPSClassAt = await provider.getClassAt("0x07921148721b727726ff737f9c65e411c730ab7dd9667f323dd449067daa0c8f"); - const jpsContract = new Contract(JPSClassAt.abi, "0x04d12d8652db5311bc38ad36ac82b2f3ae41fcbbb4ae7e991bd368b43e7ab3ae", provider); + const jpsContract = new Contract(JPSClassAt.abi, "0x07921148721b727726ff737f9c65e411c730ab7dd9667f323dd449067daa0c8f", provider); const callData = new CallData(JPSClassAt.abi); const myCallData = callData.compile("jps", { diff --git a/frontend/src/utils.jsx b/frontend/src/utils.jsx index 17df436..651c989 100644 --- a/frontend/src/utils.jsx +++ b/frontend/src/utils.jsx @@ -1,4 +1,5 @@ import jps from "./Algorithms/JPS.jsx"; +import a_star from "./Algorithms/AStar.jsx"; import random from "./Mazes/Personal.jsx"; import recursiveDivision from "./Mazes/RecursiveDivision.jsx"; import recursiveBacktracking from "./Mazes/RecusiveBacktracking.jsx"; @@ -7,6 +8,7 @@ import binaryTree from "./Mazes/binaryTree.jsx"; export const algos = { "Jump Point Search": jps, + "A*": a_star, }; export const mazes = { diff --git a/src/algorithms/a_star.cairo b/src/algorithms/a_star.cairo new file mode 100644 index 0000000..9395c81 --- /dev/null +++ b/src/algorithms/a_star.cairo @@ -0,0 +1,145 @@ +use core::array::SpanTrait; +use core::dict::Felt252DictTrait; +use core::nullable::{Nullable, NullableTrait, match_nullable, FromNullableResult}; +use core::option::OptionTrait; +use pathfinding::algorithms::jps::{InfoKey, TilesInfo, TilesInfoTrait}; +use pathfinding::data_structures::{ + map::{Map, MapTrait, convert_position_to_idx, convert_idx_to_position}, + min_heap::{MinHeap, MinHeapTrait}, +}; +use pathfinding::numbers::i64::i64; +use pathfinding::numbers::integer_trait::IntegerTrait; +use pathfinding::utils::constants::{ + PARENT_KEY, STATUS_KEY, DISTANCE_KEY, DISTANCE_TO_GOAL_KEY, ESTIMATED_TOTAL_PATH_DISTANCE_KEY +}; +use pathfinding::utils::heuristics::manhattan; +use pathfinding::utils::movement::get_movement_direction_coords; + +const OPENED: u64 = 1; +const CLOSED: u64 = 2; + +trait AStarTrait { + fn find_path(map: Map, start: (u64, u64), goal: (u64, u64)) -> Span<(u64, u64)>; +} + +impl AStarDiagOneObstacle of AStarTrait { + fn find_path(map: Map, start: (u64, u64), goal: (u64, u64)) -> Span<(u64, u64)> { + let (sx, sy) = start; + let (gx, gy) = goal; + let mut tiles_info = TilesInfoTrait::new(); + let mut open_list: MinHeap = MinHeapTrait::new(); + + let goal_id = convert_position_to_idx(map.width, gx, gy); + let start_id = convert_position_to_idx(map.width, sx, sy); + tiles_info.write(start_id, InfoKey::STATUS, OPENED); + tiles_info.write(start_id, InfoKey::ESTIMATIVE_TOTAL_COST, 0); + open_list.add(start_id, 0); + + let mut goal_flag = false; + let mut node_id_flag = 0; + + loop { + if open_list.len == 0 || goal_flag { + break; + } + + let (node_id, node_value) = open_list.poll().unwrap(); // nodo con menor costo de F + let (node_x, node_y) = convert_idx_to_position(map.width, node_id); + tiles_info.write(node_id, InfoKey::STATUS, CLOSED); + + if goal_id == node_id { + goal_flag = true; + node_id_flag = node_id; + break; + } + + let neighbours = map.get_neighbours(ref tiles_info, node_id); + let mut i = 0; + loop { + if neighbours.len() == i { + break; + } + let n_id = *neighbours.at(i); + let (nx, ny) = convert_idx_to_position(map.width, n_id); + let n_status = tiles_info.read(n_id, InfoKey::STATUS); + let n_status_is_null = match match_nullable(n_status) { + FromNullableResult::Null => true, + FromNullableResult::NotNull(val) => false, + }; + + let inx = IntegerTrait::::new(nx, false); + let iny = IntegerTrait::::new(ny, false); + if (!n_status_is_null && n_status.deref() == CLOSED) + || !map.is_walkable_at(inx, iny) { + i += 1; + continue; + } + + let nh = manhattan( + (IntegerTrait::::new(nx, false) - IntegerTrait::::new(sx, false)).mag, + (IntegerTrait::::new(ny, false) - IntegerTrait::::new(sy, false)).mag + ); + let ng = manhattan( + (IntegerTrait::::new(nx, false) - IntegerTrait::::new(gx, false)).mag, + (IntegerTrait::::new(ny, false) - IntegerTrait::::new(gy, false)).mag + ); + let new_nf = nh + ng; + let nf = tiles_info.read(n_id, InfoKey::ESTIMATIVE_TOTAL_COST); + let nf_int = match match_nullable(nf) { + FromNullableResult::Null => 0, + FromNullableResult::NotNull(val) => nf.deref(), + }; + if new_nf < nf_int || (n_status_is_null || n_status.deref() == CLOSED) { + tiles_info.write(n_id, InfoKey::ESTIMATIVE_TOTAL_COST, new_nf); + tiles_info.write(n_id, InfoKey::PARENT, node_id); + + if n_status_is_null || n_status.deref() == CLOSED { + open_list.add(n_id, new_nf); + tiles_info.write(n_id, InfoKey::STATUS, OPENED); + } + } + i += 1; + } + }; + + if goal_flag { + let (node_x, node_y) = convert_idx_to_position(map.width, node_id_flag); + return build_reverse_path_from(map, ref tiles_info, node_id_flag); + } else { + array![].span() + } + } +} + +fn build_reverse_path_from(map: Map, ref tiles_info: TilesInfo, grid_id: u64) -> Span<(u64, u64)> { + let (x, y) = convert_idx_to_position(map.width, grid_id); + let mut res = array![grid_id]; + + let mut parent_id = grid_id; + loop { + let p = tiles_info.read(parent_id, InfoKey::PARENT); + let p_is_null = match match_nullable(p) { + FromNullableResult::Null => true, + FromNullableResult::NotNull(val) => false, + }; + if p_is_null { + break; + } + res.append(p.deref()); + parent_id = p.deref(); + }; + + let mut i = res.len() - 1; + let mut reverse = array![]; + loop { + reverse.append(convert_idx_to_position(map.width, *res.at(i))); + if i == 0 { + break; + } + i -= 1; + }; + reverse.span() +} + +fn print_span(span: Span) { // let mut i = 0;s +} diff --git a/src/lib.cairo b/src/lib.cairo index 8f16d55..4b807a2 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,6 +1,7 @@ mod pathfinder; mod algorithms { + mod a_star; mod jps; } @@ -24,6 +25,7 @@ mod utils { #[cfg(test)] mod tests { + mod test_a_star; // mod test_map; mod test_jps; // mod test_heap; diff --git a/src/pathfinder.cairo b/src/pathfinder.cairo index c10caf2..e49dca6 100644 --- a/src/pathfinder.cairo +++ b/src/pathfinder.cairo @@ -12,10 +12,19 @@ trait IPathfinder { start: (u64, u64), goal: (u64, u64) ) -> Span<(u64, u64)>; + fn a_star( + self: @TContractState, + tiles: Span, + map_width: u64, + map_height: u64, + start: (u64, u64), + goal: (u64, u64) + ) -> Span<(u64, u64)>; } #[starknet::contract] mod Pathfinder { + use pathfinding::algorithms::{a_star::AStarTrait}; use pathfinding::algorithms::{jps::JPSTrait}; use pathfinding::data_structures::{map::{Map, MapTrait}, tile::{Tile, TileTrait}}; use super::IPathfinder; @@ -47,5 +56,17 @@ mod Pathfinder { let map = MapTrait::new(map_height, map_width, tiles); JPSTrait::find_path(map, start, goal) } + + fn a_star( + self: @ContractState, + tiles: Span, + map_width: u64, + map_height: u64, + start: (u64, u64), + goal: (u64, u64) + ) -> Span<(u64, u64)> { + let map = MapTrait::new(map_height, map_width, tiles); + AStarTrait::find_path(map, start, goal) + } } } diff --git a/src/tests/test_a_star.cairo b/src/tests/test_a_star.cairo new file mode 100644 index 0000000..8069eb1 --- /dev/null +++ b/src/tests/test_a_star.cairo @@ -0,0 +1,2670 @@ +use pathfinding::algorithms::a_star::{AStarTrait}; +use pathfinding::data_structures::map::{ + Map, MapTrait, convert_position_to_idx, convert_idx_to_position +}; +use pathfinding::data_structures::tile::{Tile, TileTrait}; +use pathfinding::pathfinder::{IPathfinder, IPathfinderDispatcher, IPathfinderDispatcherTrait}; +use snforge_std::{declare, ContractClassTrait}; +use starknet::ContractAddress; + +fn deploy_contract(name: felt252) -> ContractAddress { + let contract = declare(name); + contract.deploy(@ArrayTrait::new()).unwrap() +} + +const UNRECHEABLE: u64 = 999999; +const X: felt252 = 'X'; +const O: felt252 = 'O'; + +// Giving parent (P) and actual (G) +// When actual is the goal and call jump() +// Then method will return actual node as jump point +// Map: +// O O O +// O P G +// O O O +// #[test] +// fn test_jump_actual_node_is_the_goal() { +// let map_tiles = array![O,O,O, +// O,O,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 2; +// let y = 1; +// let parent_x = 1; +// let parent_y = 1; +// let goal_x = 2; +// let goal_y = 1; + +// let result = jump(map, x, y, parent_x, parent_y, goal_x, goal_y); +// assert(result.unwrap() == 5, 'jump point should be 5'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y + 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // P A O +// // O X O +// #[test] +// fn test_jump_with_horizontal_right_obstacle_in_y_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,O, +// O,X,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 0; +// let parent_y = 1; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 5'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O X O +// // P A O +// // O O O +// #[test] +// fn test_jump_with_horizontal_right_obstacle_in_y_minus_1() { +// let map_tiles = array![O,X,O, +// O,O,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 0; +// let parent_y = 1; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O X O +// // O A P +// // O O O +// #[test] +// fn test_jump_with_horizontal_left_obstacle_in_y_minus_1() { +// let map_tiles = array![O,X,O, +// O,O,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 2; +// let parent_y = 1; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y + 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // O A P +// // O X O +// #[test] +// fn test_jump_with_horizontal_left_obstacle_in_y_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,O, +// O,X,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 2; +// let parent_y = 1; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x + 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O P O +// // O A X +// // O O O +// #[test] +// fn test_jump_with_vertical_down_obstacle_in_x_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,X, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 1; +// let parent_y = 0; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O P O +// // X A O +// // O O O +// #[test] +// fn test_jump_with_vertical_down_obstacle_in_x_minus_1() { +// let map_tiles = array![O,O,O, +// X,O,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 1; +// let parent_y = 0; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // O A X +// // O P O +// #[test] +// fn test_jump_with_vertical_up_obstacle_in_x_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,X, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 1; +// let parent_y = 2; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // X A O +// // O P O +// #[test] +// fn test_jump_with_vertical_up_obstacle_in_x_minus_1() { +// let map_tiles = array![O,O,O, +// X,O,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 1; +// let parent_y = 2; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // O X A +// // O P O +// #[test] +// fn test_jump_with_diagonal_up_right_obstacle_in_x_minus_1() { +// let map_tiles = array![O,O,O, +// O,X,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 2; +// let y = 1; +// let parent_x = 1; +// let parent_y = 2; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 5, 'jump point should be 5'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y + 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // O A O +// // P X O +// #[test] +// fn test_jump_with_diagonal_up_right_obstacle_in_y_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,O, +// O,X,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 0; +// let parent_y = 2; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O P O +// // O X A +// // O O O +// #[test] +// fn test_jump_with_diagonal_down_right_obstacle_in_x_minus_1() { +// let map_tiles = array![O,O,O, +// O,X,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 2; +// let y = 1; +// let parent_x = 1; +// let parent_y = 0; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 5, 'jump point should be 5'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // P X O +// // O A O +// #[test] +// fn test_jump_with_diagonal_down_right_obstacle_in_y_minus_1() { +// let map_tiles = array![O,O,O, +// O,X,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 2; +// let parent_x = 0; +// let parent_y = 1; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 7, 'jump point should be 7'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O P O +// // O X A +// // O O O +// #[test] +// fn test_jump_with_diagonal_up_left_obstacle_in_x_plus_1() { +// let map_tiles = array![O,O,O, +// O,X,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 0; +// let y = 1; +// let parent_x = 1; +// let parent_y = 2; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 3, 'jump point should be 3'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y + 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O O +// // O A O +// // O X P +// #[test] +// fn test_jump_with_diagonal_up_left_obstacle_in_y_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,O, +// O,X,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 2; +// let parent_y = 2; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (x + 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O O P +// // O A X +// // O O O +// #[test] +// fn test_jump_with_diagonal_down_left_obstacle_in_x_plus_1() { +// let map_tiles = array![O,O,O, +// O,O,X, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 2; +// let parent_y = 0; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// // Giving parent (P) and actual (A) has an obstacle in (y - 1) position +// // When call jump() +// // Then method will return actual node as jump point +// // Map: +// // O X P +// // O A O +// // O O O +// #[test] +// fn test_jump_with_diagonal_down_left_obstacle_in_y_minus_1() { +// let map_tiles = array![O,X,O, +// O,O,O, +// O,O,O]; + +// let map = build_map(3, 3, map_tiles); + +// let x = 1; +// let y = 1; +// let parent_x = 2; +// let parent_y = 0; + +// let result = jump(map, x, y, parent_x, parent_y, UNRECHEABLE, UNRECHEABLE); +// assert(result.unwrap() == 4, 'jump point should be 4'); +// } + +// 0 1 2 3 4 5 +// 0 O O O O X O +// 1 O S O X G O +// 2 O O O X X O +// 3 O O X O O O +// 4 O O O X O X +// 5 O X O O O X +// S: Start, G: Goal +// Map width = 6, height = 6 +// fn test_find_path_with_small_map() { +// #[test] +// #[available_gas(1000000000000000)] +// fn test_a_star() { +// let map_tiles = array![O,O,O,O,X,O, +// O,O,O,X,O,O, +// O,O,O,X,X,O, +// O,O,X,O,O,O, +// O,O,O,X,O,X, +// O,X,O,O,O,X, +// ]; + +// let map = build_map(6, 6, map_tiles); + +// let start = (0, 0); +// let goal = (5, 0); + +// let mut result = AStarTrait::find_path(map, start: start, goal: goal); +// println!("------------------"); +// print(map.width, result); +// // assert(result.len() == 8, 'wrong jps'); +// } + +// 0 1 2 3 4 5 +// 0 O O O O X O +// 1 O S O X G O +// 2 O O O X X O +// 3 O O X O O O +// 4 O O O X O X +// 5 O X O X O X +// S: Start, G: Goal +// Map width = 6, height = 6 +// #[test] +// fn test_find_path_with_small_map_non_solution() { +// let map_tiles = array![ +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// X, +// X, +// X, +// X, +// O, +// O, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// O, +// O, +// X, +// X, +// X, +// O, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// X, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// O, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O +// ]; + +// let map = build_map(30, 10, map_tiles); + +// let start = (1, 2); +// let goal = (29, 9); + +// let mut result = JPSTrait::find_path(map, start: start, goal: goal); +// println!("------------------"); +// print(30, result); +// } + +#[test] +#[available_gas(1000000000000000)] +fn test_find_path_with_big_map() { + let map_tiles = array![ + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + ]; + + let map = build_map(30, 60, map_tiles); + + let start = (1, 2); + let goal = (20, 55); + + let mut result = AStarTrait::find_path(map, start: start, goal: goal); + print(map.width, result); +} + +// @external +// func test_find_path_with_big_map{pedersen_ptr: HashBuiltin*, range_check_ptr}() { +// alloc_locals; +// let point_attribute: DictAccess* = create_attribute_dict(); +// let heap: DictAccess* = heap_create(); +// tempvar map_grids: felt* = cast(new(O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, +// O,X,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, +// O,O,O,O,O,X,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, +// O,O,O,O,X,X,X,X,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, +// O,O,O,O,O,X,O,O,X,X,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, +// O,X,O,O,O,O,O,O,O,O,X,O,X,X,X,X,X,X,X,X,X,X,X,X,X,O,O,X,X,X, +// O,X,O,O,X,X,O,O,O,O,X,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, +// O,X,O,X,O,O,X,O,O,X,O,O,X,O,O,O,X,X,X,X,X,X,X,X,X,X,O,O,O,O, +// O,X,X,O,O,X,X,O,O,X,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,X,X,O,O, +// X,O,O,O,O,O,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,X,O, +// O,O,O,O,O,X,X,O,O,O,O,O,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,X, +// O,O,X,X,O,O,X,O,O,O,O,X,O,O,O,X,O,O,X,X,X,X,X,X,X,X,X,O,O,X, +// O,O,X,X,O,O,X,O,X,O,O,X,X,X,X,O,X,X,O,X,X,O,O,O,O,O,O,O,O,X, +// O,O,X,X,X,O,X,O,X,O,O,O,O,O,O,O,X,X,O,X,O,O,O,O,O,X,O,O,O,X, +// O,O,O,O,O,O,X,O,X,O,O,O,O,O,O,O,O,O,O,X,X,O,O,X,X,X,X,X,X,X), felt*); +// let map = Map(map_grids, 30, 15); + +// let start_x = 1; +// let start_y = 2; +// let end_x = 22; +// let end_y = 13; +// let (result_after_lenght: felt, result_after: Point*) = find_path{pedersen_ptr=pedersen_ptr, range_check_ptr=range_check_ptr, point_attribute=point_attribute, heap=heap}(start_x, start_y, end_x, end_y, map); +// return (); +// } + +fn build_map(width: u64, height: u64, tiles: Array) -> Map { + let mut map_tiles = array![]; + let mut x = 0; + let mut y = 0; + + loop { + let id = (y * width + x); + if id.try_into().unwrap() == tiles.len() { + break; + } + if x == width { + y += 1; + x = 0; + } + if *tiles.at(id.try_into().unwrap()) == O { + map_tiles.append(TileTrait::new(id, x.into(), y.into(), true)); + } else { + map_tiles.append(TileTrait::new(id, x.into(), y.into(), false)); + } + x += 1; + }; + MapTrait::new(height, width, map_tiles.span()) +} + +fn print(width: u64, span: Span<(u64, u64)>) { + let mut i = 0; + print!("ASTAR PATH: {{ len: {}, values: [ ", span.len()); + loop { + if span.len() == i { + break; + } + let (x, y) = *(span.at(i)); + if span.len() - 1 != i { + print!("(x: {}, y: {}), ", x, y); + } else { + print!("(x: {}, y: {})", x, y); + } + i += 1; + }; + println!(" ] }}") +} diff --git a/src/tests/test_jps.cairo b/src/tests/test_jps.cairo index 77bba9d..516dcb2 100644 --- a/src/tests/test_jps.cairo +++ b/src/tests/test_jps.cairo @@ -466,8 +466,324 @@ const O: felt252 = 'O'; // 5 O X O X O X // S: Start, G: Goal // Map width = 6, height = 6 +// #[test] +// fn test_find_path_with_small_map_non_solution() { +// let map_tiles = array![ +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// X, +// X, +// X, +// X, +// O, +// O, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// O, +// O, +// X, +// X, +// X, +// O, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// X, +// O, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// O, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// X, +// O, +// O, +// O, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// X, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// O, +// X, +// O +// ]; + +// let map = build_map(30, 10, map_tiles); + +// let start = (1, 2); +// let goal = (29, 9); + +// let mut result = JPSTrait::find_path(map, start: start, goal: goal); +// // println!("------------------"); +// // print(30, result); +// } + #[test] -fn test_find_path_with_small_map_non_solution() { +#[available_gas(1000000000000000)] +fn test_find_path_with_big_map() { let map_tiles = array![ O, O, @@ -768,92 +1084,1518 @@ fn test_find_path_with_small_map_non_solution() { O, O, X, - O + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + X, + X, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + X, + X, + X, + O, + X, + O, + O, + X, + X, + O, + O, + O, + O, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, + X, + O, + O, + O, + X, + O, + O, + X, + X, + O, + O, + X, + O, + X, + O, + O, + X, + X, + X, + X, + O, + X, + X, + O, + X, + X, + O, + O, + O, + O, + O, + O, + O, + O, + X, + O, + O, + X, + X, + X, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + X, + O, + O, + O, + O, + O, + X, + O, + O, + O, + X, + O, + O, + O, + O, + O, + O, + X, + O, + X, + O, + O, + O, + O, + O, + O, + O, + O, + O, + O, + X, + X, + O, + O, + X, + X, + X, + X, + X, + X, + X, ]; - let map = build_map(30, 10, map_tiles); + let map = build_map(30, 60, map_tiles); let start = (1, 2); - let goal = (29, 9); + let goal = (20, 55); let mut result = JPSTrait::find_path(map, start: start, goal: goal); -// println!("------------------"); -// print(30, result); + print(map.width, result); } -// #[test] -// #[available_gas(1000000000000000)] -// fn test_find_path_with_big_map() { -// let map_tiles = array![O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,X,X,X,X,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,X,X,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,O,O,O,O,O,X,O,X,X,X,X,X,X,X,X,X,X,X,X,X,O,O,X,X,X, -// O,X,O,O,X,X,O,O,O,O,X,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,X,O,O,X,O,O,X,O,O,X,O,O,O,X,X,X,X,X,X,X,X,X,X,O,O,O,O, -// O,X,X,O,O,X,X,O,O,X,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,X,X,O,O, -// X,O,O,O,O,O,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,X,O, -// O,O,O,O,O,X,X,O,O,O,O,O,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,X, -// O,O,X,X,O,O,X,O,O,O,O,X,O,O,O,X,O,O,X,X,X,X,X,X,X,X,X,O,O,X, -// O,O,X,X,O,O,X,O,X,O,O,X,X,X,X,O,X,X,O,X,X,O,O,O,O,O,O,O,O,X, -// O,O,X,X,X,O,X,O,X,O,O,O,O,O,O,O,X,X,O,X,O,O,O,O,O,X,O,O,O,X, -// O,O,O,O,O,O,X,O,X,O,O,O,O,O,O,O,O,O,O,X,X,O,O,X,X,X,X,X,X,X, -// O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,X,X,X,X,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,X,X,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,O,O,O,O,O,X,O,X,X,X,X,X,X,X,X,X,X,X,X,X,O,O,X,X,X, -// O,X,O,O,X,X,O,O,O,O,X,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,X,O,O,X,O,O,X,O,O,X,O,O,O,X,X,X,X,X,X,X,X,X,X,O,O,O,O, -// O,X,X,O,O,X,X,O,O,X,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// X,O,O,O,O,O,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,X,O, -// O,O,O,O,O,X,X,O,O,O,O,O,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,X, -// O,O,X,X,O,O,X,O,O,O,O,X,O,O,O,X,O,O,X,X,X,X,X,X,X,X,O,O,O,X, -// O,O,X,X,O,O,X,O,X,O,O,X,X,X,X,O,X,X,O,X,X,O,O,O,O,O,O,O,O,X, -// O,O,X,X,X,O,X,O,X,O,O,O,O,O,O,O,X,X,O,X,O,O,O,O,O,X,O,O,O,X, -// O,O,O,O,O,O,X,O,X,O,O,O,O,O,O,O,O,O,O,X,X,O,O,X,X,X,X,X,X,X, -// O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,X,X,X,X,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,X,X,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,O,O,O,O,O,X,O,X,X,X,X,X,X,X,X,X,X,X,X,X,O,O,X,X,X, -// O,X,O,O,X,X,O,O,O,O,X,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,X,O,O,X,O,O,X,O,O,X,O,O,O,X,X,X,X,X,X,X,X,X,X,O,O,O,O, -// O,X,X,O,O,X,X,O,O,X,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,X,X,O,O, -// X,O,O,O,O,O,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,X,O, -// O,O,O,O,O,X,X,O,O,O,O,O,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,X, -// O,O,X,X,O,O,X,O,O,O,O,X,O,O,O,X,O,O,X,X,X,X,X,X,X,X,X,O,O,X, -// O,O,X,X,O,O,X,O,X,O,O,X,X,X,X,O,X,X,O,X,X,O,O,O,O,O,O,O,O,X, -// O,O,X,X,X,O,X,O,X,O,O,O,O,O,O,O,X,X,O,X,O,O,O,O,O,X,O,O,O,X, -// O,O,O,O,O,O,X,O,X,O,O,O,O,O,O,O,O,O,O,X,X,O,O,X,X,X,X,X,X,X, -// O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,X,X,X,X,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,O,O,O,O,X,O,O,X,X,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,O,O,O,O,O,O,O,X,O,X,X,X,X,X,X,X,X,X,X,X,X,X,O,O,X,X,X, -// O,X,O,O,X,X,O,O,O,O,X,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// O,X,O,X,O,O,X,O,O,X,O,O,X,O,O,O,X,X,X,X,X,X,X,X,X,X,O,O,O,O, -// O,X,X,O,O,X,X,O,O,X,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O, -// X,O,O,O,O,O,O,O,O,O,O,O,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,X,O, -// O,O,O,O,O,X,X,O,O,O,O,O,X,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,X, -// O,O,X,X,O,O,X,O,O,O,O,X,O,O,O,X,O,O,X,X,X,X,X,X,X,X,O,O,O,X, -// O,O,X,X,O,O,X,O,X,O,O,X,X,X,X,O,X,X,O,X,X,O,O,O,O,O,O,O,O,X, -// O,O,X,X,X,O,X,O,X,O,O,O,O,O,O,O,X,X,O,X,O,O,O,O,O,X,O,O,O,X, -// O,O,O,O,O,O,X,O,X,O,O,O,O,O,O,O,O,O,O,X,X,O,O,X,X,X,X,X,X,X,]; - -// let map = build_map(30, 60, map_tiles); - -// let start = (1, 2); -// let goal = (20, 55); - -// let mut result = JPSTrait::find_path(map, start: start, goal: goal); -// print(map.width, result); -// } - // @external // func test_find_path_with_big_map{pedersen_ptr: HashBuiltin*, range_check_ptr}() { // alloc_locals; @@ -908,19 +2650,20 @@ fn build_map(width: u64, height: u64, tiles: Array) -> Map { MapTrait::new(height, width, map_tiles.span()) } -fn print(width: u64, span: Span<(u64, u64)>) { // let mut i = 0; -// print!("PATH: {{ len: {}, values: [ ", span.len()); -// loop { -// if span.len() == i { -// break; -// } -// let (x, y) = *(span.at(i)); -// if span.len() - 1 != i { -// print!("(x: {}, y: {}), ", x, y); -// } else { -// print!("(x: {}, y: {})", x, y); -// } -// i += 1; -// }; -// println!(" ] }}") +fn print(width: u64, span: Span<(u64, u64)>) { + let mut i = 0; + print!("JPS PATH: {{ len: {}, values: [ ", span.len()); + loop { + if span.len() == i { + break; + } + let (x, y) = *(span.at(i)); + if span.len() - 1 != i { + print!("(x: {}, y: {}), ", x, y); + } else { + print!("(x: {}, y: {})", x, y); + } + i += 1; + }; + println!(" ] }}") }