#pathfinding #benchmark #parser

movingai

MovingAI Benchmark Map/Scen File Parser

8 releases (breaking)

0.7.0 Mar 14, 2018
0.6.0 Feb 27, 2018
0.5.1 Feb 7, 2018
0.4.0 Jan 29, 2018
0.1.0 Jan 24, 2018

#41 in Science

Download history 10/week @ 2018-05-04 3/week @ 2018-05-11 10/week @ 2018-05-18 15/week @ 2018-05-25 41/week @ 2018-06-01 16/week @ 2018-06-08 83/week @ 2018-06-15 20/week @ 2018-06-22 70/week @ 2018-06-29 40/week @ 2018-07-13 51/week @ 2018-07-20 49/week @ 2018-07-27

61 downloads per month

movingai-rust

Travis Build Cargo Version

Still in development! Help is encouraged for stabilizing the API.

Map/Scenario Parser for the MovingAI benchmark format. It offers a quick way to parse scenario and map files, plus some map utility to manage and query information from them.

Map Features

The create not only parse a map and scene file, it also provide an object for easy interacting with it.

Some of the functionalities are:

  • Easy idiomatic access to the map date, such as width, height and tiles at specific coordinate.
  • Check if a tile is traversable or not according the MovingAI format rules.
  • Get the list of neighbors coordinates of a specific tile.
  • [TO DO] Convert bitmaps into .map files.
  • And more things I still need to decide. :D
  • Serialize/Deserialzie .map and .scen files into JSON/YAML using serde (activate --feature serde)

How to use

extern crate movingai;

use std::path::Path;
use movingai::parser::parse_map_file;

fn main() {
    let map = parse_map_file(Path::new("./test/arena.map")).unwrap();
    let width = map.width();
    let tile = map[(4,5)]; // Access map location at row 4 and column 5.
}

With this library is to use for implementing pathfinding algorithms:

// A* shortest path algorithm.

fn shortest_path(map: &MovingAiMap, start: Coords2D, goal: Coords2D) -> Option<f64> {

    let mut heap = BinaryHeap::new();
    let mut visited = Vec::<Coords2D>::new();

    // We're at `start`, with a zero cost
    heap.push(SearchNode { f: 0.0, g:0.0, h: distance(start, goal), current: start });

    while let Some(SearchNode { f: _f, g, h: _h, current }) = heap.pop() {

        if current == goal { return Some(g); }

        if visited.contains(&current) {
            continue;
        }

        visited.push(current);

        for neigh in map.neighbors(current) {
            let new_h = distance(neigh, goal);
            let i = distance(neigh, current);
            let next = SearchNode { f: g+i+new_h, g: g+i, h: new_h, current: neigh };
            heap.push(next);
        }
    }

    // Goal not reachable
    None
}

and to write benchmark over a scen file!

fn main() {
    let map = parse_map_file(Path::new("./tests/arena.map")).unwrap();
    let scenes = parse_scen_file(Path::new("./tests/arena.map.scen")).unwrap();
    for scene in scenes {
        let start = scene.start_pos;
        let goal = scene.goal_pos;
        let t = Instant::now();
        match shortest_path(&map, (1,3), (4,3)) {
            Some(x) => {
                let duration = t.elapsed();
                let seconds = duration.as_secs();
                let ms = (duration.subsec_nanos() as f64) / 1_000_000.0;
                println!("{:?} -> {:?} \tin {:?} seconds and {:?} ms", start, goal, seconds, ms);
            }
            None => println!("None"),
        }
    }
}
MIT license

Dependencies

  • optional serde 1.0.27+derive

Reverse deps