docs(pathfinding): add docstrings

This commit is contained in:
Kristofers Solo 2025-01-14 13:06:47 +02:00
parent cafcb3545f
commit 5585966da6
3 changed files with 58 additions and 7 deletions

2
Cargo.lock generated
View File

@ -2350,7 +2350,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "hexlab"
version = "0.6.0"
version = "0.6.1"
dependencies = [
"bevy",
"bevy_reflect",

View File

@ -1,7 +1,7 @@
[package]
name = "hexlab"
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
version = "0.6.0"
version = "0.6.1"
edition = "2021"
description = "A hexagonal maze generation and manipulation library"
repository = "https://github.com/kristoferssolo/hexlab"

View File

@ -1,19 +1,70 @@
//! Maze pathfinding implementation for hexagonal grids.
//!
//! This module provides functionality for finding paths through a hexagonal maze
//! using the A* pathfinding algorithm. The maze is represented as a collection of
//! hexagonal cells, where each cell may have walls on any of its six edges.
//!
//! # Examples
//!
//! ```
//! use hexlab::prelude::*;
//!
//! let maze = MazeBuilder::new()
//! .with_radius(3)
//! .with_seed(12345)
//! .build()
//! .expect("Failed to create maze");
//! assert!(maze.find_path(Hex::ZERO, Hex::new(-1, 3)).is_some());
//! ```
//!
//! # Implementation Details
//!
//! The pathfinding algorithm uses Manhattan distance as a heuristic and considers
//! walls between cells when determining valid paths. Each step between adjacent
//! cells has a cost of 1.
use hexx::{EdgeDirection, Hex};
use pathfinding::prelude::*;
use crate::Maze;
impl Maze {
#[must_use]
/// Finds the shortest path between two hexagonal positions in the maze using A* pathfinding.
///
/// This function calculates the optimal path while taking into account walls between cells.
/// The path cost between adjacent cells is always 1, and Manhattan distance is used as the
/// heuristic for pathfinding.
///
/// # Arguments
///
/// * `from` - The starting hexagonal position
/// * `to` - The target hexagonal position
///
/// # Returns
///
/// * `Some(Vec<Hex>)` - A vector of hexagonal positions representing the path from start to target
/// * `None` - If no valid path exists between the positions
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let maze = MazeBuilder::new()
/// .with_radius(3)
/// .with_seed(12345)
/// .build()
/// .expect("Failed to create maze");
/// assert!(maze.find_path(Hex::ZERO, Hex::new(-1, 3)).is_some());
/// ```
pub fn find_path(&self, from: Hex, to: Hex) -> Option<Vec<Hex>> {
let successors = |pos: &Hex| {
{
EdgeDirection::ALL_DIRECTIONS.iter().filter_map(|&dir| {
let neighbor = pos.neighbor(dir);
if let Some(current_tile) = self.get(pos) {
if let Some(_) = self.get(&neighbor) {
if !current_tile.walls.contains(dir) {
return Some((neighbor, 1)); // Cost of 1 for each step
}
if self.get(&neighbor).is_some() && !current_tile.walls.contains(dir) {
return Some((neighbor, 1)); // Cost of 1 for each step
}
}
None
@ -25,7 +76,7 @@ impl Maze {
let heuristic = |pos: &Hex| {
// Manhatan distance
let diff = *pos - to;
(diff.x.abs() + diff.y.abs() + diff.z().abs()) as u32 / 2
(diff.x.abs() + diff.y.abs() + diff.z().abs()) / 2
};
astar(&from, successors, heuristic, |pos| *pos == to).map(|(path, _)| path)