extern crate basic_pathfinding; use basic_pathfinding::coord::Coord; use basic_pathfinding::grid::{Grid, GridType}; use basic_pathfinding::pathfinding::{find_reachable, SearchOpts}; macro_rules! hashmap { ($( $key: expr => $val: expr ),*) => {{ let mut map = ::std::collections::HashMap::new(); $( map.insert($key, $val); )* map }} } #[test] fn only_traverses_walkable_tiles() { let grid = Grid { tiles: vec![ vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![2, 2, 1, 1, 1], vec![1, 1, 1, 1, 1], ], walkable_tiles: vec![1], ..Grid::default() }; let source = vec![Coord::new(1, 2)]; let opts = SearchOpts::default(); let result = find_reachable(&grid, source, opts); assert_eq!( result.stoppable, vec![ Coord::new(0, 0), Coord::new(0, 1), Coord::new(0, 2), Coord::new(1, 0), Coord::new(1, 1), Coord::new(1, 2), ] ); } #[test] fn searches_from_multiple_sources() { let grid = Grid { tiles: vec![ vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![2, 2, 2, 2, 2], vec![1, 1, 1, 1, 1], ], walkable_tiles: vec![1], ..Grid::default() }; let source = vec![Coord::new(1, 2), Coord::new(4, 2)]; let opts = SearchOpts::default(); let result = find_reachable(&grid, source, opts); println!("asdf {:?}", result); assert_eq!( result.stoppable, vec![ Coord { x: 0, y: 0 }, Coord { x: 0, y: 1 }, Coord { x: 0, y: 2 }, Coord { x: 1, y: 0 }, Coord { x: 1, y: 1 }, Coord { x: 1, y: 2 }, Coord { x: 3, y: 0 }, Coord { x: 3, y: 1 }, Coord { x: 3, y: 2 }, Coord { x: 4, y: 0 }, Coord { x: 4, y: 1 }, Coord { x: 4, y: 2 } ] ); } #[test] fn avoids_unwalkable_coords() { let grid = Grid { tiles: vec![ vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], ], walkable_tiles: vec![1], unwalkable_coords: hashmap![ 3 => hashmap![0 => true, 1 => true] ], ..Grid::default() }; let source = vec![Coord::new(1, 2)]; let opts = SearchOpts::default(); let result = find_reachable(&grid, source, opts); assert_eq!( result.stoppable, vec![ Coord::new(0, 0), Coord::new(0, 1), Coord::new(0, 2), Coord::new(1, 0), Coord::new(1, 1), Coord::new(1, 2), ] ); } #[test] fn avoids_unstoppable_coords() { let grid = Grid { tiles: vec![ vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], ], walkable_tiles: vec![1], unstoppable_coords: hashmap![3 => hashmap![ 0 => true, 1 => true ]], ..Grid::default() }; let source = vec![Coord::new(1, 2)]; let opts = SearchOpts::default(); let result = find_reachable(&grid, source, opts); assert_eq!(result.walkable, vec![Coord::new(0, 3), Coord::new(1, 3)]); assert_eq!( result.stoppable, vec![ Coord::new(0, 0), Coord::new(0, 1), Coord::new(0, 2), Coord::new(0, 4), Coord::new(1, 0), Coord::new(1, 1), Coord::new(1, 2), Coord::new(1, 4), ] ); } #[test] fn cancels_early_with_cost_threshold() { let grid = Grid { tiles: vec![ vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 0, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], ], walkable_tiles: vec![1], ..Grid::default() }; let source = vec![Coord::new(1, 2)]; let opts = SearchOpts { cost_threshold: Some(1), ..SearchOpts::default() }; let result = find_reachable(&grid, source, opts); assert_eq!( result.stoppable, vec![ Coord::new(0, 2), Coord::new(1, 1), Coord::new(1, 2), Coord::new(1, 3), ] ); let source = vec![Coord::new(1, 2)]; let opts = SearchOpts { cost_threshold: Some(4), ..SearchOpts::default() }; let result = find_reachable(&grid, source, opts); assert_eq!( result.stoppable, vec![ Coord::new(0, 0), Coord::new(0, 1), Coord::new(0, 2), Coord::new(0, 3), Coord::new(0, 4), Coord::new(1, 0), Coord::new(1, 1), Coord::new(1, 2), Coord::new(1, 3), Coord::new(1, 4), Coord::new(2, 3), Coord::new(2, 4), Coord::new(3, 2), Coord::new(3, 3), Coord::new(3, 4), Coord::new(4, 3), ] ); } #[test] fn reports_start_only_when_cost_zero() { let grid = Grid { tiles: vec![ vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], ], walkable_tiles: vec![1], ..Grid::default() }; let source = vec![Coord::new(1, 2)]; let opts = SearchOpts { cost_threshold: Some(0), ..SearchOpts::default() }; let result = find_reachable(&grid, source, opts); assert_eq!(result.stoppable, vec![Coord::new(1, 2),]); } #[test] fn doesnt_include_unwalkable_start() { let grid = Grid { tiles: vec![ vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], vec![1, 1, 1, 1, 1], ], walkable_tiles: vec![], ..Grid::default() }; let source = vec![Coord::new(1, 2)]; let opts = SearchOpts { cost_threshold: Some(4), ..SearchOpts::default() }; let result = find_reachable(&grid, source, opts); assert_eq!(result.stoppable, vec![]); } #[test] fn navigates_hex_grids() { let grid = Grid { tiles: vec![ vec![1, 0, 1, 0, 1], vec![0, 1, 0, 0, 1], vec![1, 0, 1, 0, 1], vec![0, 1, 0, 0, 1], vec![1, 1, 0, 1, 1], ], walkable_tiles: vec![1], grid_type: GridType::Hex, ..Grid::default() }; let source = vec![Coord::new(1, 1)]; let opts = SearchOpts::default(); let result = find_reachable(&grid, source, opts); assert_eq!( result.stoppable, vec![Coord::new(0, 2), Coord::new(1, 1), Coord::new(2, 0),] ); } #[test] fn navigates_intercardinal_grids() { let grid = Grid { tiles: vec![ vec![1, 0, 0, 0, 0], vec![0, 1, 0, 0, 0], vec![0, 1, 0, 0, 0], vec![1, 0, 0, 0, 0], vec![0, 1, 0, 0, 0], ], walkable_tiles: vec![1], grid_type: GridType::Intercardinal, ..Grid::default() }; let source = vec![Coord::new(1, 1)]; let opts = SearchOpts::default(); let result = find_reachable(&grid, source, opts); assert_eq!( result.stoppable, vec![ Coord::new(0, 0), Coord::new(0, 3), Coord::new(1, 1), Coord::new(1, 2), Coord::new(1, 4), ] ); }