# Conway's Game of Life in F#

Since I'm learning F# along with functional programming, I managed to implement the rules for Conway's Game of Life. I'm not sure if I can improve some of its parts, though. For example, the neighbours function does an ugly range testing, but I can't think of anything simpler.

module Game

open System

type Cell =
| Alive

let amount_neighbours (board: Cell[,]) (pos: int * int) =
let range (n: int) (limit: int) =
let min = if n < 1 then 0 else n - 1
let max = if n > (limit - 2) then (limit - 1) else n + 1
[min .. max]

let x_range = range (fst pos) (Array2D.length1 board)
let y_range = range (snd pos) (Array2D.length2 board)

List.sum [for x in x_range ->
List.sum [for y in y_range -> if board.[x, y] = Alive && (x, y) <> pos then 1 else 0]]

let lifecycle (board: Cell[,]) =
Array2D.init (Array2D.length1 board) (Array2D.length2 board) (fun i j ->
let neighbours = amount_neighbours board (i, j)
match neighbours with
| 2 -> board.[i, j]
| 3 -> Alive
| _ -> Dead)

let rec process_game (board: Cell[,]) (n: int) =
match n with
| x when x > 0 ->
printfn "Iteration"
printfn "%A" board
process_game (lifecycle board) (n - 1)
| _ -> 0

[<EntryPoint>]
let main args =
let board = Array2D.init 5 5 (fun i j -> if i = 2 && j > 0 && j < 4 then Alive else Dead)
ignore (process_game board 4)
0


I thought it would make sense if you created a function alive, which would take care of bounds checking for you. And also simplify the the final expression by using a single sequence expression instead of two like you do.

But I'm not sure it's actually much better than your version:

let amount_neighbours (board: Cell[,]) (pos: int * int) =
let alive board pos =
let (x, y) = pos
if x < 0 || x >= Array2D.length1 board ||
y < 0 || y >= Array2D.length2 board then
false
else
board.[x, y] = Alive

let vicinity x = seq { x - 1 .. x + 1 }

seq {
for x in vicinity (fst pos) do
for y in vicinity (snd pos) do
if (x, y) <> pos && alive board (x, y) then
yield true
} |> Seq.length

• Well, this is a good improvement IMO. I'll vote up as soon as I can! Thanks. Oct 20, 2012 at 19:00