val next : t -> t
val color : t -> char * char * char
+
+ val of_string : string -> t
+
+ val to_string : t -> string
end
module Coord = struct
CoordMap.empty ccoords
|> CoordMap.filter (fun _ -> Array.exists (Array.exists (fun c -> c <> d))) )
+let deserialise (type t) (m : (module Automaton with type t = t)) channel =
+ let module M = (val m) in
+ let d = Option.get (In_channel.input_line channel) |> M.of_string in
+ let board =
+ let rec aux board =
+ match In_channel.input_line channel with
+ | None -> board
+ | Some x ->
+ let x = int_of_string x
+ and y = In_channel.input_line channel |> Option.get |> int_of_string in
+ let chunk =
+ Array.init chunk_size (fun _ ->
+ Array.init chunk_size (fun _ ->
+ In_channel.input_line channel |> Option.get |> M.of_string))
+ in
+ aux (CoordMap.add (x, y) chunk board)
+ in
+ aux CoordMap.empty
+ in
+ (d, board)
+
+let serialise (type t) (m : (module Automaton with type t = t)) (d, board) channel =
+ let module M = (val m) in
+ Printf.fprintf channel "%s\n" (M.to_string d);
+ CoordMap.iter
+ (fun (x, y) chunk ->
+ Printf.fprintf channel "%d\n%d\n" x y;
+ Array.iter (Array.iter (fun c -> Printf.fprintf channel "%s\n" (M.to_string c))) chunk)
+ board
+
let automata =
[
(module Life : Automaton);
val next : t -> t
val color : t -> char * char * char
+
+ val of_string : string -> t
+
+ val to_string : t -> string
end
type 't board
val update : (module Automaton with type t = 't) -> 't board -> 't board
val automata : (module Automaton) list
+
+val deserialise : (module Automaton with type t = 't) -> in_channel -> 't board
+
+val serialise : (module Automaton with type t = 't) -> 't board -> out_channel -> unit
| Off -> ('\x00', '\x00', '\x1F')
| On -> ('\xFF', '\xFF', '\xFF')
| Dying -> ('\x00', '\x00', '\xFF')
+
+let of_string = function
+ | "D" -> Off
+ | "A" -> On
+ | "Y" -> Dying
+ | _ -> failwith "Unparseable"
+
+let to_string = function
+ | Off -> "D"
+ | On -> "A"
+ | Dying -> "Y"
|> char_of_int
in
if c > 0. then (v, '\x00', '\x00') else ('\x00', '\x00', v)
+
+let of_string = float_of_string
+
+let to_string = string_of_float
let color = function
| Dead -> ('\x00', '\x00', '\x1F')
| Alive -> ('\xFF', '\xFF', '\xFF')
+
+let of_string = function
+ | "D" -> Dead
+ | "A" -> Alive
+ | _ -> failwith "Unparseable"
+
+let to_string = function
+ | Dead -> "D"
+ | Alive -> "A"
let color = function
| Sol -> ('\x00', '\x00', '\x1F')
| Mur -> ('\xFF', '\xFF', '\xFF')
+
+let of_string = function
+ | "S" -> Sol
+ | "M" -> Mur
+ | _ -> failwith "Unparseable"
+
+let to_string = function
+ | Sol -> "S"
+ | Mur -> "M"
| Conductor -> ('\xBF', '\xBF', '\x00')
| Head -> ('\xBF', '\x00', '\x00')
| Tail -> ('\x00', '\x00', '\xBF')
+
+let of_string = function
+ | "0" -> Empty
+ | "C" -> Conductor
+ | "H" -> Head
+ | "T" -> Tail
+ | _ -> failwith "Unparseable"
+
+let to_string = function
+ | Empty -> "0"
+ | Conductor -> "C"
+ | Head -> "H"
+ | Tail -> "T"
| 'l' -> Either.left (ntimes (chpos 1 0) st)
| 'i' -> Either.left (ntimes (chsize 1) st)
| 'o' -> Either.left (ntimes (chsize (-1)) st)
+ | 'w' ->
+ Out_channel.with_open_text "test.auto" (Automata.serialise (module M) st.board);
+ Either.left st
+ | 'r' ->
+ Either.left
+ { st with board = In_channel.with_open_text "test.auto" (Automata.deserialise (module M)) }
| _ -> Either.left st
end