type coup = Coop | Trahi type strat = coup list -> coup list -> coup type param = int * int * int * int let bisounours moi autre = Coop let traitre moi autre = Trahi let sympa_irl moi autre = match moi with | Coop :: Coop :: _ -> Trahi | _ -> Coop let _ = let rec test_Q2 l n = match n with | 0 -> l | _ -> test_Q2 (sympa_irl l [] :: l) (n-1) in test_Q2 [] 9 let partie n (strat1:strat) (strat2:strat) = let rec boucle l1 l2 n = match n with | 0 -> (l1, l2) | _ -> let coup1 = strat1 l1 l2 in let coup2 = strat2 l2 l1 in boucle (coup1 :: l1) (coup2 :: l2) (n-1) in boucle [] [] n let _ = partie 4 traitre sympa_irl let score ((t,c,p,d):param) l1 l2 = let rec boucle l1 l2 s1 s2 = match l1,l2 with | [], [] -> s1, s2 | [], t::q | t::q, [] -> raise (Invalid_argument "les listes n'ont pas la même taille") | c1::q1, c2::q2 -> match c1,c2 with | Coop, Coop -> boucle q1 q2 (s1+c) (s2+c) | Trahi, Trahi -> boucle q1 q2 (s1+p) (s2+p) | Coop, Trahi -> boucle q1 q2 (s1+d) (s2+t) | Trahi, Coop -> boucle q1 q2 (s1+t) (s2+d) in boucle l1 l2 0 0 let _ = let l_traitre, l_sympa = partie 5 traitre sympa_irl in score (5,3,1,0) l_traitre l_sympa let rancunier moi autre = let rec aux autre = match autre with | [] -> Coop | Trahi::q -> Trahi | t::q -> aux q in aux autre let _ = rancunier [] [Coop; Coop; Coop; Coop; Coop] let _ = rancunier [] [Coop; Coop; Trahi; Coop; Coop] let miroir_gentil moi autre = match autre with | [] -> Coop | t::q -> t let _ = miroir_gentil [] [] let _ = miroir_gentil [] [Trahi; Coop; Coop] let _ = miroir_gentil [] [Coop; Trahi; Trahi] let miroir_mechant moi autre = match autre with | [] -> Trahi | t::q -> t let _ = miroir_mechant [] [] let _ = miroir_mechant [] [Trahi; Coop; Coop] let _ = miroir_mechant [] [Coop; Trahi; Trahi] let majorite moi autre = let rec aux autre nb_coop nb_trahi = match autre with | Coop::q -> aux q (nb_coop+1) nb_trahi | Trahi::q -> aux q nb_coop (nb_trahi+1) | [] -> if nb_trahi > nb_coop then Trahi else Coop in aux autre 0 0 let _ = majorite [] [] let _ = majorite [] [Trahi; Coop] let _ = majorite [] [Coop; Trahi; Trahi] let mastermind moi autre = match autre with | [] -> Trahi | [_] | [_;_] -> Coop | t::_ -> let rec aux autre = match autre with | [Coop; Coop; Coop] -> Trahi | [_;_;_] -> t | _::q -> aux q | _ -> assert false (* cas impossible *) in aux autre let _ = mastermind [] [] let _ = mastermind [] [Coop] let _ = mastermind [] [Coop; Coop] let _ = mastermind [] [Coop; Coop; Coop] let _ = mastermind [] [Trahi; Coop; Coop] let indecis p : strat = fun moi autre -> let x = Random.float 1. in if x < p then Coop else Trahi let _ = let test = indecis 0.5 in let rec test_Q6 l n = match n with | 0 -> l | _ -> test_Q6 (test l [] :: l) (n-1) in test_Q6 [] 9 let tournoi params strats = let nb_strats = Array.length strats in let scores = Array.make nb_strats 0 in let nb_tours = 500 + Random.int 501 in for i = 0 to nb_strats - 1 do for j = i+1 to nb_strats - 1 do let coups_i, coups_j = partie nb_tours strats.(i) strats.(j) in let score_i, score_j = score params coups_i coups_j in scores.(i) <- scores.(i) + score_i; scores.(j) <- scores.(j) + score_j done done; scores exception Perdu_J1 exception Perdu_J2 let partie n (strat1:strat) (strat2:strat) = let rec boucle l1 l2 n = match n with | 0 -> (l1, l2) | _ -> let coup1 = try strat1 l1 l2 with _ -> raise Perdu_J1 in let coup2 = try strat2 l2 l1 with _ -> raise Perdu_J2 in boucle (coup1 :: l1) (coup2 :: l2) (n-1) in boucle [] [] n let tournoi params strats = let nb_strats = Array.length strats in let scores = Array.make nb_strats 0 in let nb_tours = 500 + Random.int 501 in for i = 0 to nb_strats - 1 do for j = i+1 to nb_strats - 1 do try let coups_i, coups_j = partie nb_tours strats.(i) strats.(j) in let score_i, score_j = score params coups_i coups_j in scores.(i) <- scores.(i) + score_i; scores.(j) <- scores.(j) + score_j with | Perdu_J1 -> scores.(j) <- scores.(j) + 10000 | Perdu_J2 -> scores.(i) <- scores.(i) + 10000 done done; scores