Fixed recyclers not built next to each other
This commit is contained in:
parent
9bd9a063f8
commit
80781f7eef
@ -20,7 +20,9 @@ namespace Codingame {
|
|||||||
state.MyMatter = int.Parse(inputs[0]);
|
state.MyMatter = int.Parse(inputs[0]);
|
||||||
state.OppMatter = int.Parse(inputs[1]);
|
state.OppMatter = int.Parse(inputs[1]);
|
||||||
for (var i = 0; i < height; i++) for (var j = 0; j < width; j++) {
|
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(' ');
|
inputs = ReadInput().Split(' ');
|
||||||
field.ScrapAmount = int.Parse(inputs[0]);
|
field.ScrapAmount = int.Parse(inputs[0]);
|
||||||
field.Owner = (Owner)int.Parse(inputs[1]);
|
field.Owner = (Owner)int.Parse(inputs[1]);
|
||||||
@ -42,10 +44,12 @@ namespace Codingame {
|
|||||||
|
|
||||||
public static IEnumerable<Command> GetCommands(GameState state) {
|
public static IEnumerable<Command> GetCommands(GameState state) {
|
||||||
var units = state.FindUnits();
|
var units = state.FindUnits();
|
||||||
|
var enemies = state.FindUnits(Owner.Enemy);
|
||||||
var neutral = state.FindFields(Owner.Neutral);
|
var neutral = state.FindFields(Owner.Neutral);
|
||||||
var recyclers = state.FindFields(i => i.Recycler).Keys.ToList();
|
var recyclers = state.FindFields(i => i.Recycler).Keys.ToList();
|
||||||
var possibleBuilds = state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Take(1).ToList();
|
var possibleBuilds = state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Take(1).ToList();
|
||||||
while (possibleBuilds.Count > 0) {
|
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();
|
var possibleBuild = possibleBuilds.First();
|
||||||
if (state.MyMatter < GameState.RecyclerCost) break;
|
if (state.MyMatter < GameState.RecyclerCost) break;
|
||||||
state.MyMatter -= GameState.RecyclerCost;
|
state.MyMatter -= GameState.RecyclerCost;
|
||||||
@ -54,13 +58,15 @@ namespace Codingame {
|
|||||||
recyclers.Add(possibleBuild.Key);
|
recyclers.Add(possibleBuild.Key);
|
||||||
possibleBuilds = state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Take(1).ToList();
|
possibleBuilds = state.PossibleRecyclerSpots(recyclers).OrderByDescending(i => i.Value).Take(1).ToList();
|
||||||
}
|
}
|
||||||
foreach (var (position, amount) in units) {
|
while (state.MyMatter >= GameState.RobotCost) {
|
||||||
for (int i = 0; i < amount; i++) {
|
var maxRobots = state.MyMatter / GameState.RobotCost;
|
||||||
if (neutral.Count == 0) yield break;
|
var cost = maxRobots * GameState.RobotCost;
|
||||||
var emptySpot = neutral.Keys.First();
|
yield return new Spawn(maxRobots, units.First().Key);
|
||||||
if (!neutral.Remove(emptySpot, out var field)) throw new InvalidProgramException();
|
state.MyMatter -= cost;
|
||||||
yield return new Move(1, position, emptySpot);
|
|
||||||
}
|
}
|
||||||
|
foreach (var (position, amount) in units) {
|
||||||
|
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 record struct GameState(int Width, int Height, FieldState[,] Fields, int MyMatter = 0, int OppMatter = 0) {
|
||||||
public const int RecyclerCost = 10;
|
public const int RecyclerCost = 10;
|
||||||
|
public const int RobotCost = 10;
|
||||||
public FieldState FieldAt(Coordinate2D coord) => this[coord];
|
public FieldState FieldAt(Coordinate2D coord) => this[coord];
|
||||||
public ref FieldState this[Coordinate2D coord] => ref Fields[coord.X, coord.Y];
|
public ref FieldState this[Coordinate2D coord] => ref Fields[coord.X, coord.Y];
|
||||||
public Dictionary<Coordinate2D, int> PossibleRecyclerSpots(IReadOnlyCollection<Coordinate2D> recyclers) {
|
public Dictionary<Coordinate2D, int> PossibleRecyclerSpots(IReadOnlyCollection<Coordinate2D> recyclers) {
|
||||||
@ -116,21 +123,19 @@ namespace Codingame {
|
|||||||
for (int x = 0; x < Width; x++) {
|
for (int x = 0; x < Width; x++) {
|
||||||
Coordinate2D coord = new(x, y);
|
Coordinate2D coord = new(x, y);
|
||||||
var field = this[coord];
|
var field = this[coord];
|
||||||
if (!field.CanBuild) continue;
|
if (!field.CanBuild || field.InRangeOfRecycler) continue;
|
||||||
var potentialMaterial = coord.Neighbors().Append(coord)
|
var potentialMaterial = coord.Neighbors().Append(coord)
|
||||||
.Where(WithinBounds)
|
.Where(WithinBounds)
|
||||||
.Where(i => !NearRecycler(recyclers, i))
|
|
||||||
.Select(FieldAt)
|
.Select(FieldAt)
|
||||||
|
.Where(i => !i.InRangeOfRecycler && !NearRecycler(recyclers, i.Coordinates))
|
||||||
.Sum(i => i.ScrapAmount);
|
.Sum(i => i.ScrapAmount);
|
||||||
if (potentialMaterial != 0)
|
if (potentialMaterial != 0)
|
||||||
found[coord] = potentialMaterial;
|
found[coord] = potentialMaterial;
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool NearRecycler(IReadOnlyCollection<Coordinate2D> recyclers, Coordinate2D coord)
|
public static bool NearRecycler(IReadOnlyCollection<Coordinate2D> recyclers, Coordinate2D coord)
|
||||||
=> recyclers.Any(i => (i - coord).ManhattanDistance < 2);
|
=> recyclers.Any(i => (i - coord).ManhattanDistance <= 1);
|
||||||
|
|
||||||
public Dictionary<Coordinate2D, int> FindWhere(Func<FieldState, int> find) {
|
public Dictionary<Coordinate2D, int> FindWhere(Func<FieldState, int> find) {
|
||||||
Dictionary<Coordinate2D, int> found = new();
|
Dictionary<Coordinate2D, int> found = new();
|
||||||
for (int y = 0; y < Height; y++)
|
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 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 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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user