From 80781f7eefe93bd18f58f2a4624e67da84345543 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Wed, 21 Dec 2022 01:19:53 +0100 Subject: [PATCH] Fixed recyclers not built next to each other --- FallChallenge2022.cs | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/FallChallenge2022.cs b/FallChallenge2022.cs index fc28bc2..6297ce4 100644 --- a/FallChallenge2022.cs +++ b/FallChallenge2022.cs @@ -20,7 +20,9 @@ namespace Codingame { state.MyMatter = int.Parse(inputs[0]); state.OppMatter = int.Parse(inputs[1]); for (var i = 0; i < height; i++) for (var j = 0; j < width; j++) { - ref var field = ref state.Fields[j, i]; + Coordinate2D coord = new(j, i); + ref var field = ref state[coord]; + field.Coordinates = coord; inputs = ReadInput().Split(' '); field.ScrapAmount = int.Parse(inputs[0]); field.Owner = (Owner)int.Parse(inputs[1]); @@ -42,10 +44,12 @@ namespace Codingame { public static IEnumerable GetCommands(GameState state) { var units = state.FindUnits(); + var enemies = state.FindUnits(Owner.Enemy); var neutral = state.FindFields(Owner.Neutral); var recyclers = state.FindFields(i => i.Recycler).Keys.ToList(); var possibleBuilds = state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Take(1).ToList(); while (possibleBuilds.Count > 0) { + Console.Error.WriteLine(string.Join("\n", state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Select(i => $"Recycler at {i.Key} yields {i.Value} resources!"))); var possibleBuild = possibleBuilds.First(); if (state.MyMatter < GameState.RecyclerCost) break; state.MyMatter -= GameState.RecyclerCost; @@ -54,13 +58,15 @@ namespace Codingame { recyclers.Add(possibleBuild.Key); possibleBuilds = state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Take(1).ToList(); } + while (state.MyMatter >= GameState.RobotCost) { + var maxRobots = state.MyMatter / GameState.RobotCost; + var cost = maxRobots * GameState.RobotCost; + yield return new Spawn(maxRobots, units.First().Key); + state.MyMatter -= cost; + } foreach (var (position, amount) in units) { - for (int i = 0; i < amount; i++) { - if (neutral.Count == 0) yield break; - var emptySpot = neutral.Keys.First(); - if (!neutral.Remove(emptySpot, out var field)) throw new InvalidProgramException(); - yield return new Move(1, position, emptySpot); - } + var (enemyPosition, enemyAmount) = enemies.MinBy(i => (i.Key - position).ManhattanDistance); + yield return new Move(amount, position, enemyPosition); } } } @@ -108,6 +114,7 @@ namespace Codingame { } public record struct GameState(int Width, int Height, FieldState[,] Fields, int MyMatter = 0, int OppMatter = 0) { public const int RecyclerCost = 10; + public const int RobotCost = 10; public FieldState FieldAt(Coordinate2D coord) => this[coord]; public ref FieldState this[Coordinate2D coord] => ref Fields[coord.X, coord.Y]; public Dictionary PossibleRecyclerSpots(IReadOnlyCollection recyclers) { @@ -116,21 +123,19 @@ namespace Codingame { for (int x = 0; x < Width; x++) { Coordinate2D coord = new(x, y); var field = this[coord]; - if (!field.CanBuild) continue; + if (!field.CanBuild || field.InRangeOfRecycler) continue; var potentialMaterial = coord.Neighbors().Append(coord) .Where(WithinBounds) - .Where(i => !NearRecycler(recyclers, i)) .Select(FieldAt) + .Where(i => !i.InRangeOfRecycler && !NearRecycler(recyclers, i.Coordinates)) .Sum(i => i.ScrapAmount); if (potentialMaterial != 0) found[coord] = potentialMaterial; } return found; } - public static bool NearRecycler(IReadOnlyCollection recyclers, Coordinate2D coord) - => recyclers.Any(i => (i - coord).ManhattanDistance < 2); - + => recyclers.Any(i => (i - coord).ManhattanDistance <= 1); public Dictionary FindWhere(Func find) { Dictionary found = new(); for (int y = 0; y < Height; y++) @@ -170,5 +175,5 @@ namespace Codingame { public static Coordinate2D operator +(Coordinate2D left, Coordinate2D right) => new(left.X + right.X, left.Y + right.Y); public int ManhattanDistance => Math.Abs(X) + Math.Abs(Y); } - public record struct FieldState(int ScrapAmount, Owner Owner, int Units, bool Recycler, bool CanBuild, bool CanSpawn, bool InRangeOfRecycler); + public record struct FieldState(int ScrapAmount, Owner Owner, int Units, bool Recycler, bool CanBuild, bool CanSpawn, bool InRangeOfRecycler, Coordinate2D Coordinates); }