(* ===================================================== *)
(* Apprentissage de la programmation avec OCaml *)
(* Catherine Dubois & Valérie Ménissier-Morain *)
(* Éditions Hermès Sciences *)
(* Mars 2004 *)
(* ===================================================== *)
(* Fichier MLSRC/CC/CC_base_modulaire/circuits.ml *)
(* ===================================================== *)
open Outils;;
open Representation;;
let case_vide (c,l) = zone_de_jeu.(c).(l)=Vide;;
let cases_jointes_segment_vertical (c1,l1) (c2,l2) =
c1 = c2 &&
let (minl, maxl) =
if l1 < l2 then (l1, l2) else (l2, l1) in
(* il n'y a pas de case intermédiaire *)
maxl <= minl+1
|| (* toutes les cases intermédiaires sont vides *)
(List.for_all case_vide
(List.map (function l -> (c1, l))
(interval (minl+1) (maxl-1))));;
let cases_jointes_segment_horizontal (c1,l1) (c2,l2) =
l1 = l2 &&
let (minc, maxc) =
if c1 < c2 then (c1, c2) else (c2, c1) in
(* il n'y a pas de case intermédiaire *)
maxc <= minc+1
|| (* toutes les cases intermédiaires sont vides *)
(List.for_all case_vide
(List.map (function c -> (c, l1))
(interval (minc+1) (maxc-1))));;
let cases_jointes_segment_hv (c1,l1) (c2,l2) =
cases_jointes_segment_vertical (c1,l1) (c2,l2)
|| cases_jointes_segment_horizontal (c1,l1) (c2,l2);;
let rec cases_jointes_circuit_n_angles (c1,l1) (c2,l2) n =
if n = 0 (* Cas de base de la récursivité *)
then cases_jointes_segment_hv (c1,l1) (c2,l2)
else
List.exists
(function l ->
case_vide (c1,l)
&& cases_jointes_segment_vertical (c1,l1) (c1,l)
&& cases_jointes_circuit_n_angles (c1,l) (c2,l2) (n-1))
(interval_sans l1 l2 0 (nb_lignes-1))
|| List.exists
(function c ->
case_vide (c,l1)
&& cases_jointes_segment_horizontal (c1,l1) (c,l1)
&& cases_jointes_circuit_n_angles (c,l1) (c2,l2) (n-1))
(interval_sans c1 c2 0 (nb_colonnes-1));;
let rec cases_jointes_circuit_au_plus_n_angles (c1,l1) (c2,l2) n =
if n = 0
then cases_jointes_segment_hv (c1,l1) (c2,l2)
else
cases_jointes_circuit_au_plus_n_angles (c1,l1) (c2,l2) (n-1)
|| cases_jointes_circuit_n_angles (c1,l1) (c2,l2) n;;
let circuit_segment_vertical (c1,l1) (c2,l2) =
if cases_jointes_segment_vertical (c1,l1) (c2,l2)
then
if c1 <> c2 || l1 <> l2
then [(c1,l1);(c2,l2)]
else [(c1,l1)]
else raise Not_found;;
let circuit_segment_horizontal (c1,l1) (c2,l2) =
if cases_jointes_segment_horizontal (c1,l1) (c2,l2)
then
if c1 <> c2 || l1 <> l2
then [(c1,l1);(c2,l2)]
else [(c1,l1)]
else raise Not_found;;
let circuit_segment (c1,l1) (c2,l2) =
if cases_jointes_segment_vertical (c1,l1) (c2,l2)
|| cases_jointes_segment_horizontal (c1,l1) (c2,l2)
then
if c1 <> c2 || l1 <> l2
then [(c1,l1);(c2,l2)]
else [(c1,l1)]
else raise Not_found;;
let rec circuit_n_angles (c1,l1) (c2,l2) n =
if n = 0 (* Cas de base de la récursivité *)
then circuit_segment (c1,l1) (c2,l2)
else
try
let ligne =
List.find
(function l ->
case_vide (c1, l) &&
cases_jointes_segment_vertical (c1,l1) (c1,l) &&
cases_jointes_circuit_n_angles (c1,l) (c2,l2) (n-1))
(interval_sans l1 l2 0 (nb_lignes-1)) in
(c1, l1)::(circuit_n_angles (c1,ligne) (c2,l2) (n-1))
with Not_found ->
let colonne =
List.find
(function c ->
case_vide (c, l1) &&
cases_jointes_segment_horizontal (c1,l1) (c,l1)
&& cases_jointes_circuit_n_angles (c,l1) (c2,l2) (n-1))
(interval_sans c1 c2 0 (nb_colonnes-1)) in
(c1, l1)::(circuit_n_angles (colonne,l1) (c2,l2) (n-1));;
let rec circuit_au_plus_n_angles (c1,l1) (c2,l2) n =
if n = 0
then circuit_segment (c1,l1) (c2,l2)
else
try circuit_au_plus_n_angles (c1,l1) (c2,l2) (n-1)
with Not_found -> circuit_n_angles (c1,l1) (c2,l2) n;;
let circuit_valide (c1,l1) (c2,l2) =
match zone_de_jeu.(c1).(l1), zone_de_jeu.(c2).(l2) with
| Vide, _ | _, Vide -> []
| Occupée coul1, Occupée coul2 ->
if coul1 = coul2
then
try
circuit_au_plus_n_angles (c1,l1) (c2,l2) 2
with Not_found -> []
else [];;
Ce document a été traduit de LATEX par
HEVEA.