Created
June 1, 2022 16:48
-
-
Save eisterman/fa45ccb435962ff75453d390ccb9acaa to your computer and use it in GitHub Desktop.
Console Game of Life
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
// See https://aka.ms/new-console-template for more information | |
namespace ConsoleAppGameOfLife { | |
public class GoLRule { | |
public GoLRule() { | |
Birth = new[] { 3 }; | |
Stay = new[] { 2, 3 }; | |
} | |
public GoLRule(int[] birth, int[] stay) { | |
Birth = birth; | |
Stay = stay; | |
} | |
private int[] Birth { get;} | |
private int[] Stay { get; } | |
public int ApplyRule(int cellstatus, IEnumerable<int> neighbors) { | |
var enumerable = neighbors as int[] ?? neighbors.ToArray(); | |
if (enumerable.Length != 8) throw new ArgumentException("neighbors need to be 8"); | |
return (cellstatus == 0 ? Birth : Stay).Contains(enumerable.Count(x => x > 0)) ? 1 : 0; | |
} | |
public int ApplyRule(int cellstatus, int numberalive) { | |
return (cellstatus == 0 ? Birth : Stay).Contains(numberalive) ? 1 : 0; | |
} | |
} | |
public class GameOfLife { | |
public GameOfLife(int width, int height) : this(width, height, new GoLRule()) { } | |
public GameOfLife(int width, int height, GoLRule rule) { | |
Width = width; | |
Height = height; | |
_table = new int[width, height]; | |
Rule = rule; | |
} | |
public int Width { get; } | |
public int Height { get; } | |
public int this[int x, int y] { | |
get => _table[Math.Abs(x % Width), Math.Abs(y % Height)]; | |
set => _table[Math.Abs(x % Width), Math.Abs(y % Height)] = value; | |
} | |
private int[,] _table; | |
public GoLRule Rule { get; } | |
public int Generation { get; private set; } | |
private int GetNeighbors (int x, int y) { | |
var neigh = 0; | |
for (var i = -1; i <= 1; i++) { | |
for (var j = -1; j <= 1; j++) { | |
if (i == 0 && j == 0) continue; | |
if (this[x + i, y + j] > 0) neigh++; | |
} | |
} | |
return neigh; | |
} | |
public void RunOnce() { | |
var ntable = new int[Width, Height]; | |
for (var i = 0; i < Width; i++) { | |
for (var j = 0; j < Height; j++) { | |
ntable[i, j] = Rule.ApplyRule(_table[i, j], GetNeighbors(i, j)); | |
} | |
} | |
_table = ntable; | |
Generation++; | |
} | |
public string Format() { | |
var output = $"Generation:\t{Generation}\n"; | |
for (var j = 0; j < Height; j++) { | |
var line = ""; | |
for (var i = 0; i < Width; i++) { | |
line += _table[i, j] > 0 ? "#" : "."; | |
} | |
output += line + "\n"; | |
} | |
return output; | |
} | |
public void Randomize(int seed) { | |
var random = new Random(seed); | |
for (var i = 0; i < Width; i++) | |
for (var j = 0; j < Height; j++) { | |
_table[i, j] = random.Next(0, 2); | |
} | |
} | |
} | |
internal static class Program { | |
private static int AskNumber(string numberName) { | |
Console.Write($"Insert {numberName}: "); | |
int number; | |
while (!int.TryParse(Console.ReadLine(), out number)) { | |
Console.WriteLine("Error during integer parsing"); | |
Console.Write($"Insert {numberName}: "); | |
} | |
return number; | |
} | |
private static void Main() { | |
var width = AskNumber("Width"); | |
var height = AskNumber("Height"); | |
var seed = AskNumber("Seed"); | |
var gol = new GameOfLife(width, height); | |
gol.Randomize(seed); | |
while (true) { | |
Console.Clear(); | |
Console.WriteLine(gol.Format()); | |
gol.RunOnce(); | |
//Console.WriteLine("Press a key to continue..."); | |
//Console.ReadKey(); | |
Thread.Sleep(100); | |
} | |
// ReSharper disable once FunctionNeverReturns | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment