RosettaCodeData/Task/Flipping-bits-game/OCaml/flipping-bits-game.ocaml
2023-07-01 13:44:08 -04:00

72 lines
1.8 KiB
Text

module FlipGame =
struct
type t = bool array array
let make side = Array.make_matrix side side false
let flipcol b n =
for i = 0 to (Array.length b - 1) do
b.(n).(i) <- not b.(n).(i)
done
let fliprow b n =
for i = 0 to (Array.length b - 1) do
b.(i).(n) <- not b.(i).(n)
done
let randflip b =
let n = Random.int (Array.length b - 1) in
match Random.bool () with
| true -> fliprow b n
| false -> flipcol b n
let rec game side steps =
let start, target = make side, make side in
for i = 1 to steps do
randflip start;
randflip target
done;
if start = target then game side steps (* try again *) else
(start, target)
let print b =
for i = 0 to Array.length b - 1 do
for j = 0 to Array.length b - 1 do
Printf.printf " %d " (if b.(j).(i) then 1 else 0)
done;
print_newline ()
done;
print_newline ()
let draw_game board target =
print_endline "TARGET"; print target;
print_endline "BOARD"; print board
end
let play () =
let module G = FlipGame in
let board, target = G.game 3 10 in
let steps = ref 0 in
while board <> target do
G.draw_game board target;
print_string "> ";
flush stdout;
incr steps;
match String.split_on_char ' ' (read_line ()) with
| ["row"; row] ->
(match int_of_string_opt row with
| Some n -> G.fliprow board n
| None -> print_endline "(nothing happens)")
| ["col"; col] ->
(match int_of_string_opt col with
| Some n -> G.flipcol board n
| None -> print_endline "(nothing happens)")
| _ -> ()
done;
G.draw_game board target;
Printf.printf "\n\nGame solved in %d steps\n" !steps
let () =
if not !Sys.interactive then
(Random.self_init ();
play ())