| 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:
 133:
 134:
 135:
 136:
 137:
 138:
 139:
 140:
 141:
 142:
 143:
 144:
 145:
 146:
 147:
 148:
 149:
 150:
 151:
 152:
 153:
 154:
 155:
 156:
 157:
 158:
 159:
 160:
 161:
 162:
 163:
 164:
 165:
 
 | using System;using System.Threading.Tasks;
 
 namespace Life
 {
 public class LifeSimulation
 {
 private bool[,] world;
 private bool[,] nextGeneration;
 private Task processTask;
 
 public LifeSimulation(int size)
 {
 if (size < 0) throw new ArgumentOutOfRangeException("Size must be greater than zero");
 this.Size = size;
 world = new bool[size, size];
 nextGeneration = new bool[size, size];
 }
 
 public int Size { get; private set; }
 public int Generation { get; private set; }
 
 public Action<bool[,]> NextGenerationCompleted;
 
 public bool this[int x, int y]
 {
 get { return this.world[x, y]; }
 set { this.world[x, y] = value; }
 }
 
 public bool ToggleCell(int x, int y)
 {
 bool currentValue = this.world[x, y];
 return this.world[x, y] = !currentValue;
 }
 
 public void Update()
 {
 if (this.processTask != null && this.processTask.IsCompleted)
 {
 var flip = this.nextGeneration;
 this.nextGeneration = this.world;
 this.world = flip;
 Generation++;
 
 this.processTask = this.ProcessGeneration();
 
 if (NextGenerationCompleted != null) NextGenerationCompleted(this.world);
 }
 }
 
 public void BeginGeneration()
 {
 if (this.processTask == null || (this.processTask != null && this.processTask.IsCompleted))
 {
 this.processTask = this.ProcessGeneration();
 }
 }
 
 public void Wait()
 {
 if (this.processTask != null)
 {
 this.processTask.Wait();
 }
 }
 
 private Task ProcessGeneration()
 {
 return Task.Factory.StartNew(() =>
 {
 Parallel.For(0, Size, x =>
 {
 Parallel.For(0, Size, y =>
 {
 int numberOfNeighbors = IsNeighborAlive(world, Size, x, y, -1, 0)
 + IsNeighborAlive(world, Size, x, y, -1, 1)
 + IsNeighborAlive(world, Size, x, y, 0, 1)
 + IsNeighborAlive(world, Size, x, y, 1, 1)
 + IsNeighborAlive(world, Size, x, y, 1, 0)
 + IsNeighborAlive(world, Size, x, y, 1, -1)
 + IsNeighborAlive(world, Size, x, y, 0, -1)
 + IsNeighborAlive(world, Size, x, y, -1, -1);
 
 bool shouldLive = false;
 bool isAlive = world[x, y];
 
 if (isAlive && (numberOfNeighbors == 2 || numberOfNeighbors == 3))
 {
 shouldLive = true;
 }
 else if (!isAlive && numberOfNeighbors == 3)                         {
 shouldLive = true;
 }
 
 nextGeneration[x, y] = shouldLive;
 
 });
 });
 });
 }
 
 private static int IsNeighborAlive(bool[,] world, int size, int x, int y, int offsetx, int offsety)
 {
 int result = 0;
 
 int proposedOffsetX = x + offsetx;
 int proposedOffsetY = y + offsety;
 bool outOfBounds = proposedOffsetX < 0 || proposedOffsetX >= size | proposedOffsetY < 0 || proposedOffsetY >= size;
 if (!outOfBounds)
 {
 result = world[x + offsetx, y + offsety] ? 1 : 0;
 }
 return result;
 }
 }
 
 class Program
 {
 static void Main(string[] args)
 {
 LifeSimulation sim = new LifeSimulation(10);
 
 sim.ToggleCell(5, 5);
 sim.ToggleCell(5, 6);
 sim.ToggleCell(5, 7);
 
 sim.BeginGeneration();
 sim.Wait();
 OutputBoard(sim);
 
 sim.Update();
 sim.Wait();
 OutputBoard(sim);
 
 sim.Update();
 sim.Wait();
 OutputBoard(sim);
 
 Console.ReadKey();
 }
 
 private static void OutputBoard(LifeSimulation sim)
 {
 var line = new String('-', sim.Size);
 Console.WriteLine(line);
 
 for (int y = 0; y < sim.Size; y++)
 {
 for (int x = 0; x < sim.Size; x++)
 {
 Console.Write(sim[x, y] ? "1" : "0");
 }
 
 Console.WriteLine();
 }
 }
 }
 }
 |