(* -*-compile-command: "ocamlopt str.cmxa graphics.cmxa cc4.ml -cclib -lstr -cclib -lgraphics -ccopt -L/usr/X11R6/lib -cclib -lX11"; -*- *) let debug = ref false;; let autoplay = true;; let movenum = ref 0;; (* Nombres de longueur n en base b *) let go b n = let rec encore mot k reste = if k = n then mot :: reste else let rec encoreencore i reste = if i = b then reste else encoreencore (i+1) (encore (i::mot) (k+1) reste) in encoreencore 0 reste in encore [] 0 [];; let vide =0;; let dec = 17*7;; let oppcol = function 1 -> 2 | 2 -> 1 | _ -> failwith "oppcol";; (* Gestion des tables de hachage *) let hashvals = Array.init 17 (fun _ -> Array.init 17 (fun _ -> Array.init 2 (fun _ -> Array.init 2 (fun _ -> Random.bits ()))));; let whose_turn = Array.init 2 (fun _ -> Array.init 2 (fun _ -> Random.bits ()));; type hashval_struct = { mutable v0 : int; mutable v1 : int};; let hashval = {v0=0;v1=0};; let compute_hash (x,y) color = hashval.v0 <- hashval.v0 lxor hashvals.(x).(y).(color-1).(0); hashval.v1 <- hashval.v1 lxor hashvals.(x).(y).(color-1).(1);; let hash_size = 1 lsl 20;; let hash_mask = hash_size-1;; type hash_struct = { v_h : hashval_struct; mutable m_num : int; mutable prof : int; mutable low : int; mutable high : int};; let hashtable = Array.create hash_size None;; let zero_hash () = for i = 0 to hash_size -1 do hashtable.(i)<-None done;; let find_hash p maxp = match hashtable.(hashval.v0 land hash_mask) with None -> None | Some {v_h=v_h;prof=prof;m_num=m_num;low=low;high=high} as toto -> if v_h = hashval & m_num = !movenum+maxp then toto else None;; let modify_hash toto l h p maxp = match toto with None -> let ind = hashval.v0 land hash_mask in (match hashtable.(ind) with None -> hashtable.(ind) <- Some {v_h={v0=hashval.v0;v1=hashval.v1};m_num= !movenum+maxp;prof=p;low=l;high=h} | Some x-> if x.prof > p or x.m_num < (!movenum+maxp) then begin x.prof <-p;x.low<-l;x.high<-h;x.m_num <- !movenum+maxp; x.v_h.v0<-hashval.v0;x.v_h.v1<-hashval.v1; end) | Some c -> if l <> -32768 then c.low <- l; if h <> 32768 then c.high <- h;; (* Fin table de hachage *) (* Representation de l'etoile en 3 exemplaires, un par ligne, un pour*) (* la diagonale partant de droite et un pour la diagonale partant de*) (* gauche *) (* On code sur 18 bits soit 9x2bits. Une case vide est code par 00,*) (* une case contenant des O par 01 et une case contenant des X par*) (* 10. *) let lines = Array.create 17 0 and diag1 = Array.create 17 0 and diag2 = Array.create 17 0;; let save_pos () = (Array.copy lines,Array.copy diag1,Array.copy diag2);; let restore_pos (l,d1,d2) = Array.iteri (fun i x -> lines.(i)<-x) l; Array.iteri (fun i x -> diag1.(i)<-x) d1; Array.iteri (fun i x -> diag2.(i)<-x) d2;; (* Tables contenant les coups jouables directement ou par rebond sur*) (* une structure de pions donnees. L'indice correspond au codage de la*) (* position sur 18 bits.*) (* Le tableau diago contient les informations pour les diagonales*) (* quand c'est au O de jouer (les O vont vers le haut), et ainsi de*) (* suite. *) (* Le principe de codage de chaque chaine est le suivant: les 17*7 *) (* premieres valeurs sont la liste des cases que l'on peut atteindre *) (* lorsque l'on atterrit sur la case d'indice i, i variant de 0 a *) (* 16. Il ne peut pas y en avoir plus de 7 par case. Ces valeurs sont*) (* utilises pour les "rebonds", c.a.d pour un coup transitant par*) (* cette zone apres un saut et pouvant (ou devant) repartir. *) (* Le reste de la chaine est une suite de couple (o,d), qui est la*) (* liste des coups jouables lorsque l'on part de cette zone, sous la*) (* forme origine,destination *) let diago = Array.create (1 lsl 18) "" and diagx = Array.create (1 lsl 18) "" and lineso = Array.create (1 lsl 18) "" and linesx = Array.create (1 lsl 18) "";; (* Tables contenant les correspondances d'indices entre les trois*) (* representations de l'etoile. cdiag1 est de la forme (i,j,k,l) ou*) (* (i,j) sont les indices de diag2 et (k,l) de ligne; Pour cdiag2,*) (* (i,j,k,l): (i,j) diag1, (k,l) ligne. Pour clines, (i,j,k,l): (i,j)*) (* diag1, (k,l) diag2 *) let cdiag1 = Array.create_matrix 17 17 (-1,-1,-1,-1) and cdiag2 = Array.create_matrix 17 17 (-1,-1,-1,-1) and clines = Array.create_matrix 17 17 (-1,-1,-1,-1);; (* Tableaux d'indices autorises et jouables, pour chaque ligne et*) (* chaque diagonale. De la forme (i,j,k,l) ou i est l'indice du plus*) (* petit coup autorise, et j l'indice du plus grand coup autorise. k*) (* est l'indice du plus petit coup jouable et l l'indice du plus grand*) (* coup jouable. Un coup est jouable si le pion a le droit de*) (* s'arreter sur la case, et autorise quand il a le droit d'y venir*) (* mais doit obligatoirement en repartir.*) let idiags = Array.create 17 (0,0,0,0) and ilines = Array.create 17 (0,0,0,0);; (* Initialisation de la position *) let init_pos () = for i = 0 to 16 do diag1.(i)<-0; diag2.(i)<-0; lines.(i)<-0; done; for i = 0 to 3 do for j = 4 to i+4 do lines.(i)<- lines.(i) lor (1 lsl (2*(j-4))); let (d1i,d1j,d2i,d2j) = clines.(i).(j) in diag1.(d1i)<-diag1.(d1i) lor (1 lsl (2*(d1j-4))); diag2.(d2i)<-diag2.(d2i) lor (1 lsl (2*(d2j-4))); done; done; for i = 13 to 16 do for j = 4 to 4+16-i do let (d1i,d1j,d2i,d2j) = clines.(i).(j) in lines.(i)<- lines.(i) lor (2 lsl (2*(j-4))); diag1.(d1i)<-diag1.(d1i) lor (2 lsl (2*(d1j-4))); diag2.(d2i)<-diag2.(d2i) lor (2 lsl (2*(d2j-4))); done; done;; let inv_conv x y = let i = y/30 and xcl = x/20 in let j = if i<=3 then (xcl+i-12)/2+4 else if i<=8 then (xcl+i-4)/2 else if i<=12 then (xcl+12-i)/2 else 4+(xcl-i+4)/2 in (i,j);; let convert_line i j = if i<=3 then 2*(j-4)+(12-i) else if i<=8 then (i-4) + (j-(i-4))*2 else if i<=12 then (12-i) + (j-(12-i))*2 else 2*(j-4)+(i-4);; let affiche i j v = let c = match v with 0 -> Graphics.black | 1 -> Graphics.red | 2 -> Graphics.green | _ -> failwith "affiche" in Graphics.set_color c; let y = i*30+15 and x = (convert_line i j)*20+15 in Graphics.fill_circle x y 10;; let iter_lignes fonc = for i = 0 to 16 do let (j1,j2,_,_) = ilines.(i) in for j = j1 to j2 do let decal = (j-4)*2 in let v = (lines.(i) lsr decal) land 3 in fonc i j v done; done;; let affiche_tout () = iter_lignes affiche;; let f color table table2 x = let tab = Array.of_list x in let checkpos i m p = try ( if (p<0) or ((p>=0 && p<9) && tab.(p) <> vide) or (m<0 or m>=9 or tab.(m)=vide) then false else ( for j = max (i+1) 0 to min (m-1) 8 do if tab.(j)<>vide then raise Exit; done; for j = max (m+1) 0 to min (p-1) 8 do if tab.(j)<>vide then raise Exit; done; true)) with Exit -> false in let rec checkiter o i l = for j=1 to (12-i)/2 do let p = i+j*2 in if (checkpos i (i+j) p) then ( l := (o,p) :: (!l); checkiter o p l) done in let l = ref [] in for i = 0 to 7 do if tab.(i)=color then ( if tab.(i+1)=vide then l := (i,(i+1)) :: (!l); checkiter i i l); done; l := Sort.list (fun (x0,y0) (x1,y1) -> (y1-x1)<(y0-x0)) !l; let cpt = ref dec and s = String.make (dec+2*(List.length !l)) (Char.chr 255)in List.iter (fun (x,y) -> s.[!cpt]<-Char.chr (x+4);incr cpt; s.[!cpt]<-Char.chr (y+4);incr cpt) !l; let l = ref [] in for i = -4 to 7 do if i<0 or tab.(i)=vide then checkiter i i l; done; l := Sort.list (fun (x0,y0) (x1,y1) -> if x1>x0 then true else if x1 s.[7*(x+4)+ind.(x+4)]<-Char.chr (y+4);ind.(x+4)<-ind.(x+4)+1) !l; let m = ref 0 and m2 = ref 0 and n = (Array.length tab)-1 and s2 = String.make (String.length s) (Char.chr 255) in Array.iteri (fun i x -> m := !m lor (x lsl (2*i)); match x with 1 -> m2 := !m2 lor (2 lsl (2*(n-i))) | 2 -> m2 := !m2 lor (1 lsl (2*(n-i))) | _ -> ()) tab; table.(!m)<-s; for i = 0 to 16 do for j = 0 to 6 do let v = Char.code s.[i*7+j] in if v<>255 then s2.[(16-i)*7+j]<-Char.chr (16-v) done; done; for i = dec to String.length s -1 do s2.[i]<-Char.chr (16-(Char.code s.[i])) done; table2.(!m2)<-s2;; let g table table2 table3 table4 x = let tab = Array.of_list x and m = ref 0 and m2 = ref 0 in let n = Array.length tab -1 in Array.iteri (fun i x -> m := !m lor (x lsl (2*i)); match x with 1 -> m2 := !m2 lor (2 lsl (2*(i))) | 2 -> m2 := !m2 lor (1 lsl (2*(i))) | _ -> ()) tab; let s1 = table.(!m) and s2 = table2.(!m2) in let s3 = String.make (String.length s1 + String.length s2 - dec) (Char.chr 255) in for i = 0 to 16 do let k = ref 0 in for j = 0 to 6 do let v = Char.code s1.[i*7+j] in if v <> 255 then (s3.[i*7+ !k]<-Char.chr v;incr k) done; for j = 0 to 6 do let v = Char.code s2.[i*7+j] in if v <> 255 then (s3.[i*7+ !k]<-Char.chr v;incr k) done; done; let k = ref dec in for i = 0 to (String.length s1 -dec)/2-1 do s3.[!k] <- s1.[dec+2*i];incr k; s3.[!k] <- s1.[dec+2*i+1];incr k done; for i = 0 to (String.length s2 -dec)/2-1 do s3.[!k] <- s2.[dec+2*i];incr k; s3.[!k] <- s2.[dec+2*i+1];incr k done; table3.(!m)<-s3; table4.(!m2)<-s3;; let init_tables () = let color = 1 in List.iter (f color diago diagx) (go 3 9); List.iter (g diago diagx lineso linesx) (go 3 9); let fic = open_in "matches" in (try ( while true do let st = input_line fic in let l = Str.split (Str.regexp "[ \t]+") st in let a = Array.of_list (List.map int_of_string l) in cdiag1.(a.(0)).(a.(1)) <- (a.(2),a.(3),a.(4),a.(5)); cdiag2.(a.(2)).(a.(3)) <- (a.(0),a.(1),a.(4),a.(5)); clines.(a.(4)).(a.(5)) <- (a.(0),a.(1),a.(2),a.(3)); done; raise Exit) with End_of_file -> ()); close_in fic; let fic = open_in "diags" in for i = 0 to 16 do let st = input_line fic in let l = Str.split (Str.regexp "[ \t]+") st in match List.map int_of_string l with i1::i2::i3::i4::_ -> idiags.(i) <- (i1,i2,i3,i4) | _ -> failwith "init_tables" done; close_in fic; let fic = open_in "lines" in for i = 0 to 16 do let st = input_line fic in let l = Str.split (Str.regexp "[ \t]+") st in match List.map int_of_string l with i1::i2::i3::i4::_ -> ilines.(i) <- (i1,i2,i3,i4) | _ -> failwith "init_tables" done; close_in fic;; let print_elt ind elt = try ( let j = ref ind and s = ref "" in for i = 0 to 8 do (match (!j land 3) with 0 -> s:= !s^" ." | 1 -> s:= !s^" O" | 2 -> s:= !s^" X" | 3 -> raise Exit | _ -> ()); j := !j lsr 2 done; print_string !s; for i = 0 to (String.length elt -dec)/2-1 do Printf.printf " (%2d,%2d)" (Char.code elt.[dec+2*i]) (Char.code elt.[dec+2*i+1]); done; for i = 0 to 16 do print_string " ["; for j = 0 to 6 do let v = Char.code elt.[i*7+j] in if v <> 255 then Printf.printf "%3d" v; done; print_string "]"; done; print_newline(); ) with Exit -> if elt <> "" then (failwith "print_elt");; type k_search = Line | Diag1 | Diag2;; let k_search_to_string = function Line -> "line" | Diag1 -> "diag1" | Diag2 -> "diag2";; let convert_coord kind x y = match kind with Diag1 -> let (i,j,k,l)=cdiag1.(x).(y) in (k,l) | Diag2 -> let (i,j,k,l)=cdiag2.(x).(y) in (k,l) | Line -> (x,y);; let print_move (i,j) (k,l) = Printf.printf "(%d,%d)->(%d,%d)" i j k l;; let rec gen_move3 kind color x i1 mlist orig = if !debug then Printf.printf "g3 : %s %d %d\n" (k_search_to_string kind) x i1; let (elto,elt1,ielt) = match (kind,color) with (Diag1,1) -> (diago,diag1,idiags) | (Diag2,1) -> (diago,diag2,idiags) | (Line,1) -> (lineso,lines,ilines) | (Diag1,2) -> (diagx,diag1,idiags) | (Diag2,2) -> (diagx,diag2,idiags) | (Line,2) -> (linesx,lines,ilines) | _ -> failwith "gen_move3" in let elt = elto.(elt1.(x)) and (a1,a2,a3,a4) = ielt.(x) in try for j = 0 to 6 do let i2 = Char.code elt.[i1*7+j] in if i2 = 255 then raise Exit; if (i2>=a1) & (i2<=a2) then begin if (i2>=a3) & (i2<=a4) then begin let dest = convert_coord kind x i2 in mlist := (orig,dest)::(!mlist); if !debug then (print_move orig dest;Printf.printf " jouable\n") end else begin if !debug then ( let dest = convert_coord kind x i2 in print_move orig dest; Printf.printf " autorise\n") end; gen_move2 kind color x i2 mlist orig; end done; with Exit -> () and gen_move2 kind color x y mlist orig = match kind with Diag1 -> let (i,j,k,l)=cdiag1.(x).(y) in gen_move3 Diag2 color i j mlist orig; gen_move3 Line color k l mlist orig; | Diag2 -> let (i,j,k,l)=cdiag2.(x).(y) in gen_move3 Diag1 color i j mlist orig; gen_move3 Line color k l mlist orig; | Line -> let (i,j,k,l)=clines.(x).(y) in gen_move3 Diag1 color i j mlist orig; gen_move3 Diag2 color k l mlist orig;; let gen_move kind color mlist = let (elto,elt1,ielt) = match (kind,color) with (Diag1,1) -> (diago,diag1,idiags) | (Diag2,1) -> (diago,diag2,idiags) | (Line,1) -> (lineso,lines,ilines) | (Diag1,2) -> (diagx,diag1,idiags) | (Diag2,2) -> (diagx,diag2,idiags) | (Line,2) -> (linesx,lines,ilines) | _ -> failwith "gen_move" in for i = 0 to 16 do let elt = elto.(elt1.(i)) and (a1,a2,a3,a4) = ielt.(i) in for j = 0 to (String.length elt -dec)/2-1 do let i1 = Char.code elt.[dec+2*j] and i2 = Char.code elt.[dec+2*j+1] in if (i2>=a1) & (i2<=a2) then begin let orig = convert_coord kind i i1 in if (i2>=a3) & (i2<=a4) then begin let dest = convert_coord kind i i2 in mlist := (orig,dest)::(!mlist); if !debug then (print_move orig dest;Printf.printf " jouable\n") end else begin if !debug then ( let dest = convert_coord kind i i2 in print_move orig dest; Printf.printf " autorise\n") end; if abs (i2-i1)<> 1 then gen_move2 kind color i i2 mlist orig end done done;; let joue color ((x,y),(z,t)) = let i = x and j = y in lines.(i)<- lines.(i) lxor (color lsl (2*(j-4))); let (d1i,d1j,d2i,d2j) = clines.(i).(j) in diag1.(d1i)<-diag1.(d1i) lxor (color lsl (2*(d1j-4))); diag2.(d2i)<-diag2.(d2i) lxor (color lsl (2*(d2j-4))); let i = z and j = t in lines.(i)<- lines.(i) lxor (color lsl (2*(j-4))); let (d1i,d1j,d2i,d2j) = clines.(i).(j) in diag1.(d1i)<-diag1.(d1i) lxor (color lsl (2*(d1j-4))); diag2.(d2i)<-diag2.(d2i) lxor (color lsl (2*(d2j-4))); compute_hash (x,y) color; compute_hash (z,t) color;; exception Coucou;; exception Sortie of int;; let titi x = Printf.printf "Leaving...\n"; raise Coucou;; let _ = Sys.signal Sys.sigvtalrm (Sys.Signal_handle titi);; let bmove = ref None and lastbests = ref [];; let rec negamax col color prof maxprof alpha beta v1 v2 = if prof = maxprof then if prof mod 2 =0 then (if col = 1 then -v1+v2 else v1-v2) else (if col = 1 then v1-v2 else -v1+v2) else begin try let vhash = find_hash prof maxprof in let (pmin,pmax)= match vhash with None -> (-32768,32768) | Some c -> if c.low <= beta & c.low <> -32768 then raise (Sortie c.low); if c.high >= alpha & c.high <> 32768 then raise (Sortie c.high); if c.low=c.high then raise (Sortie c.low); (c.low,c.high) in let mlist = ref [] in gen_move Diag1 color mlist;gen_move Diag2 color mlist; gen_move Line color mlist; mlist := Sort.list (fun ((x,y),(z,t)) ((x1,y1),(z1,t1))-> if color = 1 then (z1-x1)<(z-x) else (z1-x1)>(z-x)) !mlist; if prof = 0 then begin mlist := !lastbests@(List.filter (fun x -> not (List.mem x !lastbests)) !mlist); match !mlist with (orig,dest)::_ -> print_string "hd : ";print_move orig dest;print_string ":\n"; | [] -> () end; let a = ref alpha and bestv = ref (-32768) in (try List.iter (fun coup -> let ((x,y),(z,t)) = coup in joue color coup; let (ev1, ev2) = if color = 1 then (z-x,0) else (0, z-x) in let res = -negamax col (oppcol color) (prof+1) maxprof (-beta) (- !a) (v1-ev1) (v2+ev2) in joue color coup; if res > !bestv then begin bestv := res; if prof=0 then begin bmove := Some coup; Printf.printf "val=%d best:" res; print_move (x,y) (z,t); print_newline() end; if res > !a then a := res; if res>= beta then begin modify_hash vhash res pmax prof maxprof; raise (Sortie res); end; end; ) !mlist; modify_hash vhash pmin !bestv prof maxprof; with Exit -> ()); if !mlist = [] then begin assert (if color = 1 then v1 = 0 else v2 = 0); 32700 + if color=1 then v2 else v1 end else !a with Sortie res -> res end;; let rec alpha_beta col color prof maxprof alpha beta v1 v2 = if prof = maxprof then (if col = 1 then -v1+v2 else v1-v2) else begin let mlist = ref [] in gen_move Diag1 color mlist; gen_move Diag2 color mlist; gen_move Line color mlist; mlist := Sort.list (fun ((x,y),(z,t)) ((x1,y1),(z1,t1))-> if color = 1 then (z1-x1)<(z-x) else (z1-x1)>(z-x)) !mlist; if prof = 0 then ( mlist := !lastbests @ (List.filter (fun x -> not (List.mem x !lastbests)) !mlist); match !mlist with (orig,dest)::_ -> print_string "hd : "; print_move orig dest; print_string ":\n"; | [] -> () ); if col=color then begin let a = ref alpha in (try List.iter (fun coup -> let ((x,y),(z,t)) = coup in joue color coup; let (ev1, ev2) = if color = 1 then (z-x,0) else (0, z-x) in let res = alpha_beta col (oppcol color) (prof+1) maxprof !a beta (v1-ev1) (v2+ev2) in if res > !a then begin a := res; if prof=0 then begin bmove := Some coup; Printf.printf "val=%d best:" res; print_move (x,y) (z,t); print_newline() end; end; joue color coup; if !a >= beta then raise Exit) !mlist; with Exit -> ()); if !mlist = [] then begin assert (if color = 1 then v1 = 0 else v2 = 0); 32700 + if color=1 then v2 else v1 end else !a end else begin let b = ref beta in (try List.iter (fun coup -> let ((x,y),(z,t)) = coup in joue color coup; let (ev1, ev2) = if color = 1 then (z-x,0) else (0, z-x) in b := min !b (alpha_beta col (oppcol color) (prof+1) maxprof alpha !b (v1-ev1) (v2+ev2)); joue color coup; if !b <= alpha then raise Exit) !mlist; with Exit -> ()); if !mlist = [] then begin assert (if color = 1 then v1 = 0 else v2 = 0); - (32700 + if color = 1 then v2 else v1) end else !b end end;; type algo_type = WinAlpha | Alpha | NegaMax;; let algo_type = NegaMax;; let algo col = let s_pos = save_pos () and low = ref (-32768) and high = ref 32768 and iv1 = ref (-20) and iv2 =ref (-20) and p = ref 2 in lastbests := []; bmove := None; hashval.v0 <-whose_turn.(col-1).(0); hashval.v1<-whose_turn.(col-1).(1); iter_lignes (fun i j v -> if v<>0 then compute_hash (i,j) v; match v with 0 -> () | 1 -> iv1 := !iv1 + (16-i) | 2 -> iv2 := !iv2 + i | _ -> failwith "algo"); (* let _ = Unix.setitimer Unix.ITIMER_VIRTUAL {Unix.it_interval=0.;Unix.it_value=2.} in *) try while true do Printf.printf "prof=%d\n" !p;flush stdout; let v = match algo_type with WinAlpha -> (try while true do let res = alpha_beta col col 0 !p !low !high !iv1 !iv2 in Printf.printf "%d %d %d\n" res !low !high; flush stdout; if res > !low & res< !high then begin if !p mod 2 = 0 then (low := res+3; high := res+9) else (low := res-11; high :=res-2); raise (Sortie res) end; if res <= !low then (low := -32768; high := res+1); if res >= !high then (low := res-1; high := 32768); done; failwith "Never!!!"; with Sortie res -> res) | Alpha -> alpha_beta col col 0 !p (-32768) 32768 !iv1 !iv2 | NegaMax -> negamax col col 0 !p (-32768) 32768 !iv1 !iv2 in (match !bmove with None -> Printf.printf "Passe: "; | Some (orig,dest) -> print_move orig dest; lastbests := (orig,dest):: !lastbests); print_newline (); flush stdout; if (abs v) > 32000 then ( let _ = Unix.setitimer Unix.ITIMER_VIRTUAL {Unix.it_interval=0.;Unix.it_value=0.} in raise Coucou); incr p; if !p=6 then raise Coucou; done; failwith "Never!!!"; with Coucou -> restore_pos s_pos; match !bmove with Some (orig,dest) -> Some (orig,dest) | None -> match !lastbests with [] -> None | h :: _ -> Some h;; let opponent_move color = let mlist = ref [] in gen_move Diag1 color mlist; gen_move Diag2 color mlist; gen_move Line color mlist; if !mlist = [] then raise Exit; try while true do let ev = Graphics.wait_next_event [Graphics.Button_up] in let (i,j) = inv_conv ev.Graphics.mouse_x ev.Graphics.mouse_y in Printf.printf "%d %d\n" i j; flush stdout; let ev = Graphics.wait_next_event [Graphics.Button_up] in let (k,l) = inv_conv ev.Graphics.mouse_x ev.Graphics.mouse_y in Printf.printf "%d %d\n" k l; flush stdout; if List.mem ((i,j),(k,l)) !mlist then begin joue color ((i,j),(k,l)); affiche_tout (); incr movenum; raise Exit; end; Printf.printf "Invalid move\n"; flush stdout done; with Exit -> ();; let _ = init_tables (); init_pos (); Graphics.open_graph "unix:0 520x520"; affiche_tout (); movenum := 0; let color = ref 1 in (try while true do Printf.printf "color=%d\n" !color; flush stdout; let bmove = algo !color in incr movenum; (match bmove with None -> Printf.printf "coup : Passe\n"; raise Exit | Some (orig,dest) -> Printf.printf "coup : "; print_move orig dest; print_newline(); joue !color (orig,dest)); flush stdout; affiche_tout (); if not autoplay then opponent_move (oppcol !color) else color := oppcol !color; done; with Exit -> ()); let _ = Graphics.read_key () in exit 0;;