public double TurnsToFill(Ship ship, bool IsPrevious) { int areaVal = (int)GameInfo.Map.GetXLayers(cell.position, 2, true).Average(c => ValueMapping.Mapping[c].Value); int remainingToFill = (int)MyBot.HParams[Parameters.CARGO_TO_MOVE] - ship.halite; int totalTurns = (int)(GameInfo.Distance(ship.position, cell.position) / divisor); int remainingCellValue = Value; // value can/should be modified by reduce function while (remainingToFill > 0 && remainingCellValue * .25 >= areaVal * .125) { int amountMined = (int)(remainingCellValue * .25) + 1; remainingCellValue -= amountMined; remainingToFill -= amountMined; totalTurns++; } if (remainingToFill > 0) { int extraTurns = 1 + (int)(remainingToFill / (areaVal * .125 + 1)); totalTurns += 2 + extraTurns; // estimate # of turns to fill from nearby, +1 prevents /0 remainingToFill -= (int)(extraTurns * (areaVal * .125 + 1)); } totalTurns += closestDropDist; double res = totalTurns + (remainingToFill / 1000.0); if (IsPrevious) { res *= .95; // bias to previous move } return((double)totalTurns + (remainingToFill / 1000.0)); // differentiate 2 moves of same turns to prevent ships from swapping }
private double CalculateSafetyRatio() { if (NumMyShips + NumEnemyShips == 0) { return(1.0); } double myVal = MyShips.Sum(s => 1 / Math.Sqrt(1 + GameInfo.Distance(s, RootCell))); double enemyVal = EnemyShips.Sum(s => 1 / Math.Sqrt(1 + GameInfo.Distance(s, RootCell))); return((.5 + myVal) / (myVal + enemyVal)); }
public static void ProcessTurn() { // first make dropoffs... foreach (var ship in Fleet.AllShips) { if (GameInfo.NextDropoff != null && ship.position.Equals(GameInfo.NextDropoff.Position) && CanCreateDropoff(ship.position)) { Fleet.AddMove(ship.MakeDropoff()); } } // iterate bestdropoffs to potentially select next dropoff... if (GameInfo.ReserveForDropoff && !ShouldCreateDropoff()) { Log.LogMessage("drop-off: save for new dropoff disabled"); GameInfo.ReserveForDropoff = false; GameInfo.NextDropoff = null; } if (GameInfo.BestDropoffs.Any()) { GameInfo.BestDropoffs = GameInfo.BestDropoffs.OrderByDescending(d => d.VirtualDropValue * Math.Pow(.95, GameInfo.MyClosestDropDistance(d.Position))).ToList(); var bestDrop = GameInfo.BestDropoffs[0]; if (!GameInfo.ReserveForDropoff && ShouldCreateDropoff() && bestDrop.Cell.MyClosestShips().Any(s => GameInfo.Distance(s.position, bestDrop.Position) <= s.DistanceToMyDropoff)) { Log.LogMessage("drop-off: save halite for newdropoff has been flagged as true"); GameInfo.ReserveForDropoff = true; } if (GameInfo.ReserveForDropoff && CanCreateDropoff(bestDrop.Position)) { GameInfo.NextDropoff = GameInfo.BestDropoffs[0]; Log.LogMessage($"Next dropoff flagged as {GameInfo.NextDropoff.Position.ToString()}"); } } // Delete any dropoffs that have been mostly havested foreach (var d in GameInfo.BestDropoffs.ToList()) { int halite = (int)d.VirtualDropValue; if (GameInfo.Map.At(d.Position).IsStructure || halite < HaliteCutoff) { if (GameInfo.NextDropoff == d) { DeleteNextDropoff(); } GameInfo.BestDropoffs.Remove(d); Log.LogMessage($"drop-off at {d.Position.x},{d.Position.y} has been deleted... halite {halite}, cutoff {HaliteCutoff}"); } } }
// likelihood my ships can recover public double CargoRecoveryLikelihood(Ship myCrashedShip, Ship enemyCrashedShip) { // edge cases, cell is a structure if (GameInfo.CellAt(RootCell).IsOpponentsStructure) { return(0); } if (GameInfo.CellAt(RootCell).IsMyStructure) { return(1.0); } // do score calculation double myPoints = 0; double enemyPoints = 0; for (int i = 1; i < Layers; i++) { var cells = GameInfo.Map.GetXLayers(RootCell, i); int closestEnemyDrop = cells.Any(c => c.IsOpponentsStructure) ? cells.Where(c => c.IsOpponentsStructure).Min(c => GameInfo.Distance(RootCell, c.position)) : -1; int closestMyDrop = cells.Any(c => c.IsMyStructure) ? cells.Where(c => c.IsMyStructure).Min(c => GameInfo.Distance(RootCell, c.position)) : -1; foreach (var c in cells.Where(c => c.IsOccupied())) { double points = 1.0 / Math.Sqrt(i); var deduction = c.ship.halite; if (c.IsOccupiedByMe) { deduction = closestMyDrop >= 0 ? deduction * i / Layers : deduction; points *= (1000.0 - deduction) / 1000.0; myPoints += points; } else { deduction = closestEnemyDrop >= 0 ? deduction * i / Layers : deduction; points *= (1000.0 - deduction) / 1000.0; enemyPoints += points; } } } if (myPoints + enemyPoints == 0) { return(0); } double destructionRatio = 1.0; destructionRatio = (enemyCrashedShip.halite + 1000.0) / (myCrashedShip.halite + 1000.0); return(myPoints / (myPoints + enemyPoints) * destructionRatio); }
public static int MyClosestDropDistance(Position p) => GameInfo.Distance(p, MyClosestDrop(p));