-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Functional Refactor #3
base: master
Are you sure you want to change the base?
Changes from all commits
2f9e707
e6cdbb0
91a01e1
0e78400
ed48299
2d9004d
bec3dd7
6b6ddb0
bc1dc10
433ceac
5406389
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,6 @@ obj/ | |
/packages/ | ||
riderModule.iml | ||
/_ReSharper.Caches/ | ||
.idea | ||
.idea | ||
.ionide | ||
.fake |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
module GameOfLife.Program | ||
open System | ||
open System.Threading | ||
|
||
let rows = 15 | ||
let columns = 15 | ||
let timer = 500 | ||
|
||
type Status = ``💀`` = 0 | ``😁`` = 1 | ||
type RNG = Security.Cryptography.RandomNumberGenerator | ||
|
||
let private nextGeneration (grid: Status [,]) = | ||
grid | ||
|> Array2D.mapi (fun r c -> | ||
let aliveNeighbors = | ||
(seq { -1 .. 1 }, seq { -1 .. 1 }) | ||
||> Seq.allPairs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|> Seq.choose (function | (0, 0) -> None | x -> Some x) //skip center | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|> Seq.map (fun (x, y) -> x + r, y + c) | ||
|> Seq.filter (fun (x, y) -> x < rows && y < columns && x >= 0 && y >= 0) | ||
|> Seq.sumBy (fun (x, y) -> int grid.[x, y]) | ||
function | ||
// Cell is lonely and dies OR Cell dies due to over population | ||
| Status.``😁`` when aliveNeighbors < 2 || aliveNeighbors > 3 -> Status.``💀`` | ||
// A new cell is born | ||
| Status.``💀`` when aliveNeighbors = 3 -> Status.``😁`` | ||
// stays the same | ||
| unchanged -> unchanged) | ||
|
||
let private stringify (grid: Status [,]) = | ||
grid | ||
|> Array2D.mapi (fun _ y -> if y = columns - 1 then sprintf "%A\n" else string) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curried form functions means multiple arguments can be invoke like nested single argument functions and vice versa. Many might not be a fan of this, but I like, the if expression returns a choice of functions from inside a two argument function to make a three argument function! |
||
|> Seq.cast<string> | ||
|> String.concat String.Empty | ||
|
||
[<EntryPoint>] | ||
let main _ = | ||
let cts = new CancellationTokenSource() | ||
Console.CancelKeyPress.Add(fun _ -> cts.Cancel(); Console.WriteLine "\n👋 Ending simulation.") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. F# doesn't need semicolons, but you can swap with a new line for most things. |
||
//Define our async work - cold | ||
let work = async { | ||
// randomly initialize our grid | ||
let mutable grid = | ||
Array2D.init rows columns (fun _ _ -> RNG.GetInt32(0, 2) |> enum) | ||
while true do | ||
// Displaying the grid | ||
Console.SetCursorPosition(0, 0) | ||
grid |> stringify |> Console.Write | ||
grid <- nextGeneration grid | ||
do! Async.Sleep timer | ||
} | ||
Comment on lines
+41
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
// let's give our console | ||
// a good scrubbing | ||
Console.Clear() | ||
Console.BackgroundColor <- ConsoleColor.Black | ||
Console.CursorVisible <- false | ||
//Do The thing | ||
Async.RunSynchronously(work, cancellationToken = cts.Token) | ||
0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want a single type, but not bulky name? Use a type alias!