I have this record type.
type cell = { alive : bool ; column : int ; row : int }
;;
Now I create a grid of such cells.
#require "containers";;
let makegrid = CCList.init 2 ( fun i -> (CCList.init 2 (fun j -> { alive = true; column = j;row = i })) );;
I draw a square grid using lablgtk based on the number of cells in the grid.
let drawgrid area (backing:GDraw.pixmap ref) grid =
let rec loop1 limit m y =
match m with
| m when m < limit ->
(let rec loop x n =
match n with
| n when n < limit ->
let x = x + 20 in
let width, height = 20,20 in
displayrectangle area backing x y width height;
(*Printf.printf "%3d %3d\n" x y;*)
loop x (n + 1)
| n when n >= limit -> loop1 (List.length grid) (m + 1) (y + 20)
in loop 0 0)
(* when m >= limit *)
| m when m >= limit -> ()
in loop1 (List.length grid) 0 0
;;
So the final code is like this.
let makegameoflifegrid = CCList.init 7 ( fun i -> (CCList.init 7 (fun j -> { alive = false; column = j;row = i })) ) in
let drawing_area = GMisc.drawing_area ~width:200 ~height:200 ~packing:aspect_frame#add () in
drawing_area#event#connect#expose ~callback:(expose drawing_area backing);
drawing_area#event#connect#configure ~callback:(configure window backing);
drawing_area#event#add [`EXPOSURE];
window#show ();
drawgrid drawing_area backing makegameoflifegrid;
GMain.Main.main ()
;;
let _ = main ()
;;
I was wondering how to relate the cell type with its GUI representation which has x,y co-ordinates. This is basically a game of life and if I have to make a cell solid based on whether the cell is alive or not then I have to deal with two different represenations - alive attribute in the cell and x,y co-ordinates in the GUI.
Is there a functional solution for this ? The code actually works(except this problem) and has no inherent problem at this time and I know basic OCaml.
Update :
One could put the x and y co-ordinates in the record itself like this.
let drawgridrepresentation area (backing:GDraw.pixmap ref) grid =
let rec loop1 limit m y g1=
match m with
| m when m < limit ->
(let rec loop x n g=
match n with
| n when n < limit ->
let x = x + 20 in
let width, height = 20,20 in
displayrectangle area backing x y width height;
(*Printf.printf "%3d %3d\n" x y;*)
let gridmapi =
List.mapi (fun i el -> List.mapi ( fun i el1 ->
if (n = el1.column && m = el1.row)
then
({ el1 with row = x; column = y}
) else el1) el ) g in
loop x (n + 1) gridmapi
| n when n >= limit -> loop1 (List.length grid) (m + 1) (y + 20) g
in loop 0 0 g1)
(* when m >= limit *)
| m when m >= limit -> g1
in loop1 (List.length grid) 0 0 grid
;;
But I think I miss something.