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

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

let écrire_centré_fenêtre haut s =
  let (w,h)= text_size s in
  moveto ((size_x()-w)/2) (haut-h/2);
  draw_string s;;

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 =
  [| 56.0; 72.0; 96.0; 112.0; 128.0; 144.0 |];;

let niveau_maximum = 5;;

let dessiner_barre_progression () =
  let ld = largeur_cartouche-2*largeur_caractère in
  let
 gauche_cartouche =
    size_x() - largeur_cartouche+largeur_caractère in
  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
  fill_rect gauche_cartouche taille_pièce lt taille_pièce;;

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 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 ()
    | _ -> 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 jeu () =
  Random.self_init ();
  état.sélection <- None;
  état.niveau <- 0;
  open_graph "";
  set_window_title "Court circuit";
  état.temps_référence <- Unix.gettimeofday();
  while état.niveau < niveau_maximum do
    état.niveau <- état.niveau+1;
    état.historique <- [];
    é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)
      && état.niveau < niveau_maximum
    then attente_niveau_suivant()
    else (print_string "Le temps imparti est terminé\n"; exit 0)
  done;
  exit 0;;

jeu();;

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