-
Notifications
You must be signed in to change notification settings - Fork 1
/
GameOfLife.cs
132 lines (111 loc) · 4.28 KB
/
GameOfLife.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) 2021 Claus Jørgensen
// Conway's Game of Life
// https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
public sealed class GameOfLife
{
private int[,] map;
public GameOfLife(int[,] seed)
{
map = seed;
}
public void Transition()
{
var d1 = map.GetLength(0);
var d2 = map.GetLength(1);
int[,] newMap = new int[d1, d2];
for (int x = 0; x < d1; x++)
{
for (int y = 0; y < d2; y++)
{
var neighbors = GetNeighbors(x, y);
var numAlive = neighbors.Aggregate(0, (a, c) => c == 1 ? a + 1 : a);
if (numAlive < 2)
newMap[x, y] = 0; // death by under population
else if (numAlive > 3)
newMap[x, y] = 0; // death by over population
else if (map[x, y] == 0 && numAlive == 3)
newMap[x, y] = 1; // alive by reproduction
else
newMap[x, y] = map[x, y]; // continue unchanged
}
}
map = newMap;
}
public override string ToString()
{
var stringBuilder = new StringBuilder();
for (int x = 0; x < map.GetLength(0); x++)
{
for (int y = 0; y < map.GetLength(1); y++)
{
if (map[x, y] == 1)
stringBuilder.Append("+ ");
else
stringBuilder.Append(" ");
}
stringBuilder.AppendLine();
}
return stringBuilder.ToString();
}
private IEnumerable<int> GetNeighbors(int x, int y)
{
var mapSizeX = map.GetLength(0);
var mapSizeY = map.GetLength(1);
if ((x - 1) >= 0)
yield return map[x - 1, y]; // left
if ((x + 1) < mapSizeX)
yield return map[x + 1, y]; // right
if ((y - 1) >= 0)
yield return map[x, y - 1]; // top
if ((y + 1) < mapSizeY)
yield return map[x, y + 1]; // bottom
if ((x - 1) >= 0 && (y - 1) >= 0)
yield return map[x - 1, y - 1]; // top-left
if ((x - 1) >= 0 && (y + 1) < mapSizeY)
yield return map[x - 1, y + 1]; // bottom-left
if ((x + 1) < mapSizeX && (y + 1) < mapSizeY)
yield return map[x + 1, y + 1]; // top-right
if ((x + 1) < mapSizeX && (y - 1) >= 0)
yield return map[x + 1, y - 1]; // bottom-right
}
}
public class Program
{
static void Main()
{
int[,] pentadecathlon = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
var game = new GameOfLife(pentadecathlon);
while (true)
{
Console.Clear();
Console.WriteLine(game.ToString());
game.Transition();
Thread.Sleep(1000);
}
}
}