private static IEnumerator PredictFinalPosionsOfOwnShip(GenericShip ship) { Selection.ChangeActiveShip(ship); VirtualBoard.SwitchToRealPosition(ship); Dictionary <string, NavigationResult> navigationResults = new Dictionary <string, NavigationResult>(); foreach (var maneuver in ship.GetManeuvers()) { GenericMovement movement = ShipMovementScript.MovementFromString(maneuver.Key); ship.SetAssignedManeuver(movement, isSilent: true); movement.Initialize(); movement.IsSimple = true; MovementPrediction prediction = new MovementPrediction(ship, movement); prediction.CalculateOnlyFinalPositionIgnoringCollisions(); VirtualBoard.SetVirtualPositionInfo(ship, prediction.FinalPositionInfo, prediction.CurrentMovement.ToString()); VirtualBoard.SwitchToVirtualPosition(ship); float minDistanceToEnemyShip, minDistanceToNearestEnemyInShotRange, minAngle; int enemiesInShotRange; ProcessHeavyGeometryCalculations(ship, out minDistanceToEnemyShip, out minDistanceToNearestEnemyInShotRange, out minAngle, out enemiesInShotRange); NavigationResult result = new NavigationResult() { movement = prediction.CurrentMovement, distanceToNearestEnemy = minDistanceToEnemyShip, distanceToNearestEnemyInShotRange = minDistanceToNearestEnemyInShotRange, angleToNearestEnemy = minAngle, enemiesInShotRange = enemiesInShotRange, isBumped = prediction.IsBumped, isLandedOnObstacle = prediction.IsLandedOnAsteroid, isOffTheBoard = prediction.IsOffTheBoard, FinalPositionInfo = prediction.FinalPositionInfo }; result.CalculatePriority(); if (DebugManager.DebugAiNavigation) { Console.Write("", LogTypes.AI); } navigationResults.Add(maneuver.Key, result); VirtualBoard.SwitchToRealPosition(ship); yield return(true); } ship.ClearAssignedManeuver(); VirtualBoard.UpdateNavigationResults(ship, navigationResults); }
private static IEnumerator ProcessMovementPredicition() { //Save current virtual positions Dictionary <GenericShip, ShipPositionInfo> defaultVirtualPositions = new Dictionary <GenericShip, ShipPositionInfo>(); //Set positions of ships that move later List <GenericShip> shipsSorted = Roster.AllShips.Values .OrderByDescending(n => n.Owner.PlayerNo == Phases.PlayerWithInitiative) .OrderBy(n => n.State.Initiative) .Where(n => n != CurrentShip) .ToList(); foreach (GenericShip ship in shipsSorted) { VirtualBoard.SwitchToVirtualPosition(ship); //Check possible collisions if (!IsActivationBeforeCurrentShip(ship)) { DistanceInfo distInfo = new DistanceInfo(CurrentShip, ship); if (distInfo.Range <= 1) { //Save old prediction and re-check movement defaultVirtualPositions.Add(ship, VirtualBoard.Ships[ship].VirtualPositionInfo); yield return(PredictSimpleManeuver(ship)); VirtualBoard.SetVirtualPositionInfo(ship, CurrentSimpleMovementPrediction.FinalPositionInfo); Selection.ChangeActiveShip(CurrentShip); } } } //Distance float minDistanceToEnenmyShip = float.MaxValue; foreach (GenericShip enemyShip in CurrentShip.Owner.EnemyShips.Values) { DistanceInfo distInfo = new DistanceInfo(CurrentShip, enemyShip); if (distInfo.MinDistance.DistanceReal < minDistanceToEnenmyShip) { minDistanceToEnenmyShip = distInfo.MinDistance.DistanceReal; } } //In arc - improve int enemiesInShotRange = 0; float minDistanceToNearestEnemyInShotRange = 0; foreach (GenericShip enemyShip in CurrentShip.Owner.EnemyShips.Values) { ShotInfo shotInfo = new ShotInfo(CurrentShip, enemyShip, CurrentShip.PrimaryWeapons.First()); if (shotInfo.IsShotAvailable) { enemiesInShotRange++; if (minDistanceToNearestEnemyInShotRange < shotInfo.DistanceReal) { minDistanceToNearestEnemyInShotRange = shotInfo.DistanceReal; } } } NavigationResult result = new NavigationResult() { movement = CurrentMovementPrediction.CurrentMovement, distanceToNearestEnemy = minDistanceToEnenmyShip, distanceToNearestEnemyInShotRange = minDistanceToNearestEnemyInShotRange, enemiesInShotRange = enemiesInShotRange, isBumped = CurrentMovementPrediction.IsBumped, isLandedOnObstacle = CurrentMovementPrediction.IsLandedOnAsteroid, obstaclesHit = CurrentMovementPrediction.AsteroidsHit.Count, isOffTheBoard = CurrentMovementPrediction.IsOffTheBoard, minesHit = CurrentMovementPrediction.MinesHit.Count, isOffTheBoardNextTurn = !NextTurnNavigationResults.Any(n => !n.isOffTheBoard), isHitAsteroidNextTurn = !NextTurnNavigationResults.Any(n => n.obstaclesHit == 0), FinalPositionInfo = CurrentMovementPrediction.FinalPositionInfo }; result.CalculatePriority(); NavigationResults.Add( CurrentMovementPrediction.CurrentMovement.ToString(), result ); //Restore previous virtual positions foreach (var shipInfo in defaultVirtualPositions) { VirtualBoard.SetVirtualPositionInfo(shipInfo.Key, shipInfo.Value); } //Restore positions of ships that move later foreach (GenericShip ship in shipsSorted.Where(n => !IsActivationBeforeCurrentShip(n))) { VirtualBoard.SwitchToRealPosition(ship); } }
private static IEnumerator FindBestManeuver(GenericShip ship) { Selection.ChangeActiveShip(ship); if (DebugManager.DebugAiNavigation) { Console.Write("", LogTypes.AI); Console.Write("Best maneuver calculations for " + ship.ShipId, LogTypes.AI, isBold: true); } int bestPriority = int.MinValue; KeyValuePair <string, NavigationResult> maneuverToCheck = new KeyValuePair <string, NavigationResult>(); do { VirtualBoard.SwitchToRealPosition(ship); bestPriority = VirtualBoard.Ships[ship].NavigationResults.Max(n => n.Value.Priority); maneuverToCheck = VirtualBoard.Ships[ship].NavigationResults.Where(n => n.Value.Priority == bestPriority).First(); if (DebugManager.DebugAiNavigation) { Console.Write("Current best maneuver is " + maneuverToCheck.Key + " with priority " + maneuverToCheck.Value.ToString(), LogTypes.AI); } GenericMovement movement = ShipMovementScript.MovementFromString(maneuverToCheck.Key); ship.SetAssignedManeuver(movement, isSilent: true); movement.Initialize(); movement.IsSimple = true; MovementPrediction prediction = new MovementPrediction(ship, movement); yield return(prediction.CalculateMovementPredicition()); VirtualBoard.SetVirtualPositionInfo(ship, prediction.FinalPositionInfo, prediction.CurrentMovement.ToString()); VirtualBoard.SwitchToVirtualPosition(ship); CurrentNavigationResult = new NavigationResult() { movement = prediction.CurrentMovement, isBumped = prediction.IsBumped, isLandedOnObstacle = prediction.IsLandedOnAsteroid, obstaclesHit = prediction.AsteroidsHit.Count, isOffTheBoard = prediction.IsOffTheBoard, minesHit = prediction.MinesHit.Count, isOffTheBoardNextTurn = false, //!NextTurnNavigationResults.Any(n => !n.isOffTheBoard), isHitAsteroidNextTurn = false, //!NextTurnNavigationResults.Any(n => n.obstaclesHit == 0), FinalPositionInfo = prediction.FinalPositionInfo }; foreach (GenericShip enemyShip in CurrentPlayer.EnemyShips.Values) { VirtualBoard.SwitchToVirtualPosition(enemyShip); } if (!prediction.IsOffTheBoard) { yield return(CheckNextTurnRecursive(ship)); float minDistanceToEnemyShip, minDistanceToNearestEnemyInShotRange, minAngle; int enemiesInShotRange; ProcessHeavyGeometryCalculations(ship, out minDistanceToEnemyShip, out minDistanceToNearestEnemyInShotRange, out minAngle, out enemiesInShotRange); CurrentNavigationResult.distanceToNearestEnemy = minDistanceToEnemyShip; CurrentNavigationResult.distanceToNearestEnemyInShotRange = minDistanceToNearestEnemyInShotRange; CurrentNavigationResult.angleToNearestEnemy = minAngle; CurrentNavigationResult.enemiesInShotRange = enemiesInShotRange; } CurrentNavigationResult.CalculatePriority(); if (DebugManager.DebugAiNavigation) { Console.Write("After reevaluation priority is changed to " + CurrentNavigationResult.ToString(), LogTypes.AI); } VirtualBoard.Ships[ship].NavigationResults[maneuverToCheck.Key] = CurrentNavigationResult; bestPriority = VirtualBoard.Ships[ship].NavigationResults.Max(n => n.Value.Priority); if (DebugManager.DebugAiNavigation) { Console.Write("Highest priority of all maneuvers is " + bestPriority, LogTypes.AI); } VirtualBoard.SwitchToRealPosition(ship); maneuverToCheck = VirtualBoard.Ships[ship].NavigationResults.First(n => n.Key == maneuverToCheck.Key); foreach (GenericShip enemyShip in CurrentPlayer.EnemyShips.Values) { VirtualBoard.SwitchToRealPosition(enemyShip); } } while (maneuverToCheck.Value.Priority != bestPriority); if (DebugManager.DebugAiNavigation) { Console.Write("Maneuver is chosen: " + maneuverToCheck.Key, LogTypes.AI); } VirtualBoard.Ships[ship].SetPlannedManeuverCode(maneuverToCheck.Key, ++OrderOfActivation); ship.ClearAssignedManeuver(); }