using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using GameOfLife.Entities; namespace GameOfLife { public class LifeHashSet : LifeBase { protected HashSet World; public LifeHashSet() { World = new HashSet(); } public LifeHashSet(IEnumerable cells) : this() { foreach (var cell in cells) World.Add(cell); } public override bool IsCellAlive(Cell cell) => World.Contains(cell); protected override bool ToggleCell_Internal(Cell cell) { if (IsCellAlive(cell)) { World.Remove(cell); return false; } World.Add(cell); return true; } protected override int IncrementGeneration_Internal() { World = GetNextGeneration_Parallel(NeighborhoodField); return World.Count; } private HashSet GetNextGeneration_Serial(IEnumerable> field) { return new HashSet( field.Where( cellNeighborCount => LifeRule(World.Contains(cellNeighborCount.Item1), cellNeighborCount.Item2)) .Select(c => c.Item1)); } private HashSet GetNextGeneration_Parallel(IEnumerable> field) { var nextGeneration = new HashSet(); Parallel.ForEach( field, () => new HashSet(), (cellNeighborCount, loop, localNextGen) => { var cell = cellNeighborCount.Item1; var neighborCount = cellNeighborCount.Item2; if (LifeRule(World.Contains(cell), neighborCount)) localNextGen.Add(cell); return localNextGen; }, globalNextGen => { lock (nextGeneration) foreach (var cell in globalNextGen) nextGeneration.Add(cell); } ); return nextGeneration; } public override IEnumerable LivingCells => World; } }