# Learning F#: The Game of Life (Vol. 5)

# Intro

I have been plugging away at the Game of Life implementation and have been spinning my wheels on mapping.

## Maps

There’s two types of maps that I’m aware of in F#.

There’s “Map” the type and there’s “map” the function.

## “Map” the type

Map the type is essentially a dictionary. It’s an immutable structure of keys and values.

I have only learned to construct a map from a sequence of tuples:

let myMap = [ (0,0); (1,1); (2,2); (3,3) ] |> Map.ofSeq

If one wanted to retrieve values from a map (aka: f# dictionary) then I think one could do something like this:

let values = [ (0,0); (1,1); (2,2); (3,3) ] |> Map.ofSeq |> Map.toSeq |> Seq.map snd

The above code should have captured all the value elements within the dictionary.

## “Map” the function

Map also is the name of a function that does a transform from one structure to another structure based on source data.

Remember this:

let values = [ (0,0); (1,1); (2,2); (3,3) ] |> Map.ofSeq |> Map.toSeq |> Seq.map snd

Well we used map the function here:

... |> Seq.map snd

In the above case we took a list of tuples and took the second element from the tuple.

## The Game of Life

In the Game of Life, I added some new tests:

[<Test>] let ``set cell to alive``() = // Setup let rowCount = 3 let target = { X=2; Y=2; State=Alive } let grid = rowCount |> createGrid |> setCell target // Test let result = grid |> getStatus (2,2) // Verify result |> should equal Alive [<Test>] let ``get neighbors``() = // Setup let rowCount = 3 let grid = rowCount |> createGrid let center = 2,2 let count = center |> getNeighbors |> List.length // Verify count |> should equal 8 [<Test>] let ``center cell is the first to live``() = // Setup let rowCount = 3 let result = rowCount |> createGrid |> cycle |> getStatus (2,2) // Verify result |> should equal Alive [<Test>] let ``Any live cell with fewer than two live neighbors dies, as if caused by under-population``() = // Setup let rowCount = 3 let result = rowCount |> createGrid |> cycle |> cycle |> getStatus (2,2) // Verify result |> should equal Dead

Thus, the updated business logic is the following:

type State = Alive | Dead type Cell = { X:int; Y:int; State:State } type Response = | Die | Survive | Resurect let isNeighbor cell1 cell2 = let isAbsNeighbor v1 v2 = match abs (v1 - v2) with | 0 | 1 -> true | _ -> false let isValueNeighbor v1 v2 = match v1 >= 0 && v2 >= 0 with | true -> isAbsNeighbor v1 v2 | _ -> isAbsNeighbor v2 v1 match cell1.X <> cell2.X || cell1.Y <> cell2.Y with | true -> isValueNeighbor cell1.X cell2.X && isValueNeighbor cell1.Y cell2.Y | _ -> false let createGrid rowCount = [for x in 1..rowCount do for y in 1..rowCount do yield { X=x; Y=y; State=Dead } ]|> List.map (fun c -> (c.X, c.Y), { X=c.X; Y=c.Y; State=Dead }) |> Map.ofList let setCell cell (grid:Map<(int * int), Cell>) = grid |> Map.map (fun k v -> match k with | c when c = (cell.X, cell.Y) -> { v with State=cell.State } | _ -> v) let getStatus coordinate (grid:Map<(int * int), Cell>) = match grid.TryFind coordinate with | Some cell -> cell.State | None -> Dead let getNeighbors (coordinate:int*int) = let x,y = coordinate let west = x-1, y let northWest = x-1, y+1 let north = x, y+1 let northEast = x+1, y+1 let east = x+1, y let southEast = x+1, y-1 let south = x, y-1 let southWest = x-1, y-1 [west; northWest; north; northEast; east; southEast; south; southWest] let values = [ (0,0); (1,1); (2,2); (3,3) ] |> Map.ofSeq |> Map.toSeq |> Seq.map snd let cycle (grid:Map<(int * int), Cell>) = let isBeginnng = grid |> Map.forall (fun _ cell -> cell.State = Dead) match isBeginnng with | true -> grid |> setCell { X=2; Y=2; State=Alive } | false -> ??? idk

## Impediment

I’m stuck on updating the grid per time interval.

Here’s the function that I attempt to update the cells for within the grid:

let cycle (grid:Map<(int * int), Cell>) = let isBeginnng = grid |> Map.forall (fun _ cell -> cell.State = Dead) match isBeginnng with | true -> grid |> setCell { X=2; Y=2; State=Alive } | false -> ??? idk

In the above code, I’m struggling with transforming the state of specific elements within a collection that’s always changing? Specifically, I do not know of an appropriate approach for transforming a grid each time the state of one of the cells within the grid changes.

# Conclusion

In conclusion, I have been plugging away at the Game of Life implementation and have been spinning my wheels on mapping. Thus I discussed the two types of mapping.