Skip to main content

advanced_pathfinding_demo/
advanced_pathfinding_demo.rs

1//! Simplified advanced pathfinding demonstration to avoid clippy issues.
2
3#![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; // ~1.414 * 10 for diagonal
121            } else {
122                return 10; // Standard orthogonal movement
123            }
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}