public static List <Command> GenerateCommandQueue() { foreach (var ship in AvailableShips) { var dirs = DirectionExtensions.ALL_CARDINALS.ToList(); if (ship.CellHalite > 0) { dirs.Insert(0, Direction.STILL); } else { dirs.Add(Direction.STILL); } if (dirs.Any(d => Safety.IsSafeMove(ship, d))) { AddMove(ship.Move(dirs.First(d => Safety.IsSafeMove(ship, d)), "Left-over ship, making move from fleet logic.")); } else if (dirs.Any(d => !CollisionCells.Contains(GameInfo.CellAt(ship, d)))) { AddMove(ship.Move(dirs.First(d => !CollisionCells.Contains(GameInfo.CellAt(ship, d))), "Left-over ship, Moving towards an enemy instead of crashing myself...")); } } var commands = usedShips.Values.ToList();; if (shouldSpawnShip) { commands.Add(GameInfo.Me.shipyard.Spawn()); } return(commands); }
// excludes start and end nodes public static List <MapCell> CalculateGreedyPathOfLeastResistance(Position start, Position end, HashSet <MapCell> CellsToAvoid = null) { List <MapCell> path = new List <MapCell>(); Position next = start; while (true) { var cells = end.GetAllDirectionsTo(next).Select(d => GameInfo.CellAt(next, d)); cells = cells.OrderBy(c => c.halite); var cell = cells.ElementAt(0); if (cell.position.Equals(end)) { return(path); } if (CellsToAvoid != null) { cells = cells.Where(c => !CellsToAvoid.Contains(c)); } if (cells.Count() == 0) { return(null); } next = cell.position; path.Add(cell); } }
private static bool ShouldCreateDropoff() => Fleet.ShipCount / GameInfo.Me.GetDropoffs().Count >= MyBot.HParams[Parameters.SHIPS_PER_DROPOFF]; // need a minimum of ships per drop private static bool CanCreateDropoff(Position pos) { //int target = 4000; // 4000 + 1000 for ship cost int halite = GameInfo.Me.halite; var closestShips = GameInfo.CellAt(pos).MyClosestShips(); var ship = closestShips.OrderBy(s => s.halite).First(); halite += ship.halite - Navigation.PathCost(ship.position, pos); halite += (int)(.75 * GameInfo.CellAt(pos).halite); return(halite > 4000); }
public static int AvailableMoveCounts(Ship ship, bool includeStill) { var dirs = includeStill ? DirectionExtensions.ALL_DIRECTIONS : DirectionExtensions.ALL_CARDINALS; int count = 0; foreach (var d in dirs) { if (!Fleet.CollisionCells.Contains(GameInfo.CellAt(ship, d))) { count++; } } return(count); }
// excludes start and end nodes public static List <MapCell> CalculatePathOfLeastResistance(Position start, Position end, HashSet <MapCell> CellsToAvoid = null) { HashSet <MapCell> visited = new HashSet <MapCell>(); List <Path> Paths = new List <Path>(); foreach (var d in end.GetAllDirectionsTo(start)) { var cell = GameInfo.CellAt(start, d); if (CellsToAvoid == null || !CellsToAvoid.Contains(cell)) { Paths.Add(new Path { resistance = cell.halite / 10, path = new List <MapCell> { cell } }); } } while (true) { if (Paths.Count == 0) { return(null); } int shortest = Paths.Min(x => x.resistance); var shortestPath = Paths.First(x => x.resistance == shortest); var last = shortestPath.path.Last(); foreach (var d in end.GetAllDirectionsTo(last.position)) { var cell = GameInfo.CellAt(last.position, d); if (cell.position.AsPoint.Equals(end.AsPoint)) { shortestPath.path.Add(cell); return(shortestPath.path); } if (!visited.Contains(cell) && (CellsToAvoid == null || !CellsToAvoid.Contains(cell))) { var newPath = shortestPath.path.ToList(); newPath.Add(cell); Paths.Add(new Path { path = newPath, resistance = shortestPath.resistance + (cell.halite / 10) }); visited.Add(cell); } } Paths.Remove(shortestPath); } }
// 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 void AddMove(Command command) { availableShipMoves.Remove(command.Ship); Safety.TwoTurnAvoider.Remove(command.TargetCell); usedShips[command.Ship] = command; collisionCells.Add(command.TargetCell); Log.LogMessage(command.Comment); if (availableShipMoves.Any(kvp => GameInfo.AvailableMoveCounts(kvp.Key, !command.Ship.OnDropoff) == 1)) { var shipToMove = availableShipMoves.First(kvp => GameInfo.AvailableMoveCounts(kvp.Key, !command.Ship.OnDropoff) == 1).Key; var dirs = shipToMove.OnDropoff ? DirectionExtensions.ALL_CARDINALS : DirectionExtensions.ALL_DIRECTIONS; if (dirs.Any(d => !CollisionCells.Contains(GameInfo.CellAt(shipToMove, d)))) { var dir = dirs.First(d => !CollisionCells.Contains(GameInfo.CellAt(shipToMove, d))); AddMove(shipToMove.Move(dir, $"Moving ship {shipToMove.Id} because there were no other moves remaining")); } } }
public static bool IsAccessible(Position start, Position end, bool collisionOnly = false) { HashSet <MapCell> used = collisionOnly? Fleet.CollisionCells.ToHashSet() : Fleet.ProbablyOccupiedCells; Stack <Position> nexts = new Stack <Position>(); nexts.Push(start); while (nexts.Any()) { var n = nexts.Pop(); if (end.Equals(n)) { return(true); } used.Add(GameInfo.CellAt(n)); var cells = end.GetAllDirectionsTo(n).Select(d => GameInfo.CellAt(n, d)); cells = cells.Where(c => !used.Contains(c)); cells.ToList().ForEach(c => nexts.Push(c.position)); } return(false); }
public static bool IsBlockedByEnemies(Position start, Position end) { HashSet <MapCell> used = new HashSet <MapCell>(); Stack <Position> nexts = new Stack <Position>(); nexts.Push(start); while (nexts.Any()) { var n = nexts.Pop(); if (end.Equals(n)) { return(false); } used.Add(GameInfo.CellAt(n)); var cells = end.GetAllDirectionsTo(n).Select(d => GameInfo.CellAt(n, d)); cells = cells.Where(c => !used.Contains(c) && !c.IsOccupiedByOpponent); cells.ToList().ForEach(c => nexts.Push(c.position)); } return(true); }
public static bool IsSafeMove(Ship ship, Direction direction) { MapCell target = GameInfo.CellAt(ship, direction); if (Fleet.CollisionCells.Contains(target)) { return(false); } // calculate recovery chance... double recoveryChance = 1.0; if (target.IsThreatened) { var lowestEnemy = GameInfo.LowestNeighboringOpponentShip(target); recoveryChance = new Zone(target.position, 5).CargoRecoveryLikelihood(ship, lowestEnemy); } return(recoveryChance > MyBot.HParams[Parameters.SAFETY_RATIO]); }
public static void SpawnShip() { collisionCells.Add(GameInfo.CellAt(GameInfo.Me.shipyard.position)); shouldSpawnShip = true; }
public static int PathCost(Position start, Position end, HashSet <MapCell> CellsToAvoid = null) { var polr = CalculatePathOfLeastResistance(start, end, CellsToAvoid); return(polr.Sum(p => (int)(p.halite / 10)) + (int)(GameInfo.CellAt(start).halite / 10)); }
public void Add(Ship ship, MapCell target, List <Direction> dirs) => dirs.ForEach(d => Add(ship, GameInfo.CellAt(target, d)));
public static bool IsCompletelySafeMove(Ship s, Direction d) => IsSafeMove(s, d); // && (!GameInfo.CellAt(s, d).IsThreatened || s.DistanceToMyDropoff <= 3) ; public static bool IsSafeAndAvoids2Cells(Ship s, Direction d) => IsSafeMove(s, d) && (d == Direction.STILL || (s.halite - (s.CellHalite * .1) >= GameInfo.CellAt(s, d).halite * .1) || TwoTurnAvoider.IsOkay(s, d));
public bool IsOkay(Ship s, Direction d) => IsOkay(GameInfo.CellAt(s, d));