(* ===================================================== *)
(*      Apprentissage de la programmation avec OCaml     *)
(*      Catherine Dubois & Valérie Ménissier-Morain      *)
(*                Éditions Hermès Sciences               *)
(*                        Mars 2004                      *)
(* ===================================================== *)
(* Fichier MLSRC/CC/CC_ameliorations/evenements.ml       *)
(* ===================================================== *)

open Outils;;
open Graphics;;
open Representation;;
open Circuits;;
open Affichage_base;;
open Affichage_jeu;;
open Suggestion;;
open Action;;
open Backtrack;;
open Pause;;
open Highscores;;

let attente_niveau_suivant () =
  clear_graph ();
  let s1 = "POUR PASSER AU NIVEAU SUIVANT"
  and s2 = "APPUYER SUR UNE TOUCHE" in
  set_font "-*-helvetica-bold-r-*-*-24-*";
  let (_,h1)=text_size s1 in
  écrire_centré_fenêtre (2*h1+((size_y()-3*h1)/2)) s1;
  écrire_centré_fenêtre ((size_y()-3*h1)/2) s2;
  read_key(); ();;

let durée_niveau =
  [| 0.0; 56.0; 72.0; 96.0; 112.0; 128.0; 144.0 |];;

let niveau_maximum = 6;;

let dessiner_barre_progression () =
  let ld = largeur_cartouche-2*largeur_caractère in
  let
 gauche_cartouche =
    size_x() - largeur_cartouche+largeur_caractère in
  set_color foreground;
  draw_rect gauche_cartouche taille_pièce ld taille_pièce;;

let mise_à_jour_barre_progression t =
  let d = durée_niveau.(état.niveau) in
  let
 ld = largeur_cartouche-2*largeur_caractère in
  let
 lt = int_of_float ((t/.d)*.(float_of_int ld)) in
  let
 gauche_cartouche =
    size_x() - largeur_cartouche+largeur_caractère in
  set_color foreground;
  fill_rect gauche_cartouche taille_pièce lt (taille_pièce-2);;

let vider_file () =
  while key_pressed () do read_key () done;;

let réaction_clic mp =
  let (c,l) = position_zone_de_jeu mp in
  if position_pièce_zone_de_jeu_valide (c, l)
  then
    match
 état.sélection with
    | None -> sélectionner (c,l)
    | Some (c',l') ->
        if (c',l') = (c,l)
        then désélectionner (c,l)
        else éliminer (c,l) (c',l');;

let attente_touche () =
  vider_file();
  écrire_centré_fenêtre 10 "APPUYER SUR UNE TOUCHE POUR CONTINUER";
  read_key(); ();;

let affichage_scores scores =
  let temps = Unix.gettimeofday () -. état.temps_référence in
    affichage_meilleurs_scores scores;
    attente_touche ();
    clear_graph();
    dessiner_zone_de_jeu();
    état.temps_référence <- Unix.gettimeofday() -. temps;
    dessiner_cartouche ();
    dessiner_barre_progression ();
    match état.sélection with
    | None -> ()
    | Some (c,l) -> dessiner_sélection (coordonnées_pièce (c,l));;

exception Nouveaujeu;;

let gestion_événements_joueur s =
  if s.button then
    begin
    while
 button_down () do () done;
    réaction_clic (s.mouse_x,s.mouse_y)
    end
  else (* touche frappée *)
    match
 s.key with
    | 'q' -> exit 0
    | 's' -> (vider_file (); suggestion ())
    | 'b' -> (vider_file (); étape_backtrack ())
    | 'p' -> pause ()
    | 'h' -> (vider_file (); affichage_scores (lire_fichier_scores()))
    | 'm' -> (vider_file (); état.muet <- not état.muet)
    | 'c' -> (vider_file ();
              état.couleurs <- not état.couleurs;
              dessiner_zone_de_jeu ();
              match état.sélection with
              | None -> ()
              | Some (c,l) -> dessiner_sélection (coordonnées_pièce (c,l)))
    | 't' -> (vider_file ();
              état.touches <- not état.touches;
              dessiner_cartouche ())
    | 'n' -> raise Nouveaujeu
    | _ -> vider_file ();;

let trame_temporelle t =
  let s = wait_next_event [Key_pressed; Button_down; Poll] in
  if s.button || s.keypressed
  then gestion_événements_joueur s
  else if Unix.gettimeofday () -. !t >= 1.0 then
    begin
      mise_à_jour_barre_progression
        (Unix.gettimeofday() -. état.temps_référence);
      t := floor (Unix.gettimeofday ());
    end;;

let augmentation_score () =
  let d = ref (Unix.gettimeofday()-.état.temps_référence) in
  let
 incrément = 10*état.niveau*état.niveau in
  while !d < durée_niveau.(état.niveau) do
    d := !d+.1.0;
    mise_à_jour_barre_progression !d;
    état.score <- état.score + incrément;
    affichage_score ();
    sleep 0.01;
  done;;

let fin_jeu () =
  let scores = lire_fichier_scores () in
  mise_à_jour_tableau_scores scores;
  écrire_fichier_scores scores;
  affichage_meilleurs_scores scores;
  attente_touche ();;

let rec demande_continuer () =
  clear_graph();
  set_font "-*-helvetica-bold-r-normal--24-*";
  set_color foreground;
  écrire_centré_fenêtre (size_y()/2) "Voulez-vous rejouer? (o/n)";
  let c = read_key () in
  draw_char c;
  match Char.lowercase c with
  | 'o' -> true
  | 'n' -> false
  | _ -> demande_continuer ();;

let jeu () =
  Random.self_init ();
  état.sélection <- None;
  état.niveau <- 0;
  état.score <- 0;
  open_graph "";
  set_window_title "Court circuit";
  état.temps_référence <- Unix.gettimeofday();
  while état.niveau < niveau_maximum do
    état.historique <- [];
    état.niveau <- état.niveau+1;
    état.temps_référence <- Unix.gettimeofday();
    nouvelle_zone_de_jeu ();
    clear_graph ();
    dessiner_zone_de_jeu ();
    dessiner_cartouche ();
    dessiner_barre_progression ();
    let t = ref état.temps_référence in
    while Unix.gettimeofday() -. état.temps_référence
          < durée_niveau.(état.niveau)
      && not (zone_de_jeu_vide ()) do
        trame_temporelle t;
    done;
    if Unix.gettimeofday() -. état.temps_référence
       <= durée_niveau.(état.niveau)
    then
      begin
        augmentation_score ();
        affichage_score();
        Unix.sleep 1;
        if état.niveau < niveau_maximum
        then attente_niveau_suivant();
      end
    else (if not état.muet then sound 200 500; fin_jeu (); exit 0)
  done;
  fin_jeu ();;

let jeux () =
  let continuer = ref true in
  while !continuer do
    try

      jeu ();
      continuer := demande_continuer ();
    with Nouveaujeu -> ();
  done;;

jeux();;

Ce document a été traduit de LATEX par HEVEA.