diff --git a/.gitignore b/.gitignore
index 91953df..9b027c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,6 @@ obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
-.idea
\ No newline at end of file
+.idea
+.ionide
+.fake
\ No newline at end of file
diff --git a/GameOfLife.sln b/GameOfLife.sln
index fbb78e5..ce65135 100644
--- a/GameOfLife.sln
+++ b/GameOfLife.sln
@@ -1,6 +1,6 @@
ο»Ώ
Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameOfLife", "GameOfLife\GameOfLife.csproj", "{980E6F7A-195D-4F06-9398-B07DD274D20A}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameOfLife", "GameOfLife\GameOfLife.fsproj", "{980E6F7A-195D-4F06-9398-B07DD274D20A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/GameOfLife/GameOfLife.csproj b/GameOfLife/GameOfLife.fsproj
similarity index 71%
rename from GameOfLife/GameOfLife.csproj
rename to GameOfLife/GameOfLife.fsproj
index 2c0dacc..3922103 100644
--- a/GameOfLife/GameOfLife.csproj
+++ b/GameOfLife/GameOfLife.fsproj
@@ -4,5 +4,8 @@
Exe
netcoreapp3.1
+
+
+
diff --git a/GameOfLife/Program.cs b/GameOfLife/Program.cs
deleted file mode 100644
index 0564248..0000000
--- a/GameOfLife/Program.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-ο»Ώusing System;
-using System.Security.Cryptography;
-using System.Text;
-using System.Threading;
-
-namespace GameOfLife
-{
- static class Program
- {
- const int Rows = 15;
- const int Columns = 15;
-
- static bool runSimulation = true;
-
- public static void Main()
- {
- var grid = new Status[Rows, Columns];
-
- // randomly initialize our grid
- for (var row = 0; row < Rows; row++)
- {
- for (var column = 0; column < Columns; column++)
- {
- grid[row, column] = (Status) RandomNumberGenerator.GetInt32(0, 2);
- }
- }
-
- Console.CancelKeyPress += (sender, args) =>
- {
- runSimulation = false;
- Console.WriteLine("\nπ Ending simulation.");
- };
-
- // let's give our console
- // a good scrubbing
- Console.Clear();
-
- // Displaying the grid
- while (runSimulation)
- {
- Print(grid);
- grid = NextGeneration(grid);
- }
- }
-
- private static Status[,] NextGeneration(Status[,] currentGrid)
- {
- var nextGeneration = new Status[Rows, Columns];
-
- // Loop through every cell
- for (var row = 1; row < Rows - 1; row++)
- for (var column = 1; column < Columns - 1; column++)
- {
- // find your alive neighbors
- var aliveNeighbors = 0;
- for (var i = -1; i <= 1; i++)
- {
- for (var j = -1; j <= 1; j++)
- {
- aliveNeighbors += currentGrid[row + i, column + j] == Status.Alive ? 1 : 0;
- }
- }
-
- var currentCell = currentGrid[row, column];
-
- // The cell needs to be subtracted
- // from its neighbours as it was
- // counted before
- aliveNeighbors -= currentCell == Status.Alive ? 1 : 0;
-
- // Implementing the Rules of Life
-
- // Cell is lonely and dies
- if (currentCell.HasFlag(Status.Alive) && aliveNeighbors < 2)
- {
- nextGeneration[row,column] = Status.Dead;
- }
-
- // Cell dies due to over population
- else if (currentCell.HasFlag(Status.Alive) && aliveNeighbors > 3)
- {
- nextGeneration[row, column] = Status.Dead;
- }
-
- // A new cell is born
- else if (currentCell.HasFlag(Status.Dead) && aliveNeighbors == 3)
- {
- nextGeneration[row,column] = Status.Alive;
- }
- // stays the same
- else
- {
- nextGeneration[row, column] = currentCell;
- }
- }
- return nextGeneration;
- }
-
- private static void Print(Status[,] future, int timeout = 500)
- {
- var stringBuilder = new StringBuilder();
- for (var row = 0; row < Rows; row++)
- {
- for (var column = 0; column < Columns; column++)
- {
- var cell = future[row, column];
- stringBuilder.Append(cell == Status.Alive ? "π§βπ" : "π½");
- }
- stringBuilder.Append("\n");
- }
-
- Console.BackgroundColor = ConsoleColor.Black;
- Console.CursorVisible = false;
- Console.SetCursorPosition(0, 0);
- Console.Write(stringBuilder.ToString());
- Thread.Sleep(timeout);
- }
- }
-
- public enum Status
- {
- Dead,
- Alive,
- }
-}
\ No newline at end of file
diff --git a/GameOfLife/Program.fs b/GameOfLife/Program.fs
new file mode 100644
index 0000000..72ace83
--- /dev/null
+++ b/GameOfLife/Program.fs
@@ -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
+ |> Seq.choose (function | (0, 0) -> None | x -> Some x) //skip center
+ |> 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)
+ |> Seq.cast
+ |> String.concat String.Empty
+
+[]
+let main _ =
+ let cts = new CancellationTokenSource()
+ Console.CancelKeyPress.Add(fun _ -> cts.Cancel(); Console.WriteLine "\nπ Ending simulation.")
+ //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
+ }
+ // 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