Source

ocaml-toys / maze / gfx.ml

Full commit
exception Break

let pixel = 32

let load_maze maze name = 
  Graphics.set_window_title ("Maze solver - " ^ name);
  let width = Maze.width maze and height = Maze.height maze in
  Graphics.resize_window (width*pixel) (height*pixel);
  let gray = Graphics.rgb 150 150 150 in
  for x = 0 to width -1 do
    for y = 0 to height - 1 do
      let tile = Maze.get maze (x, y) in
      let color = match tile with
        | '@' -> Graphics.red
        | 'X' -> Graphics.green
        | '#' -> gray
        | _ -> Graphics.white
      in
      Graphics.set_color color;
      Graphics.fill_rect (x*pixel) ((height-1-y)*pixel) pixel pixel;
      Graphics.set_color gray;
      Graphics.draw_rect (x*pixel) ((height-1-y)*pixel) pixel pixel;
    done
  done 

let draw_dot maze (x, y) = 
  let shift = pixel / 2 in
  let half = shift / 2 in
  let height = Maze.height maze in
  if Maze.get maze (x, y) <> '#' then Graphics.fill_rect 
    (x*pixel + half) ((height-y-1)*pixel + half) shift shift

let walk maze path =
  Graphics.set_color Graphics.blue;
  List.iter (draw_dot maze) path

let solve maze goal start = 
  let path = Astar.Pathfinding.find_path maze start goal in
  walk maze path;
  while Graphics.read_key() != ' ' do
    ()
  done

let rec interact maze goal start current =
  Graphics.set_color Graphics.black;
  draw_dot maze current; 
  
  let key = Graphics.read_key() in
  if key = 'k' then raise Break
  else if key = ' ' then solve maze goal start
  else begin
    let next = match key with
      | '6' -> (fst current) +1, snd current
      | '4' -> (fst current) -1, snd current
      | '8' -> fst current, (snd current) -1
      | '2' -> fst current, (snd current) +1
      | _ -> current
    in
    if not (Maze.check maze next) || Maze.get maze next = '#' then begin 
      interact maze goal start current
    end
    else begin
      Graphics.set_color 0xffc600;
      draw_dot maze current;
      if next = goal then solve maze goal start
      else interact maze goal start next
    end       
  end
                           
let _ =
  Random.self_init ();
  Graphics.open_graph "";
  try
    while true do
	    let maze, start, goal = Generator.generate 15 11 in
	    load_maze maze "auto";
      interact maze goal start start
    done
  with Break -> ()