(*** type monstre ******************************************************) (* définition du type *) type monstre = string * int * int * int;; (* constructeur du type *) let (creerMonstre : string->int->int->int->monstre) = function n -> function a -> function b -> function c -> if a<0 or b<0 or c<0 then failwith ("le monstre "^n^" ne peut pas être créé") else (n,a,b,c);; (* accesseurs du type *) let (nom : monstre->string) = function (n,a,b,c) -> n;; let (oeil : monstre->int) = function (n,a,b,c) -> a;; let (bouche : monstre->int) = function (n,a,b,c) -> b;; let (pate : monstre->int) = function (n,a,b,c) -> c;; (*** bébés *************************************************************) (* croisement génétique *) let (croisement : monstre->monstre->monstre) = function m1 -> function m2 -> creerMonstre (nom m1^nom m2) (oeil m1+oeil m2) (bouche m1+bouche m2) (pate m1+pate m2);; (* fonction intermédiaire, pour faciliter l'écriture de reproduction *) (* le plus petit des arguments est le premier élément du couple *) (* le plus grand des arguments est le deuxième élément du couple *) let minmax a b = if a < b then (a,b) else (b,a);; (* pour avoir un nombre aléatoire appartenant à [A,B], *) (* on prend un nombre aléatoire entre 0 et (B-A+1) *) (* et on ajoute A à ce nombre *) let (reproduction : monstre->monstre->monstre) = function m1 -> function m2-> let am,aM = minmax (oeil m1) (oeil m2) and bm,bM = minmax (bouche m1) (bouche m2) and cm,cM = minmax (pate m1) (pate m2) in let na = am + Random.int (aM-am+1) and nb = bm + Random.int (bM-bm+1) and nc = cm + Random.int (cM-cm+1) in if na = oeil m1 & nb = bouche m1 & nc = pate m1 then m1 else if na = oeil m2 & nb = bouche m2 & nc = pate m2 then m2 else creerMonstre (nom m1^nom m2) na nb nc;; (*** classer les monstres **********************************************) (* prend un nom de monstre (string) et une liste de monstre (monstre list) *) (* et compte le nombre de fois où ce monstre se trouve dans la liste *) let rec (compterMonstreV1 : string->monstre list->int) = function nm -> function [] -> 0 |t::r -> if ((nom t) = nm) then 1 + compterMonstreV1 nm r else compterMonstreV1 nm r;; (* ou *) let rec compterMonstreV2 nm = function [] -> 0 |t::r -> if ((nom t) = nm) then 1 + compterMonstreV2 nm r else compterMonstreV2 nm r;; (* ou *) let rec compterMonstreV3 nm l = match l with [] -> 0 |t::r -> if ((nom t) = nm) then 1 + compterMonstreV3 nm r else compterMonstreV3 nm r;; (* fait une liste avec tous les monstres de la liste de départ qui satisfont *) (* le critère de recherche fonction accesseur/valeur *) let rec (rechercheMonstre : monstre list->(monstre->int)->int->monstre list) = function l -> function access -> function valeur -> match l with [] -> [] |t::r -> if ((access t) = valeur) then t::(rechercheMonstre r access valeur) else rechercheMonstre r access valeur;; (* ou *) let rec rechercheMonstreV2 access valeur = function [] -> [] |t::r -> if ((access t) = valeur) then t::(rechercheMonstreV2 access valeur r) else rechercheMonstreV2 access valeur r;; (* cette fonction s'appelle simplement par rechercheMonstreV2 oeil 3 listeMonstre *) (* oeil étant défini au préalable *) (* fonction intermédiaire pour la fonction bonus : *) (* oui ou non un monstre est-il présent dans la liste *) let rec (estPresent : monstre->monstre list->bool) = function m -> function [] -> false |t::r -> if t=m then true else estPresent m r;; (* fonction naïve qui supprime les doublons dans la liste de monstre *) let rec (supprDoublons : monstre list->monstre list) = function [] -> [] |t::r -> if estPresent t r then supprDoublons r else t::(supprDoublons r);;