72 lines
1.8 KiB
OCaml
72 lines
1.8 KiB
OCaml
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 ())
|