private static int ApplyBuildAlmostReachableMaxHeightCellRule(ScoringContext context) { int score = 0; List<Position> reachableNeighbours = GetReachableNeighbours(context.CurrentPosition, context.Map); foreach (Position neighbour in reachableNeighbours) { // If this is the neighbour I'm building on, don't forget to increment int neighbourHeight = context.Map[neighbour.X, neighbour.Y]; if (neighbour.Equals(context.NextBuildPosition)) neighbourHeight++; if (neighbourHeight == 3) { score += 5; } if (neighbourHeight == 2) { score += 2; } if (neighbourHeight == 1) { score += 1; } } // Penalize dead-ends score -= (8 - reachableNeighbours.Count) * 2; return score; }
private static int ComputeActionScore( GameAction candidate, int[,] map, Position[] units) { var scoringContext = new ScoringContext(candidate, map, units); // TODO: maybe add a bit of randomness to the initial score? int score = 0; #region Movement analysis score += ApplyGoToMaxHeightRule(scoringContext); score += ApplyGoHigherRule(scoringContext); score += ApplyCenterAffinityRule(scoringContext); #endregion #region Build analysis score += ApplyBuildReachableMaxHeightCellRule(scoringContext); score += ApplyBuildAlmostReachableMaxHeightCellRule(scoringContext); // Avoid building height 4 as I might block myself, unless I'm blocking the opponent? // TODO #endregion Console.Error.WriteLine($"Evaluating action: {candidate}"); Console.Error.WriteLine($"Score: {score}"); return score; }
private static int ApplyBuildReachableMaxHeightCellRule(ScoringContext context) { // If I'm moving to height 2 and I can build a height 3 cell it's great for next round if (context.NextPositionHeight == 2 && context.NextBuildHeight == 3) { return 25; } return 0; }
private static int ApplyGoHigherRule(ScoringContext context) { // It's probably always good to go higher if (context.NextPositionHeight > context.CurrentPositionHeight) { return 25; } return 0; }
private static int ApplyGoToMaxHeightRule(ScoringContext context) { // If you can score a point, it's most likely a good thing to do if (context.NextPositionHeight == 3) { return 30; } return 0; }
private static int ApplyCenterAffinityRule(ScoringContext context) { // Going in the direction of the center is probably good var center = new Position(context.MapSize / 2, context.MapSize / 2); int currentDistanceToCenter = center.GetDistance(context.CurrentPosition); int nextDistanceToCenter = center.GetDistance(context.NextPosition); if (nextDistanceToCenter < currentDistanceToCenter) { return 2 * (currentDistanceToCenter - nextDistanceToCenter) / context.MapSize; } return 0; }