private int GenerateLevel(int level, TileLevels levels) { var current = levels.TileAt(level); int newGeneration = 0; for (int y = 0; y < Size; y++) { for (int x = 0; x < Size; x++) { if (x == 2 && y == 2) { continue; } var bugsAround = BugsAroundRecursive(level, x, y, levels).Sum(); var isBug = IsBug(current, x, y); var bugLives = isBug && bugsAround == 1; var infected = !isBug && bugsAround > 0 && bugsAround < 3; var nextGenerationIsBug = bugLives || infected; if (nextGenerationIsBug) { newGeneration |= PositionToInt(x, y); } } } return(newGeneration); }
private TileLevels GenerateRecursive(TileLevels levels) { var level = 0; int newGeneration = GenerateLevel(level, levels); var newTileLevels = new TileLevels(newGeneration); int max = levels.Levels.Keys.Max(); int min = levels.Levels.Keys.Min(); level = 1; do { newGeneration = GenerateLevel(level, levels); newTileLevels.AddTile(level, newGeneration); level++; } while (newGeneration != 0 || level < max); level = -1; do { newGeneration = GenerateLevel(level, levels); newTileLevels.AddTile(level, newGeneration); level--; } while (newGeneration != 0 || level > min); return(newTileLevels); }
public int BugsAfterMinutes(int encodedTilesAtBaseLevel, int minutes) { var tileLevels = new TileLevels(encodedTilesAtBaseLevel); foreach (var _ in Enumerable.Range(1, minutes)) { tileLevels = GenerateRecursive(tileLevels); } return(tileLevels.Levels.Values.Sum(tile => Decode(tile, '1', '0').Count(c => c == '1'))); }
private List <int> BugsAroundRecursive(int level, int x, int y, TileLevels tiles) { var encodedTilesAtLevel = tiles.TileAt(level); var encodedTilesAtNextLevel = tiles.TileAt(level + 1); var encodedTilesAtPreviousLevel = tiles.TileAt(level - 1); var neighbors = new List <int>(); var topAtLevel = IsBug(encodedTilesAtLevel, x, y - 1) ? 1 : 0; var rightAtLevel = IsBug(encodedTilesAtLevel, x + 1, y) ? 1 : 0; var belowAtLevel = IsBug(encodedTilesAtLevel, x, y + 1) ? 1 : 0; var leftAtLevel = IsBug(encodedTilesAtLevel, x - 1, y) ? 1 : 0; if (x == 2 & y == 1) { neighbors.AddRange(new[] { topAtLevel, rightAtLevel, leftAtLevel }); // next level top side for (int xi = 0; xi < Size; xi++) { neighbors.Add(IsBug(encodedTilesAtNextLevel, xi, 0) ? 1 : 0); } } else if (x == 3 && y == 2) { neighbors.AddRange(new[] { topAtLevel, rightAtLevel, belowAtLevel }); // next level right side for (int yi = 0; yi < Size; yi++) { neighbors.Add(IsBug(encodedTilesAtNextLevel, Size - 1, yi) ? 1 : 0); } } else if (x == 2 && y == 3) { neighbors.AddRange(new[] { rightAtLevel, belowAtLevel, leftAtLevel }); // next level bottom side for (int xi = 0; xi < Size; xi++) { neighbors.Add(IsBug(encodedTilesAtNextLevel, xi, Size - 1) ? 1 : 0); } } else if (x == 1 && y == 2) { neighbors.AddRange(new[] { topAtLevel, belowAtLevel, leftAtLevel }); // next level left side for (int yi = 0; yi < Size; yi++) { neighbors.Add(IsBug(encodedTilesAtNextLevel, 0, yi) ? 1 : 0); } } else if (x == 0 || x == Size - 1 || y == 0 || y == Size - 1) { if (x == 0 && y == 0) { neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 2, 1) ? 1 : 0); neighbors.Add(rightAtLevel); neighbors.Add(belowAtLevel); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 1, 2) ? 1 : 0); } else if (x > 0 && x < Size - 1 && y == 0) { neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 2, 1) ? 1 : 0); neighbors.Add(rightAtLevel); neighbors.Add(belowAtLevel); neighbors.Add(leftAtLevel); } else if (x == Size - 1 && y == 0) { neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 2, 1) ? 1 : 0); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 3, 2) ? 1 : 0); neighbors.Add(belowAtLevel); neighbors.Add(leftAtLevel); } else if (x == Size - 1 && y > 0 && y < Size - 1) { neighbors.Add(topAtLevel); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 3, 2) ? 1 : 0); neighbors.Add(belowAtLevel); neighbors.Add(leftAtLevel); } else if (x == Size - 1 && y == Size - 1) { neighbors.Add(topAtLevel); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 3, 2) ? 1 : 0); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 2, 3) ? 1 : 0); neighbors.Add(leftAtLevel); } else if (x > 0 && x < Size - 1 && y == Size - 1) { neighbors.Add(topAtLevel); neighbors.Add(rightAtLevel); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 2, 3) ? 1 : 0); neighbors.Add(leftAtLevel); } else if (x == 0 && y == Size - 1) { neighbors.Add(topAtLevel); neighbors.Add(rightAtLevel); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 2, 3) ? 1 : 0); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 1, 2) ? 1 : 0); } else if (x == 0 && y > 0 && y < Size - 1) { neighbors.Add(topAtLevel); neighbors.Add(rightAtLevel); neighbors.Add(belowAtLevel); neighbors.Add(IsBug(encodedTilesAtPreviousLevel, 1, 2) ? 1 : 0); } } else { neighbors.AddRange(new [] { topAtLevel, rightAtLevel, belowAtLevel, leftAtLevel }); } return(neighbors); }