Commits

Anonymous committed 798a8bf

Game submodule with a state type

Comments (0)

Files changed (1)

 
 module Image = struct
   open Sdlloader
-    
+  
   let castle = ref None
   let knight = ref None
   let star = ref None
   let flag = ref None
   let bullet = ref None
-
-  let colors = [|"blue";"green";"orange";"pink";"purple";"red";"yellow" |]  
+  
+  let colors = [|"blue";"green";"orange";"pink";"purple";"red";"yellow" |]
   let select_color () =
     let index = Random.int (Array.length colors) in
     colors.(index)
   done
 
 (* interactions *)
-
-let solve screen maze goal start =
-  let open Sdlevent in
-  let open Sdlkey in
-  let path = Astar.Pathfinding.find_path maze start goal in
-  let walk path = List.iter (draw_bullet screen maze Image.star) path in
-  walk path;
-  let rec loop () =
-    match wait_event () with
-    | QUIT -> raise Escape
-    | KEYDOWN { keysym = KEY_ESCAPE } -> raise Escape
-    | KEYDOWN { keysym = KEY_SPACE } -> raise Break
-    | _ -> loop ()
-  in
-  try loop ()
-  with Break -> ()
-
-let rec interact screen maze goal start current =
-  let open Sdlevent in
-  let open Sdlkey in
-  draw_knight screen maze current;
+module Game = struct
+  type state = {
+    maze: char array array;
+    start: int * int;
+    goal: int * int;
+    player_position: int * int;
+    steps: int;
+  }
   
-  let next = match wait_event () with
-    | QUIT -> raise Escape
-    | KEYDOWN { keysym = KEY_ESCAPE } -> raise Escape
-    | KEYDOWN { keysym = KEY_SPACE } -> raise Break
-    | KEYDOWN { keysym = KEY_RIGHT } -> (fst current) +1, snd current
-    | KEYDOWN { keysym = KEY_LEFT } -> (fst current) -1, snd current
-    | KEYDOWN { keysym = KEY_UP } -> fst current, (snd current) -1
-    | KEYDOWN { keysym = KEY_DOWN } -> fst current, (snd current) +1
-    | _ -> current
-  in
-  if next = current then interact screen maze goal start current
-  else if not (Maze.check maze next) || Maze.get maze next = '#' then begin
-    Sfx.play Sfx.error;
-    interact screen maze goal start current
-  end
-  else begin
-    draw_bullet screen maze Image.bullet current;
-    if next = goal then (Sfx.play Sfx.success; raise Break)
-    else (Sfx.play Sfx.step; interact screen maze goal start next)
-  end
+  let init_state maze start goal = 
+    {maze=maze; start=start; goal=goal; player_position=start; steps=0}
+  
+  let solve screen state =
+    let open Sdlevent in
+    let open Sdlkey in
+    let path = Astar.Pathfinding.find_path state.maze state.start state.goal in
+    let walk path = List.iter (draw_bullet screen state.maze Image.star) path in
+    walk path;
+    let rec loop () =
+      match wait_event () with
+      | QUIT -> raise Escape
+      | KEYDOWN { keysym = KEY_ESCAPE } -> raise Escape
+      | KEYDOWN { keysym = KEY_SPACE } -> raise Break
+      | _ -> loop ()
+    in
+    try loop ()
+    with Break -> ()
+  
+  let rec interact screen state =
+    let open Sdlevent in
+    let open Sdlkey in
+    let position = state.player_position in
+    draw_knight screen state.maze position;
+    
+    let next = 
+      match wait_event () with
+      | QUIT -> raise Escape
+      | KEYDOWN { keysym = KEY_ESCAPE } -> raise Escape
+      | KEYDOWN { keysym = KEY_SPACE } -> raise Break
+      | KEYDOWN { keysym = KEY_RIGHT } -> (fst position) +1, snd position
+      | KEYDOWN { keysym = KEY_LEFT } -> (fst position) -1, snd position
+      | KEYDOWN { keysym = KEY_UP } -> fst position, (snd position) -1
+      | KEYDOWN { keysym = KEY_DOWN } -> fst position, (snd position) +1
+      | _ -> position
+    in
+    if next = position then interact screen state
+    else if not (Maze.check state.maze next) || Maze.get state.maze next = '#' then begin
+      Sfx.play Sfx.error;
+      interact screen state
+    end
+    else begin
+      draw_bullet screen state.maze Image.bullet position;
+      if next = state.goal then (Sfx.play Sfx.success; raise Break)
+      else (Sfx.play Sfx.step; interact screen {state with player_position=next; steps=succ state.steps})
+    end
+end
 
 (* main *)
 
       let maze, start, goal = generate_maze generator maze_width maze_height in
       Image.load (Image.select_color ());
       load_maze screen maze;
+      let state = Game.init_state maze start goal in
       try
-        interact screen maze goal start start
-      with Break -> solve screen maze goal start
+        Game.interact screen state
+      with Break -> Game.solve screen state
     done
   with Escape -> ()