(* Correction (version simple) TP07 : ricochet robots - partie 1 *)

(* description du plateau de jeu *)

let obs_l = [| [|0; 4; 10; 16|]; [|0; 14; 16|]; [|0; 6; 16|];
   [|0; 9; 16|]; [|0; 3; 15; 16|]; [|0; 7; 16|]; [|0; 1; 12; 16|]; [|0; 7; 9; 16|];
   [|0; 7; 9; 16|]; [|0; 4; 13; 16|]; [|0; 6; 16|]; [|0; 10; 16|]; [|0; 8; 16|];
   [|0; 2; 15; 16|]; [|0; 4; 10; 16|]; [|0; 5; 12; 16|] |];;

let obs_c = [| [|0; 5; 11; 16|]; [|0; 6; 13; 16|]; [|0; 4; 16|];
   [|0; 15; 16|]; [|0; 10; 16|]; [|0; 3; 16|]; [|0; 10; 16|]; [|0; 6; 7; 9; 12; 16|];
   [|0; 7; 9; 16|]; [|0; 3; 12; 16|]; [|0; 14; 16|]; [|0; 16|]; [|0; 7; 16|];
   [|0; 2; 10; 16|]; [|0; 4; 13; 16|]; [|0; 2; 12; 16|] |];;

(* affichage de la grille *)

let gray = Graphics.rgb 100 100 100;;

let affiche_grille () =
   Graphics.set_color gray;
   for j = 0 to 16 do
      Graphics.moveto 0 (j * 50);
      Graphics.lineto 800 (j * 50);
   done;
   for i = 0 to 16 do
      Graphics.moveto (i * 50) 0;
      Graphics.lineto (i * 50) 800;
   done;;;;

(* positionnement des murs *)
let mur (x0,y0) (x1,y1) =
   Graphics.set_line_width 3;
   Graphics.moveto x0 y0;
   Graphics.lineto x1 y1;
;;

let place_mur_V i sj =
   mur (50 * sj, 800 - 50 * i) (50 * sj, 800 - 50 * (i+1))
;;
let place_murs_ligne ()=
Graphics.set_color Graphics.red;
for i = Array.length obs_l - 1 downto 0 do
   let ligne = obs_l.(i) in
   for j = 0 to Array.length ligne - 1 do
     place_mur_V i ligne.(j)
   done
done;;

let place_mur_H si j =
   mur (50 * j, 800 - 50 * si) (50 * (j+1), 800 - 50 * si)
;;
let place_murs_colonne ()=
Graphics.set_color Graphics.red;
for j = 0 to Array.length obs_c - 1 do
   let colonne = obs_c.(j) in
   for i = 0 to Array.length colonne - 1 do
      place_mur_H colonne.(i) j
   done
done;;

(* position et couleurs des robots *)

let robots = [|(5,12); (0,0); (2,1); (4,7);|];;
let colors = [|Graphics.red; Graphics.green; Graphics.blue; Graphics.yellow;  |];;

let traceRobots () = 
   for i = 0 to Array.length robots - 1 do
      let (lig,col) = robots.(i) in
      Graphics.set_color colors.(i);
      Graphics.fill_circle (col*50 + 25) ((16-lig)*50 - 25)  20
   done;;

(* l'arrivée *)

let lig_arriv, col_arriv = (14,3);;

let traceArrivee () = 
   Graphics.set_color Graphics.black;
   Graphics.fill_rect (col_arriv*50 + 5) ((16-lig_arriv)*50 - 45) 40 40;;


(* déplacement *)

let teleporteRobot i (lig,col) = 
   let lig0, col0 = robots.(i) in
   Graphics.set_color Graphics.white;
   Graphics.fill_circle (col0*50 + 25) ((16-lig0)*50 - 25)  20;
   Graphics.set_color colors.(i);
   Graphics.fill_circle (col*50 + 25) ((16-lig)*50 - 25)  20;
   robots.(i) <- (lig, col)
;;

let deplaceRobot i direction = 
   if (i >= 0 && i < Array.length robots) then begin
    let (lig0, col0) = robots.(i) in
      let (lig, col) = match direction with
      | '8' -> (lig0-1, col0)
      | '2' -> (lig0+1, col0)
      | '4' -> (lig0, col0-1)
      | '6' -> (lig0, col0+1)
      | _ -> Printf.printf "direction invalide \n"; (lig0, col0)
      in teleporteRobot i (lig, col)
   end
;;

(* Démarrage du jeu *)
(* NB : déplacament des robots case par case, 
        sans tenir compte des murs, ni autres robots
        pas de controle de sortie du plateau,
        rattrapage des erreurs de saisie *)
let jeu () =
   Graphics.open_graph " 801x801";
   Graphics.set_window_title "Ricochet Robots";
   affiche_grille ();
   place_murs_ligne ();
   place_murs_colonne ();
   traceRobots ();
   traceArrivee ();
   let vict = ref false in
   while (not !vict) do
      let irob = int_of_char (Graphics.read_key ()) - 48 in
      let direction = Graphics.read_key () in
      deplaceRobot irob direction;
      if robots.(0) = (lig_arriv, col_arriv) then vict := true
   done;
   Printf.printf "Victoire !\n";;

jeu ();;