Source

ocaml-toys / maze / maze.ml

vfiack 30eb194 
Vincent Fiack 2fbf286 












vfiack f2fd08c 
vfiack 30eb194 
vfiack f2fd08c 





vfiack 30eb194 

vfiack f2fd08c 

vfiack 30eb194 
vfiack f2fd08c 
Vincent Fiack 2fbf286 




vfiack f2fd08c 
Vincent Fiack 2fbf286 

vfiack 30eb194 



Vincent Fiack 2fbf286 
vfiack 30eb194 
vfiack bfb565a 

Vincent Fiack 2fbf286 
vfiack 30eb194 






Vincent Fiack 2fbf286 
vfiack 30eb194 
vfiack 87e9938 
vfiack 30eb194 



Vincent Fiack 2fbf286 
vfiack 30eb194 





module Parser = struct
  let split separator s =
    let list = ref [] in
    let start = ref 0 in
    let () = try
        while true do
          let index = String.index_from s !start separator in
          list := (String.sub s !start (index - !start)) :: !list;
          start := index + 1
        done
      with Not_found -> list := (String.sub s !start ((String.length s) - !start)) :: !list
    in
    List.rev !list
  
  let from_string str =
    let ants = ref [] and goal = ref (0, 0) in
    let lines = split '\n' str in
    let height, width = List.length lines, String.length (List.hd lines) in
    let maze = Array.make_matrix width height ' ' in
    for x = 0 to width -1 do
      for y = 0 to height -1 do
        maze.(x).(y) <- (List.nth lines y).[x];
        if maze.(x).(y) = '@' then ants := (x, y) :: !ants
        else if maze.(x).(y) = 'X' then goal := x, y
      done
    done;
    maze, !goal, !ants
  
  let from_file filename =
    let channel = open_in_bin filename in
    let size = in_channel_length channel in
    let buffer = Buffer.create size in
    Buffer.add_channel buffer channel size;
    from_string (Buffer.contents buffer)
end

let width maze = Array.length maze
let height maze = Array.length maze.(0)
let get maze (x, y) = maze.(x).(y)
let set maze (x, y) value = maze.(x).(y) <- value

let walk maze path =
  let walk_once coords = if get maze coords = ' ' then set maze coords '.' in
  List.iter walk_once path

let draw maze =
  for y = 0 to (height maze) -1 do
    for x = 0 to (width maze) -1 do
      print_char (get maze (x, y))
    done;
    print_newline ()
  done

let is_passable maze coord = get maze coord <> '#'

let distance (x1, y1) (x2, y2) =
  let square x = x * x in
  let sqrt_int x = int_of_float (sqrt (float_of_int x)) in
  sqrt_int (square (x1 - x2) + square (y1 - y2))

let neighbor_nodes maze (x, y) =
  let nodes = [] in
  let nodes = if x > 0 then (x -1, y) :: nodes else nodes in
  let nodes = if x < (width maze) - 1 then (x +1, y) :: nodes else nodes in
  let nodes = if y > 0 then (x, y -1) :: nodes else nodes in
  let nodes = if y < (height maze) - 1 then (x, y +1) :: nodes else nodes in
  nodes