(* #load "graphics.cma";; *) (* #use "o_img.ml";; *) (* #use "o_sudoku2.ml";; *) open Array;; open Graphics;; (* *) open O_sudoku;; (* *) (* Interface graphique part. 1 *) let gris = rgb 224 224 224 and bleuvert = rgb 0 160 160 and orange = rgb 252 192 0 and darkgrey = rgb 128 128 128 ;; let current_color () = let color = point_color 0 0 in plot 0 0; let current_color = point_color 0 0 in set_color color; plot 0 0; set_color current_color; current_color; ;; (* x,y est la coordonnée du centre de la case 1,1 ; e est l'espace entre les cases *) let init_graph () = open_graph " 1024x768"; let m = 100 and sx = size_x() and sy = size_y() in let e = ((min sx sy)-2*m)/9 in let x = (sx/2)-4*e and y = (sy/2)+4*e in x,y,e; ;; let x,y,e = init_graph() ;; let draw_line x1 y1 x2 y2 = let x,y = current_point() in moveto x1 y1; lineto x2 y2; moveto x y; ;; let draw_rect x y w h = moveto x y; lineto (x+w) y; lineto (x+w) (y+h); lineto x (y+h); lineto x y; ;; let draw_grille fore back = let x0 = x-e/2 and y0 = y+e/2 in if not (back = transp) then ( set_color back; for i = 0 to 2 do for j = 0 to 2 do if (i mod 2) = (j mod 2) then fill_rect (x0+3*i*e) (y0-3*j*e) (3*e) (-3*e); done; done; ); set_color fore; for ij = 0 to 9 do let xi = x0+ij*e and yi = y0-ij*e in draw_line (x0-1) yi (x0+9*e+2) yi; draw_line xi y0 xi (y0-9*e-1); if ij mod 3 = 0 then ( draw_line (x0-1) (yi-1) (x0+9*e+2) (yi-1); draw_line (x0-1) (yi+1) (x0+9*e+2) (yi+1); draw_line (xi-1) y0 (xi-1) (y0-9*e-1); draw_line (xi+1) y0 (xi+1) (y0-9*e-1); ); done; ;; let chiffres h = let dilate_im i h = let m = dump_image i in let n = length m and l = length m.(0) in let d = make_matrix (n*h) (l*h) 0 in for i = 0 to n*h -1 do for j = 0 to l*h -1 do let c = m.(i/h).(j/h) in d.(i).(j) <- (if c = black then black else transp) done; done; make_image d; in set_color black; let ch = make 10 (dilate_im (get_image x y 8 18) h) in for z = 1 to 9 do clear_graph(); moveto x y; draw_string (string_of_int z); ch.(z) <- dilate_im (get_image x y 8 18) h; done; clear_graph(); ch; ;; let h = e/18 ;; let chiffres_png () = (* *) let m = O_img.load1_cv "o_chiffres.png" in (* *) (* let m = load1_cv "o_chiffres.png" in *) let n = length m and l = length m.(0) in if n > e || l/9 > e then failwith "chiffres trop gros"; let ch = make 10 (get_image 0 0 n (l/9)) in for z = 1 to 9 do let p = make_matrix n (l/9) transp in for i = 0 to n - 1 do for j = 0 to l /9 - 1 do let c = m.(i).((z-1)*l/9+j) in p.(i).(j) <- (if c = white then transp else black); done; done; ch.(z) <- make_image p; done; ch; ;; let ch, png = try chiffres_png(), true with _ -> chiffres h, false ;; let draw_image im i j = if current_color() = black then draw_image im i j else ( let m = dump_image im in let n = length m and p = length m.(0) in for y = 0 to n - 1 do for x = 0 to p - 1 do if m.(n-1-y).(x) = black then plot (i+x) (j+y); done; done; ); ;; let draw_case i j z = let color = current_color() in set_color (if (i-1)/3 mod 2 = (j-1)/3 mod 2 then gris else white); fill_rect (x+(j-1)*e-e/2+2) (y-(i-1)*e-e/2+2) (e-4) (e-5); set_color color; if z <> 0 then ( if png then ( draw_image ch.(z) (x+(j-1)*e-5*h+1) (y-(i-1)*e-9*h-1); ) else ( draw_image ch.(z) (x+(j-1)*e-4*h-1) (y-(i-1)*e-8*h); ); ); ;; let rec draw_cases = function | [] -> () | ((i,j,z)::q) -> draw_case i j z ; draw_cases q ;; let draw_bouton y s = if s <> "" then ( let color = current_color() in set_color white; fill_rect (x+10*e+1) (y-10*h+1) 98 (10*h-2); set_color color; moveto (x+10*e+50-(fst (text_size s))/2) (y-8*h); draw_string s; if s <> "opt: " then draw_rect (x+10*e) (y-10*h) 100 (10*h) else ( draw_line (x+10*e+52) (y-9*h) (x+10*e+77) (y-9*h); for i = 0 to 5 do set_color black; draw_line (x+10*e+5*i+47) (y-9*h+5*i) (x+10*e+5*i+52) (y-9*h+5*i); draw_line (x+10*e+5*i+52) (y-9*h) (x+10*e+5*i+52) (y-9*h+5*i+5); if !opt > i then ( set_color (match i with | 0 -> blue | 1 -> green | 2 -> yellow | 3 -> orange | _ -> red); fill_rect (x+10*e+5*i+53) (y-9*h) 4 (5*i+4); ); done; moveto (x+10*e+88) (y-8*h); draw_string "+"; draw_rect (x+10*e+86) (y-8*h-1) 12 14; moveto (x+10*e+31) (y-8*h); draw_string "-"; draw_rect (x+10*e+29) (y-8*h-1) 12 14; ); ); ;; let draw_bouton y i = draw_bouton (y-17*h*i) ;; let rec draw_boutons start labels = for i = 0 to length labels - 1 do draw_bouton (y-17*h*start) i labels.(i) done; ;; let clear_boutons () = let color = current_color() in set_color white; fill_rect (x+9*e) (y-9*e) 200 (10*e); set_color color; ;; let draw_str i s = moveto (x+10*e+50-4*(String.length s)) (y-17*h*i+12); draw_string s; ;; let get_champ i = draw_rect (x+10*e) (y-17*h*i-10*h) 100 (10*h); let res = ref "" in try while true do let color = current_color() in set_color white; fill_rect (x+10*e+1) (y-17*h*i-10*h+1) 98 (10*h-2); set_color color; moveto (x+10*e+3) (y-17*h*i-8*h); draw_string (!res ^ "_"); let s = wait_next_event [Key_pressed] in match s.key with | '\013' -> failwith "return" | '\008' -> let n = String.length !res in if n > 0 then res:= String.sub !res 0 (n-1); | c when String.length !res < 11 -> res:= !res ^ (String.make 1 c); | _ -> () done; !res; with Failure "return" -> !res ;; let rec get_champ_int i = try int_of_string (get_champ i); with Failure "int_of_string" -> get_champ_int i ;; let ch_petit = chiffres 1 ;; let draw_poss i j z aff barre rond = if z = 0 then draw_case i j 0 else ( let xj = x+(j-1)*e+(((z-1) mod 3)-1)*e/4-4 and yi = y-(i-1)*e-((z-1)/3-1)*e/4-9 in if aff then ( draw_image ch_petit.(z) xj yi; ); if barre then ( draw_line xj yi (xj+8) (yi+16); draw_line xj (yi+16) (xj+8) yi; ); if rond then ( draw_circle (xj+4) (yi+7) 8; ); if not aff && not barre && not rond then ( let color = current_color() in set_color (if (i-1)/3 mod 2 = (j-1)/3 mod 2 then gris else white); fill_rect xj yi 8 16; set_color color; ); ); ;; let draw_coin i j n = set_color (match n mod 9 with | 0 -> red | 1 -> yellow | 2 -> cyan | 3 -> magenta | 4 -> bleuvert | 5 -> orange | 6 -> green | 7 -> blue | _ -> darkgrey); match n / 9 with | 0 -> let ii = if i mod 3 = 0 then 1 else 0 and jj = if j mod 3 = 0 then 1 else 0 in fill_arc (x-e/2+j*e-jj) (y+e/2-i*e+ii) 9 9 90 180 | 1 -> let ii = if i mod 3 = 1 then 3 else 2 and jj = if j mod 3 = 0 then 1 else 0 in fill_arc (x-e/2+j*e-jj) (y+e/2-(i-1)*e-ii) 9 9 180 270 | 2 -> let ii = if i mod 3 = 1 then 3 else 2 and jj = if j mod 3 = 1 then 3 else 2 in fill_arc (x-e/2+(j-1)*e+jj) (y+e/2-(i-1)*e-ii) 9 9 270 0 | 3 -> let ii = if i mod 3 = 0 then 1 else 0 and jj = if j mod 3 = 1 then 3 else 2 in fill_arc (x-e/2+(j-1)*e+jj) (y+e/2-i*e+ii) 9 9 0 90 | 4 -> let jj = if j mod 3 = 1 then 3 else 2 in fill_arc (x-e/2+(j-1)*e+jj) (y-(i-1)*e-2) 4 4 270 90 | 5 -> let jj = if j mod 3 = 1 then 3 else 2 in fill_arc (x-e/2+(j-1)*e+jj) (y-(i-1)*e+10) 4 4 270 90 | _ -> let jj = if j mod 3 = 1 then 3 else 2 in fill_arc (x-e/2+(j-1)*e+jj) (y-(i-1)*e-14) 4 4 270 90 ;; let rec draw_coins1 n = function | [] -> () | ((i,j,_)::q) -> draw_coin i j n ; draw_coins1 n q ;; let rec draw_coins2 n = function | [] -> () | (((i,j,_),l)::q) -> draw_coin i j (n+9) ; draw_coins1 n l ; draw_coins2 (n+1) q ;; let rec polygamie a = function | [] -> 0 | (b::q) -> (if List.mem a b then 1 else 0) + polygamie a q ;; let rec draw_coins3 n m w l = match w,l with | _, [] -> () | _, ([]::r) -> draw_coins3 n (m+1) true r | false, [(i,j,z)::q] -> draw_coin i j (9+n); draw_coins3 n m false [q]; | _, (((i,j,z)::q)::r) -> draw_coin i j (9+n); draw_coin i j ((polygamie (i,j,z) r)*9+18+m); draw_coins3 n m true (q::r); ;; let rec draw_coins4 n w l = match w,l with | _, [] -> n | false, [a,b,c] -> draw_coins3 n 0 false a ; n+1 | _, ((a,b,c)::q) -> draw_coins3 n 0 false a ; draw_coins1 n (b @ c) ; draw_coins4 (n+1) true q ;; let draw_coins5 a b w v n = match v,n with | true, n when 0 <= n && n < 9 -> draw_coins1 (n+9) a ; if w then draw_coins1 n b | true, n when 8 < n && n < 18 -> draw_coins1 (n+9) a ; if w then draw_coins1 (n+18) b | true, n when 17 < n && n < 27 -> draw_coins1 (n+27) a; if w then draw_coins1 (n+36) b | true, n -> draw_coins1 (n+9) a ; if w then draw_coins1 (n+9) b | false, n -> draw_coins1 n (a @ b) ;; let rec draw_coins6 v n w l = match w,l with | _, [] -> n | w, [a,b] -> draw_coins5 a b w v n ; n+1 | _, ((a,b)::q) -> draw_coins5 a b true v n ; draw_coins6 v (n+1) true q ;;