예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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();
        }