Last active
August 29, 2015 14:09
-
-
Save Porges/f13e902d8dd3d9b7756a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Life | |
open System | |
// A cell is either alive or dead | |
type Cell = Dead | Alive | |
// A board is an array of arrays of cells | |
type Board = Cell[][] | |
// Makes a square board of dead cells | |
let makeBoard n = Array.create n (Array.create n Dead) | |
// A point is x & y coordinates | |
type Point = | |
{ x : int; y : int } | |
// We can add points together: | |
static member (+) (p1, p2) = { x = p1.x + p2.x; y = p1.y + p2.y } | |
// Simple function to construct a point | |
let point x y = { x = x; y = y} | |
// We can access the point on a board: | |
let (@) b p = | |
if p.y >= Array.length b || p.y < 0 | |
then Dead | |
else | |
let row = b.[p.y] | |
if p.x >= Array.length row || p.x < 0 | |
then Dead | |
else row.[p.x] | |
// We can check if a particular cell is alive | |
let isAlive board point = board @ point = Alive | |
// Get all the neighbours for a particular point: | |
let neighbours p = seq { | |
for y in [-1..1] do | |
for x in [-1..1] do | |
if not (x = 0 && y = 0) | |
then yield p + point x y | |
} | |
// Count the number of neighbours that are alive for a point on a board: | |
let aliveNeighbours b = neighbours >> Seq.sumBy (isAlive b >> Convert.ToInt32) | |
// Calculate the new state for a particular point: | |
let newState b p = | |
if isAlive b p | |
then | |
match aliveNeighbours b p | |
with | |
| 2 | 3 -> Alive | |
| _ -> Dead | |
else | |
match aliveNeighbours b p | |
with | |
| 3 -> Alive | |
| _ -> Dead | |
// Generate a new board from an existing one: | |
let step (b : Board) : Board = Array.init b.Length (fun y -> Array.init b.Length (fun x -> newState b (point x y))) | |
// Here's an example board: | |
let board1 = Array.init 3 (fun _ -> [| Dead; Alive; Dead |]) | |
// How to print a board: | |
let printBoard (b : Board) = | |
for y in b do | |
for x in y do | |
printf "%s" (if x = Alive then "X" else " ") | |
printfn "" | |
printfn "---" | |
let rec run b : unit = | |
printBoard b | |
Console.ReadKey(true) |> ignore | |
run (step b) | |
let main = run board1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment