(* Correction (version avancée) - 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 casesup i tab = (* cherche la plus petite valeur supérieure à i dans tab croissant *) let v = ref 16 in for j = Array.length tab - 1 downto 0 do if tab.(j) > i then v := tab.(j) done; !v - 1 ;; let caseinf i tab = (* cherche la plus grande valeur inférieure à i dans tab croissant *) let v = ref 0 in for j = 0 to Array.length tab - 1 do if tab.(j) <= i then v := tab.(j) done; !v ;; (* Déplacement de robot gêné par un autre robot ? *) let filter (l_orig,c_orig) (l_dest,c_dest) direction (l_ri, c_ri) = match direction with | '2' -> if c_ri = c_dest && l_orig < l_ri && l_ri <= l_dest then (l_ri - 1, c_dest) else (l_dest,c_dest) | '8' -> if c_ri = c_dest && l_orig > l_ri && l_ri >= l_dest then (l_ri + 1, c_dest) else (l_dest,c_dest) | '6' -> if l_ri = l_dest && c_orig < c_ri && c_ri <= c_dest then (l_dest, c_ri - 1) else (l_dest,c_dest) | '4' -> if l_ri = l_dest && c_orig > c_ri && c_ri >= c_dest then (l_dest, c_ri + 1) else (l_dest,c_dest) | _ -> failwith "impossible" let deplaceRobot i direction = let lig, col = robots.(i) in let lig2, col2 = (* la destination sans tenir compte des autres robots *) match direction with | '2' -> let obs = obs_c.(col) in let ldest = casesup lig obs in (ldest,col) | '6' -> let obs = obs_l.(lig) in let cdest = casesup col obs in (lig,cdest) | '8' -> let obs = obs_c.(col) in let ldest = caseinf lig obs in (ldest,col) | '4' -> let obs = obs_l.(lig) in let cdest = caseinf col obs in (lig,cdest) | _ -> Printf.printf "mouvement invalide (2-4-6-8)\n"; (lig,col) in let dest = ref (lig2,col2) in (* on tient compte des autres robots *) for j = 0 to Array.length robots - 1 do dest := filter (lig,col) !dest direction robots.(j) done; !dest ;; (* Démarrage du jeu *) (* NB : jeu fonctionnel 0 : robot rouge 1 : robot vert 2 : robot bleu 3 : robot jaune Déplacements au pavé numérique : 2(bas) 4(gauche) 6(droite) 8(haut) *) 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 if (irob >= 0 && irob <= 3) then begin let (lig, col) = deplaceRobot irob (Graphics.read_key ()) in Printf.printf "robot %d vers (%d %d)\n" irob lig col; teleporteRobot irob (lig, col); if (lig = lig_arriv && col = col_arriv && irob = 0) then vict := true end else Printf.printf "numéro de robot invalide\n"; done; Graphics.set_color Graphics.black; Graphics.moveto 353 400; Graphics.draw_string "!!! VICTOIRE !!!"; Printf.printf "Victoire !\n"; Graphics.read_key ();; jeu ();;