advanced_pathfinding_demo/
advanced_pathfinding_demo.rs1#![allow(clippy::needless_return)]
4#![allow(clippy::implicit_return)]
5#![allow(clippy::redundant_else)]
6
7use tiles_tools::{
8 pathfind::{astar, astar_multi_goal, astar_with_edge_costs, PathfindingConfig, astar_advanced},
9 coordinates::{
10 hexagonal::{Coordinate as HexCoord, Axial, Pointy},
11 triangular::{Coordinate as TriCoord, TwelveConnected},
12 isometric::{Coordinate as IsoCoord, Diamond},
13 square::{Coordinate as SquareCoord, FourConnected, EightConnected},
14 },
15};
16use std::collections::HashSet;
17
18fn main() {
19 println!("Advanced Pathfinding Demonstration");
20 println!("=================================");
21
22 demonstrate_basic_pathfinding();
23 demonstrate_advanced_pathfinding();
24 demonstrate_multi_goal_pathfinding();
25 demonstrate_edge_cost_pathfinding();
26 demonstrate_hexagonal_pathfinding();
27 demonstrate_triangular_pathfinding();
28 demonstrate_isometric_pathfinding();
29
30 println!("\nš Advanced Pathfinding Demo Complete!");
31 println!("Key features demonstrated:");
32 println!("- Multiple coordinate systems");
33 println!("- Obstacle avoidance");
34 println!("- Variable terrain costs");
35 println!("- Multi-goal pathfinding");
36 println!("- Performance characteristics");
37}
38
39fn demonstrate_basic_pathfinding() {
40 println!("\n=== Basic A* Pathfinding ===");
41 let start = SquareCoord::<FourConnected>::new(0, 0);
42 let goal = SquareCoord::<FourConnected>::new(5, 5);
43
44 let obstacles: HashSet<_> = [
45 SquareCoord::<FourConnected>::new(2, 1),
46 SquareCoord::<FourConnected>::new(2, 2),
47 SquareCoord::<FourConnected>::new(2, 3),
48 SquareCoord::<FourConnected>::new(3, 3),
49 ].into_iter().collect();
50
51 if let Some((path, cost)) = astar(
52 &start,
53 &goal,
54 |coord| return !obstacles.contains(coord),
55 |_coord| return 1,
56 ) {
57 println!("Basic path found: {} steps, cost: {}", path.len(), cost);
58 println!("Path: {path:?}");
59 } else {
60 println!("No path found");
61 }
62}
63
64fn demonstrate_advanced_pathfinding() {
65 println!("\n=== Advanced A* with Configuration ===");
66 let start = SquareCoord::<FourConnected>::new(0, 0);
67 let goal = SquareCoord::<FourConnected>::new(5, 5);
68
69 let config = PathfindingConfig::new()
70 .with_max_distance(20)
71 .with_terrain_cost(SquareCoord::<FourConnected>::new(1, 1), 3)
72 .with_terrain_cost(SquareCoord::<FourConnected>::new(1, 2), 3)
73 .with_base_cost(1);
74
75 if let Some((path, cost)) = astar_advanced(&start, &goal, &config) {
76 println!("Advanced path found: {} steps, cost: {}", path.len(), cost);
77 println!("Path: {path:?}");
78 } else {
79 println!("No advanced path found");
80 }
81}
82
83fn demonstrate_multi_goal_pathfinding() {
84 println!("\n=== Multi-Goal Pathfinding ===");
85 let ai_position = SquareCoord::<FourConnected>::new(2, 2);
86 let possible_targets = [
87 SquareCoord::<FourConnected>::new(0, 0),
88 SquareCoord::<FourConnected>::new(5, 1),
89 SquareCoord::<FourConnected>::new(1, 5),
90 SquareCoord::<FourConnected>::new(4, 4),
91 ];
92
93 if let Some((path, cost, chosen_target)) = astar_multi_goal(
94 &ai_position,
95 &possible_targets,
96 |_coord| return true,
97 |_coord| return 1,
98 ) {
99 println!("AI chose target: {chosen_target:?}");
100 println!("Best path found: {} steps, cost: {}", path.len(), cost);
101 println!("Path: {path:?}");
102 } else {
103 println!("No multi-goal path found");
104 }
105}
106
107fn demonstrate_edge_cost_pathfinding() {
108 println!("\n=== Edge Cost Pathfinding (8-Connected) ===");
109 let start_8 = SquareCoord::<EightConnected>::new(0, 0);
110 let goal_8 = SquareCoord::<EightConnected>::new(4, 3);
111
112 if let Some((path, cost)) = astar_with_edge_costs(
113 &start_8,
114 &goal_8,
115 |_coord| return true,
116 |from, to| {
117 let dx = (to.x - from.x).abs();
118 let dy = (to.y - from.y).abs();
119 if dx == 1 && dy == 1 {
120 return 14; } else {
122 return 10; }
124 },
125 ) {
126 println!("Edge cost path found: {} steps, cost: {}", path.len(), cost);
127 println!("Path: {path:?}");
128 } else {
129 println!("No edge cost path found");
130 }
131}
132
133fn demonstrate_hexagonal_pathfinding() {
134 println!("\n=== Hexagonal Grid Pathfinding ===");
135 let hex_start = HexCoord::<Axial, Pointy>::new(-2, 2);
136 let hex_goal = HexCoord::<Axial, Pointy>::new(3, -1);
137
138 if let Some((path, cost)) = astar(
139 &hex_start,
140 &hex_goal,
141 |_coord| return true,
142 |_coord| return 1,
143 ) {
144 println!("Hexagonal path found: {} steps, cost: {}", path.len(), cost);
145 println!("Path: {path:?}");
146 } else {
147 println!("No hexagonal path found");
148 }
149}
150
151fn demonstrate_triangular_pathfinding() {
152 println!("\n=== Triangular Grid Pathfinding ===");
153 let tri_start = TriCoord::<TwelveConnected>::new(0, 0);
154 let tri_goal = TriCoord::<TwelveConnected>::new(4, 2);
155
156 if let Some((path, cost)) = astar(
157 &tri_start,
158 &tri_goal,
159 |_coord| return true,
160 |_coord| return 1,
161 ) {
162 println!("Triangular path found: {} steps, cost: {}", path.len(), cost);
163 println!("Path: {path:?}");
164 } else {
165 println!("No triangular path found");
166 }
167}
168
169fn demonstrate_isometric_pathfinding() {
170 println!("\n=== Isometric Grid Pathfinding ===");
171 let iso_start = IsoCoord::<Diamond>::new(0, 0);
172 let iso_goal = IsoCoord::<Diamond>::new(3, 2);
173
174 if let Some((path, cost)) = astar(
175 &iso_start,
176 &iso_goal,
177 |_coord| return true,
178 |_coord| return 1,
179 ) {
180 println!("Isometric path found: {} steps, cost: {}", path.len(), cost);
181 println!("Path: {path:?}");
182 } else {
183 println!("No isometric path found");
184 }
185}