mapgen 0.6.0

Map generator for games (dungeons, worlds etc.)
Documentation
//! Different metrics for the map
//! Can be used to meausre the quality of the map or the quality of the generator.
//! To meause the quality of the generator; generate lots of maps, measure them
//! and the provide generator score as an average.
//! 

use super::map_buffer::MapBuffer;
use super::dijkstra::DijkstraMap;


/// This metric calculates the percentage of walkable cells (Floor).
/// If this number is very low (like < 10%) then it means that the map 
/// is probably to degenerated and shouldn't be used
pub fn density(map: &MapBuffer) -> f32 {
    let floor_count = map.walkables.iter()
        .filter(|&&x| x)
        .count();
    floor_count as f32 / map.walkables.len() as f32
}


/// Calculate the length of the shortes path from the starting point
/// to the exit.
/// If this path is very short, then the map is probably degenerated.
pub fn path_length(map: &MapBuffer) -> f32 {
    if map.starting_point.is_none() {
        return 0.0
    }
    
    match map.exit_point {
        None => 0.0,
        Some(exit) => {
            let dijkstra = DijkstraMap::new(map);
            dijkstra.tiles[map.xy_idx(exit.x, exit.y)]
        },
    }
}


/// ------------------------------------------------------------------------------------------------
/// Module unit tests
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
    use super::*;
    use crate::geometry::Point;


    #[test]
    fn test_density_no_floor() {
        let map = MapBuffer::new(10, 10);
        let score = density(&map);
        assert_eq!(score, 0.0);
    }

    #[test]
    fn test_density() {
        let map_str = "
            ##########
            #   ##   #
            ##########
            ";
        let map = MapBuffer::from_string(map_str);
        let score = density(&map);
        assert_eq!(score, 0.2);
    }

    #[test]
    fn test_no_path() {
        let map_str = "
            ##########
            #   ##   #
            ##########
            ";
        let map = MapBuffer::from_string(map_str);
        let score = path_length(&map);
        assert_eq!(score, 0.0);
    }

    #[test]
    fn test_path_length() {
        let map_str = "
            ##########
            #   ##   #
            #        #
            ##########
            ";
        let mut map = MapBuffer::from_string(map_str);
        map.starting_point = Some(Point::new(1,1));
        map.exit_point = Some(Point::new(8,1));

        let score = path_length(&map);
        assert!(f32::abs(score - 7.9) <= 0.01);
    }
}