private List <Action> SelectPowerActions() { var powerActions = new List <Action>(); ////Silence ? if (TrySilence(out var silenceDirection, out var moves)) { powerActions.Add(MySubmarine.Silence(silenceDirection, moves)); } ////Place mine ? if (TrySelectMinePosition(out var position, out var mineDirection)) { powerActions.Add(MySubmarine.PlaceMine((position, mineDirection))); } ////Trigger mine ? if (TryTriggerMine(out var minePosition)) { powerActions.Add(MySubmarine.TriggerMine(minePosition)); } ////Trigger torpedo ? if (TryLaunchTorpedo(out var torpedoPosition)) { powerActions.Add(MySubmarine.LaunchTorpedo(torpedoPosition)); } return(powerActions); }
private bool TrySelectMinePosition(out Position position, out Direction direction) { position = Position.None; direction = Direction.E; if (_gameState.MineAvailable == false) { return(false); } var myPosition = MySubmarine.Position; var neighborWaterPositions = Map.GetNeighborPositions(myPosition); var placedMines = MySubmarine.GetPlacedMines(); foreach (var item in neighborWaterPositions) { var possibleMinePosition = item.Value; var possibleMineDirection = item.Key; if (MySubmarine.HasPlacedMineAt(possibleMinePosition) == false) { var blastedPositions = GetBlastedPositions(possibleMinePosition); var blastOtherMines = blastedPositions.Any(p => placedMines.Contains(p)); if (blastOtherMines == false) { position = possibleMinePosition; direction = possibleMineDirection; } } } return(position.IsNot(Position.None)); }
private Action SelectMoveAction() { var fromPosition = MySubmarine.Position; var possibleMoves = GetPossibleDirectionsForMove(fromPosition); var possibleMoveCount = possibleMoves.Count; if (possibleMoveCount == 0) { return(MySubmarine.SurfaceMySubmarine()); } if (possibleMoveCount == 1) { var possibleMove = possibleMoves.Single(); return(MySubmarine.MoveMySubmarine(possibleMove, SelectPowerToCharge())); } var visitedPositions = MySubmarine.VisitedPositions; var rankedMoves = new Dictionary <int, List <Tuple <Position, Direction> > >(); foreach (var possibleMove in possibleMoves) { var floodFillEngine = new FloodFillEngine(visitedPositions); var filledRegion = floodFillEngine.Run(possibleMove.Item1); var score = filledRegion.Count; if (rankedMoves.ContainsKey(score) == false) { rankedMoves[score] = new List <Tuple <Position, Direction> >(); } rankedMoves[score].Add(new Tuple <Position, Direction>(possibleMove.Item1, possibleMove.Item2)); } var bestMoves = rankedMoves.OrderByDescending(kvp => kvp.Key).First().Value; var bestMove = GetBestMoveByStealth(bestMoves); return(MySubmarine.MoveMySubmarine(bestMove, SelectPowerToCharge())); }
private bool TryTriggerMine(out Position bestMinePosition) { bestMinePosition = Position.None; var enemyPositions = OpponentSubmarine.PossiblePositions; if (enemyPositions.Count > 30) { return(false); } //Select the mine which blast the maximum opponent positions var minePositions = MySubmarine.GetPlacedMines(); var blastedOpponentPositions = 0; foreach (var minePosition in minePositions) { var blastedPositions = GetBlastedPositions(minePosition); if (blastedPositions.Contains(MySubmarine.Position) == false) { //Count how many possible positions are blasted var count = enemyPositions.Count(p => blastedPositions.Contains(p)); if (count >= 6 || enemyPositions.Count <= 6) { if (count > blastedOpponentPositions) { blastedOpponentPositions = count; bestMinePosition = minePosition; } } } } return(bestMinePosition.IsNot(Position.None)); }
static void Main(string[] args) { string[] inputs; inputs = Console.ReadLine().Split(' '); int width = int.Parse(inputs[0]); int height = int.Parse(inputs[1]); int myId = int.Parse(inputs[2]); List <string> rows = new List <string>(height); for (int i = 0; i < height; i++) { rows.Add(Console.ReadLine()); } Map.InitializeMap(height, width, rows.ToArray()); // Write an action using Console.WriteLine() // To debug: Console.Error.WriteLine("Debug messages..."); var initialPosition = new StartingPositionComputer().EvaluateBestPosition(); Console.WriteLine(initialPosition.ToString()); MySubmarine.MoveMySubmarine((initialPosition, Direction.E), Power.MINE); var mylastActions = new List <Action>(); var stopwatch = Stopwatch.StartNew(); // game loop while (true) { var line = Console.ReadLine(); var sonarLine = Console.ReadLine(); var txtOpponentOrders = Console.ReadLine(); var start = stopwatch.ElapsedMilliseconds; inputs = line.Split(' '); int x = int.Parse(inputs[0]); int y = int.Parse(inputs[1]); var myPosition = new Position(x, y); int myLife = int.Parse(inputs[2]); int oppLife = int.Parse(inputs[3]); int torpedoCooldown = int.Parse(inputs[4]); int sonarCooldown = int.Parse(inputs[5]); int silenceCooldown = int.Parse(inputs[6]); int mineCooldown = int.Parse(inputs[7]); var opponentActions = Action.Parse(txtOpponentOrders); Player.Debug("*** OpponentSubmarine.UpdateState ***"); OpponentSubmarine.UpdateState(oppLife, opponentActions, mylastActions); OpponentSubmarine.Debug(); Player.Debug(""); Player.Debug("*** MySubmarine.UpdateState ***"); MySubmarine.UpdateState(myLife, mylastActions, opponentActions); MySubmarine.Debug(); var stealthScore = $"{MySubmarine.PossiblePositions.Count} - {OpponentSubmarine.PossiblePositions.Count}"; var gameState = new GameState(torpedoCooldown, sonarCooldown, silenceCooldown, mineCooldown); var ai = new AI(gameState); var actions = ai.ComputeActions(); MySubmarine.ApplyActions(actions); mylastActions = actions; var messageAction = new MessageAction($"{stealthScore} ({stopwatch.ElapsedMilliseconds - start}ms)"); actions.Add(messageAction); Console.WriteLine(Action.ToText(actions)); } }