open Graphics let col = 20 let lig = 10 let pas = 30 let () = open_graph (Printf.sprintf " %dx%d" (pas * col) (pas * lig)); set_color black; for i = 0 to col - 1 do let x = i * pas in moveto x 0; lineto x (pas * lig); done; for j = 0 to lig - 1 do let y = j * pas in moveto 0 y; lineto (pas * col) y done let () = at_exit close_graph type cell = | Cache of bool * bool (* bombe / drapeau *) | Decouvert let cells = Array.create_matrix col lig (Cache (false,false)) let cell i j = cells.(i).(j) let nbb = 20 let bombe i j = match cell i j with | Cache (b,_) -> b | Decouvert -> false let () = Random.self_init (); let k = ref 0 in while !k < nbb do let i = Random.int col in let j = Random.int lig in if not (bombe i j) then begin cells.(i).(j) <- Cache (true, false); incr k end done let colorie c i j = set_color c; let x = i * pas + 2 in let y = j * pas + 2 in fill_rect x y (pas - 4) (pas - 4) let gris = rgb 200 200 200 let () = for i = 0 to col - 1 do for j = 0 to lig - 1 do colorie gris i j done done let nb_drapeaux = ref 0 let nb_decouvert = ref 0 exception Perdu exception Gagne let autour i j f = let f i' j' = if i' >= 0 && i' < col && j' >= 0 && j' < lig then f i' j' in f (i-1) j; f (i-1) (j+1); f i (j+1); f (i+1) (j+1); f (i+1) j; f (i+1) (j-1); f i (j-1); f (i-1) (j-1) let rec decouvre i j = incr nb_decouvert; colorie white i j; let n = ref 0 in autour i j (fun i' j' -> if bombe i' j' then incr n); cells.(i).(j) <- Decouvert; if !n > 0 then begin set_color black; moveto (i * pas + pas/3) (j * pas + pas/3); draw_char (Char.chr (Char.code '0' + !n)) end else autour i j decouvre_si_cache and decouvre_si_cache i j = match cell i j with | Cache _ -> decouvre i j | Decouvert -> () let click (x,y) = ignore (wait_next_event [Button_up]); let i = x / pas in let j = y / pas in match cell i j with | Cache (true, _) -> raise Perdu | Cache (false, _) -> decouvre i j | Decouvert -> () let dessine_drapeau i j = let x = i * pas in let y = j * pas in set_color red; fill_poly [| x+2, y+2; x+pas-4,y+pas/2; x+2,y+pas-4 |] let pose_drapeau (x,y) = let i = x / pas in let j = y / pas in match cell i j with | Cache (b, false) -> dessine_drapeau i j; incr nb_drapeaux; cells.(i).(j) <- Cache (b, true) | Cache (b, true) -> colorie gris i j; decr nb_drapeaux; cells.(i).(j) <- Cache (b, false) | Decouvert -> () let dessine_bombe i j = let x = i * pas in let y = j * pas in set_color blue; fill_circle (x+pas/2) (y+pas/2) (pas/2-5) let revele () = for i = 0 to col - 1 do for j = 0 to lig - 1 do if bombe i j then dessine_bombe i j done done; ignore (wait_next_event [Key_pressed]) let () = try while true do let st = wait_next_event [Button_down; Key_pressed] in if st.button then click (mouse_pos ()); if st.keypressed then begin let c = st.key in if c = 'q' then raise Exit else pose_drapeau (mouse_pos ()) end; if !nb_drapeaux = nbb && !nb_drapeaux + !nb_decouvert = col * lig then raise Gagne done with | Perdu -> revele (); print_endline "perdu"; exit 0 | Gagne -> revele (); print_endline "gagné"; exit 0 | Exit -> exit 0