# Intro

I posted my thoughts several articles ago regarding my journey of learning F# via the implementation of The Game of Life. I had initially attempted (through my ignorance) Domain-Driven Design and quickly ran into some design issues. I received some feedback regarding my initial design on StackOverflow and decided to try an alternative design. Thus, I decided to use TDD.

One of the feedback items that I received was to consider using a grid instead of an array. But what really is a grid? As of right now, I would define a grid as a container of X,Y coordinates. Then I was confronted with the question, “how do I represent an x,y coordinate?”.

## Representing an X,Y Coordinate

At first, I considered using a tuple:

```let cell = 0,0
let x,y = cell
```

However, in this domain a grid has cells which is really an identified part of the system. As a result, I decided that it would probably be best to define a cell instead.

Thus, I defined a cell as the following:

```type Cell = { X:int; Y:int }
```

## What to do with a Cell?

Having a cell is great. However, a cell by itself is rendered useless. Hence, The Game of Life requires cells to live, die, and be resurrected from the dead based on the status of their neighbors.

## Defining a Cell’s Neighbor

Using a grid I can visually identify a cell’s neighbor. However, to do this programmatically, I relied on TDD.

The following logic was generated via TDD:

```let isXNeighbor cell1 cell2 =

if cell1.X >= 0  && cell2.X >= 0 then
abs (cell1.X - cell2.X) = abs 1 ||
abs (cell1.X - cell2.X) = abs 0
else
abs (cell2.X - cell1.X) = abs 1 ||
abs (cell2.X - cell1.X) = abs 0

let isYNeighbor cell1 cell2 =

if cell1.Y >= 0  && cell2.Y >= 0 then
abs (cell1.Y - cell2.Y) = abs 1 ||
abs (cell1.Y - cell2.Y) = abs 0
else
abs (cell2.Y - cell1.Y) = abs 1 ||
abs (cell2.Y - cell1.Y) = abs 0

let isNeighbor cell1 cell2 =

if cell1.X <> cell2.X && cell1.Y <> cell2.Y then
let xAligned = isXNeighbor cell1 cell2
let yAligned = isYNeighbor cell1 cell2

xAligned && yAligned

else false
```

I then refactored that logic to the following:

```let isAbsNeighbor v1 v2 =
abs (v1 - v2) = abs 1 ||
abs (v1 - v2) = abs 0

let IsValueNeighbor v1 v2 =

if v1 >= 0  && v2 >= 0
then isAbsNeighbor v1 v2
else isAbsNeighbor v2 v1

let isNeighbor cell1 cell2 =

if cell1.X <> cell2.X || cell1.Y <> cell2.Y then
let xAligned = IsValueNeighbor cell1.X cell2.X
let yAligned = IsValueNeighbor cell1.Y cell2.Y

xAligned && yAligned

else false
```

The actual tests that flushed out the logic is the following:

```open FsUnit
open NUnit.Framework

[<Test>]
let ``cells sharing x-coordinate are neighbors``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=0; Y=1 }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cells sharing y-coordinate are neighbors``() =
// Setup
let cell1 = { X=0; Y=1 }
let cell2 = { X=1; Y=1 }

cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's right 1 and down 1 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=1; Y=(-1) }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's right 1 and down-0 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=1; Y=0 }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's right 1 and up 1 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=1; Y=1 }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's up 1 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=0; Y=1 }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's down 1 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=0; Y=(-1) }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's left 1 and up 1 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=(-1); Y=1 }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``cell that's left 1 and down 1 is neighbor``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=(-1); Y=(-1) }

// Verify
cell1 |> isNeighbor cell2
|> should equal true

[<Test>]
let ``far away x-coordinates are not neighbors``() =
// Setup
let cell1 = { X=(-1); Y=0 }
let cell2 = { X=(+1); Y=0 }

// Verify
cell1 |> isNeighbor cell2
|> should equal false

[<Test>]
let ``far away y-coordinates are not neighbors``() =
// Setup
let cell1 = { X=0; Y=(+1) }
let cell2 = { X=0; Y=(-1) }

// Verify
cell1 |> isNeighbor cell2
|> should equal false

[<Test>]
let ``far away x,y-coordinates are not neighbors``() =
// Setup
let cell1 = { X=(+1); Y=(+1) }
let cell2 = { X=(+1); Y=(-1) }

// Verify
cell1 |> isNeighbor cell2
|> should equal false

[<Test>]
let ``cells with same coordinates cannot be neighbors``() =
// Setup
let cell1 = { X=0; Y=0 }
let cell2 = { X=0; Y=0 }

// Verify
cell1 |> isNeighbor cell2
|> should equal false
```

# Conclusion

In conclusion, I posted my thoughts several articles ago regarding my journey of learning F# via the implementation of The Game of Life. I had initially attempted (through my ignorance) Domain-Driven Design and quickly ran into some design issues. I received some feedback regarding my initial design on StackOverflow and decided to try an alternative design. Thus, I decided to use TDD. I’m still a novice to F#. Hence, I know that my implementation can be further refined. However, I do believe that I no expert starts as an expert. Thus, wish me luck!