public void AttackClosestEnemyTankToOwnBase(GameState currGameState, Tank killerTank, Tank targetTank,
                                                    TankActionSet actionSet, bool[] moveChosenByTankNumber)
        {
            MobileState killerTankState = currGameState.GetMobileState(killerTank.Index);

            if (killerTankState.IsActive)
            {
                MobileState enemyTankState = currGameState.GetMobileState(targetTank.Index);
                if (enemyTankState.IsActive)
                {
                    DirectionalMatrix <DistanceCalculation> attackMatrix
                        = currGameState.CalculationCache.GetIncomingAttackMatrixForTankByTankIndex(targetTank.Index);
                    if (attackMatrix != null)
                    {
                        DistanceCalculation attackCalculation = attackMatrix[killerTankState.Dir, killerTankState.Pos];
                        TankAction[]        tankActions
                            = PathCalculator.GetTankActionsOnIncomingShortestPath(attackMatrix, killerTankState, enemyTankState.Pos,
                                                                                  currGameState.CalculationCache.FiringLinesForTanksMatrix, keepMovingCloserOnFiringLastBullet: true);
                        if (tankActions.Length > 0)
                        {
                            actionSet.Actions[killerTank.Number]      = tankActions[0];
                            moveChosenByTankNumber[killerTank.Number] = true;
                        }
                    }
                }
            }
        }
Beispiel #2
0
        public static void Main()
        {
            // The first three problems are in this project

            Point3D point = new Point3D(5.4m, 6.6m, 3.1m);

            Console.WriteLine(point);

            Point3D anotherPoint = new Point3D(1m, 5.78m, -2.75m);

            Console.WriteLine(anotherPoint);

            Console.WriteLine("{0:F3}", DistanceCalculation.CalculateDistance(point, anotherPoint));

            Point3D basePoint = Point3D.StartingPoint;

            Console.WriteLine(basePoint);

            Path3D listOfPoints = new Path3D();

            listOfPoints.AddPoint(point);
            listOfPoints.AddPoint(basePoint);
            listOfPoints.AddPoint(anotherPoint);

            Storage.SavePath(listOfPoints);
        }
Beispiel #3
0
        public TankAction[] GetActionsToReachLineOfFireDefencePointByIncomingAttackDirection(
            int playerIndex, int tankNumber, Direction finalIncomingDirectionOfAttack)
        {
            Player      player    = Game.Current.Players[playerIndex];
            Tank        tank      = player.Tanks[tankNumber];
            MobileState tankState = GetTankState(playerIndex, tankNumber);

            if (tankState.IsActive)  // TODO: Check if locked in a firefight also
            {
                DirectionalMatrix <DistanceCalculation> distanceMatrix
                    = GameState.CalculationCache.GetDistanceMatrixFromTankByTankIndex(tank.Index);
                Direction defenceDir = finalIncomingDirectionOfAttack.GetOpposite();
                if (defenceDir == Direction.NONE)
                {
                    defenceDir = Direction.RIGHT;
                }
                int startPosOffsetFromBase = Constants.TANK_OUTER_EDGE_OFFSET;
                int endPosOffsetFromBase   = startPosOffsetFromBase + MAX_POINTS_TO_TRY_FOR_DEFENCE_POS;
                for (int offsetSize = startPosOffsetFromBase; offsetSize < endPosOffsetFromBase; offsetSize++)
                {
                    Point defencePos = player.Base.Pos + defenceDir.GetOffset(offsetSize);
                    DistanceCalculation tankDefenceCalc = distanceMatrix[defenceDir, defencePos];
                    if (tankDefenceCalc.CodedDistance == 0)
                    {
                        // This defence point can't be reached, try further away
                        continue;
                    }
                    return(PathCalculator.GetTankActionsOnOutgoingShortestPath(distanceMatrix, defenceDir, defencePos));
                }
            }
            return(new TankAction[0]);
        }
Beispiel #4
0
        public int GetDistanceFromTankToPointUsingDistanceMatrix(
            DirectionalMatrix <DistanceCalculation> distanceMatrix,
            Direction directionAtDestination, Point destination)
        {
            DistanceCalculation distanceCalc = distanceMatrix[directionAtDestination, destination];

            return(distanceCalc.Distance);
        }
    //TO FIND ALL ROUTER CONNECTION AND ROUTER CINNECTED LINK
    public void Connectivity(string SR, string DR, ArrayList arryConnection)
    {
        DistanceCalculation.arryConnection.Clear();
        DistanceCalculation.arryConnection = arryConnection;
        arryCon     = arryConnection; //LINK BETWEEN SOURCE AND DESTINATION
        destination = DR;             //DESSTINATION
        source      = SR;             //SOURCE

        for (int i = 0; i < arryConnection.Count; i++)
        {
            rec  = arryConnection[i].ToString();
            splt = rec.Split('-');

            if (source.Equals(splt[0]))
            {
                middle = splt[1];
            }
            else if (source.Equals(splt[1]))
            {
                middle = splt[0];
            }
            else
            {
                continue;
            }

            if (middle.Equals(destination))
            {
                arryNeighR1 = new ArrayList();
                arryNeighR1.Add(source);
                arryNeighR1.Add(middle);
                //ADD NEIGHBOUR NODE FOR EACH ROUTER
                DistanceCalculation.PossiblePath.Add(arryNeighR1);
                for (int k = 0; k < DistanceCalculation.PossiblePathDistance.Count; k++)
                {
                    strngB = DistanceCalculation.PossiblePathDistance[k].ToString();
                    splt1  = strngB.Split('-');

                    if (((splt1[0] == source) && splt1[1] == destination) || ((splt1[1] == source) && (splt1[0] == destination)))
                    {
                        km = Convert.ToDouble(splt1[2]);
                        break;
                    }
                }
                // ADD ROUTER DISTANCE
                DistanceCalculation.distance.Add(km);
            }
            else
            {
                arryNeighR1 = new ArrayList();
                arryNeighR1.Add(source);
                arryNeighR1.Add(middle);
                DistanceCalculation dc = new DistanceCalculation();
                //TO CALL GETPATH METHOD FOR CHECK ROUTER LINK
                dc.getpath(source, destination, arryNeighR1, middle);
            }
        }
    }
Beispiel #6
0
        public int GetDistanceFromTankToPoint(int playerIndex, int tankNumber,
                                              Direction directionAtDestination, Point destination)
        {
            Tank tank = Game.Current.Players[playerIndex].Tanks[tankNumber];
            DirectionalMatrix <DistanceCalculation> distanceMatrix
                = GameState.CalculationCache.GetDistanceMatrixFromTankByTankIndex(tank.Index);
            DistanceCalculation distanceCalc = distanceMatrix[directionAtDestination, destination];

            return(distanceCalc.Distance);
        }
Beispiel #7
0
        public int GetAttackDistanceFromHypotheticalTankStateToTank(
            MobileState attackTankState, int targetPlayerIndex, int targetTankNumber,
            EdgeOffset[] edgeOffsets)
        {
            Tank targetTank = Game.Current.Players[targetPlayerIndex].Tanks[targetTankNumber];
            DirectionalMatrix <DistanceCalculation> distanceMatrix
                = GameState.CalculationCache.GetIncomingAttackMatrixForTankByTankIndex(targetTank.Index);
            DistanceCalculation distanceCalc = distanceMatrix[attackTankState];

            return(distanceCalc.Distance);
        }
Beispiel #8
0
        public int GetDistanceFromTankToTargetTank(
            int attackPlayerIndex, int attackTankNumber, int targetPlayerIndex, int targetTankNumber)
        {
            Tank attackTank = Game.Current.Players[attackPlayerIndex].Tanks[attackTankNumber];
            DirectionalMatrix <DistanceCalculation> distanceMatrix
                = GameState.CalculationCache.GetDistanceMatrixFromTankByTankIndex(attackTank.Index);

            Tank                defenceTank     = Game.Current.Players[targetPlayerIndex].Tanks[targetTankNumber];
            MobileState         targetTankState = GetTankState(targetPlayerIndex, targetTankNumber);
            DistanceCalculation distanceCalc    = distanceMatrix[targetTankState];

            return(distanceCalc.Distance);
        }
Beispiel #9
0
        protected void btnSubmitAddress_Click(object sender, EventArgs e)
        {
            string  inputAddress = txtAddress.Text;
            Address inputLatLong = GeoCodingApi.GetGeoCod(inputAddress);

            if (!string.IsNullOrEmpty(inputAddress))
            {
                foreach (Address address in addressStore)
                {
                    if (address != null)
                    {
                        address.Distance = DistanceCalculation.Distance(address.Latitude, address.Longitude, inputLatLong.Latitude, inputLatLong.Longitude, 'K');
                        //address.Distance = DistanceMatrixApi.GetDistance(address, inputLatLong); Get distance from Google Distance Matrix API
                    }
                }
                var closestAddress = addressStore.OrderBy(x => x.Distance).Take(5);
                repAddress.DataSource = closestAddress;
                repAddress.DataBind();
            }
        }
Beispiel #10
0
        public Umap(
            DistanceCalculation distance = null,
            IProvideRandomValues random  = null,
            int dimensions                    = 2,
            int numberOfNeighbors             = 15,
            int?customNumberOfEpochs          = null,
            ProgressReporter progressReporter = null)
        {
            if ((customNumberOfEpochs != null) && (customNumberOfEpochs <= 0))
            {
                throw new ArgumentOutOfRangeException(nameof(customNumberOfEpochs), "if non-null then must be a positive value");
            }

            _distanceFn        = distance ?? DistanceFunctions.Cosine;
            _random            = random ?? DefaultRandomGenerator.Instance;
            _nNeighbors        = numberOfNeighbors;
            _optimizationState = new OptimizationState {
                Dim = dimensions
            };
            _customNumberOfEpochs = customNumberOfEpochs;
            _progressReporter     = progressReporter;
        }
Beispiel #11
0
        /// <summary>
        ///   Calculates the distance (in km) between two specified <see cref="LatLng">latlong points</see>.
        ///   By default this uses the Law of Cosines formula (http://en.wikipedia.org/wiki/Law_of_cosines).
        /// </summary>
        /// <param name="pointOne">The first point to use in the calculation.</param>
        /// <param name="pointTwo">The second point to use in the calculation.</param>
        /// <param name="calculation">
        ///   <para>The calculation to use.</para>
        ///   <para>By default this uses the Law of Cosines formula.</para>
        /// </param>
        /// <returns>
        ///   The distance (in km) between the two points specified.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        ///   The specified <paramref name="calculation"/> is outside the allowable <see cref="DistanceCalculation">values</see>.
        /// </exception>
        public static double Distance(
            LatLng pointOne,
            LatLng pointTwo,
            DistanceCalculation calculation = DistanceCalculation.LawOfCosines)
        {
            switch (calculation)
            {
            case DistanceCalculation.Haversine:
                double pointOneLatitude  = pointOne.Latitude.ToRadians();
                double pointOneLongitude = pointOne.Longitude.ToRadians();
                double pointTwoLatitude  = pointTwo.Latitude.ToRadians();
                double pointTwoLongitude = pointTwo.Longitude.ToRadians();

                double longitude = pointTwoLongitude - pointOneLongitude;
                double latitude  = pointTwoLatitude - pointOneLatitude;

                double intermediateResult = Math.Pow(Math.Sin(latitude / 2.0), 2.0) +
                                            Math.Cos(pointOneLatitude) * Math.Cos(pointTwoLatitude) *
                                            Math.Pow(Math.Sin(longitude / 2.0), 2.0);

                // Intermediate result c (great circle distance in Radians).

                double c = 2.0 * Math.Atan2(Math.Sqrt(intermediateResult), Math.Sqrt(1.0 - intermediateResult));

                return(EarthsRadiusInKilometers * c);

            case DistanceCalculation.LawOfCosines:
                return((Math.Acos(
                            Math.Sin(pointOne.Latitude) * Math.Sin(pointTwo.Latitude) +
                            Math.Cos(pointOne.Latitude) * Math.Cos(pointTwo.Latitude) *
                            Math.Cos(pointTwo.Longitude - pointOne.Longitude)
                            ) * EarthsRadiusInKilometers).ToRadians());

            default:
                throw new ArgumentOutOfRangeException("calculation");
            }
        }
        private void ChooseShortestPathBotMoves()
        {
            GameState     currGameState = Game.Current.CurrentTurn.GameState;
            TankActionSet actionSet     = new TankActionSet(YourPlayerIndex, currGameState.Tick);

            bool[] moveChosen = new bool[Constants.TANKS_PER_PLAYER];

            RespondToBullets(currGameState, actionSet, moveChosen);

            Tuple <int, int, TankAction>[] tankNumberDistanceAndActionArray = new Tuple <int, int, TankAction> [Constants.TANKS_PER_PLAYER];

            // The closest bot can attack the base:
            for (int tankNumber = 0; tankNumber < Constants.TANKS_PER_PLAYER; tankNumber++)
            {
                Tank        tank      = You.Tanks[tankNumber];
                MobileState tankState = currGameState.GetMobileState(tank.Index);
                if (!tankState.IsActive)
                {
                    tankNumberDistanceAndActionArray[tankNumber]
                        = new Tuple <int, int, TankAction>(tankNumber, Constants.UNREACHABLE_DISTANCE, TankAction.NONE);
                    continue;
                }

                Base enemyBase = Opponent.Base;
                DirectionalMatrix <DistanceCalculation> distancesToEnemyBase
                    = currGameState.CalculationCache.GetIncomingDistanceMatrixForBase(Opponent.Index);
                DistanceCalculation distanceCalc = distancesToEnemyBase[tankState.Dir, tankState.Pos];

                FiringLineMatrix firingLineMatrix = currGameState.CalculationCache.FiringLinesForPointsMatrix;
                TankAction[]     tankActions      = PathCalculator.GetTankActionsOnIncomingShortestPath(distancesToEnemyBase,
                                                                                                        tankState.Dir, tankState.Pos.X, tankState.Pos.Y, enemyBase.Pos.X, enemyBase.Pos.Y,
                                                                                                        firingLineMatrix, keepMovingCloserOnFiringLastBullet: false);

                if (tankActions.Length == 0)
                {
                    tankNumberDistanceAndActionArray[tankNumber]
                        = new Tuple <int, int, TankAction>(tankNumber, Constants.UNREACHABLE_DISTANCE, TankAction.NONE);
                }
                else
                {
                    tankNumberDistanceAndActionArray[tankNumber]
                        = new Tuple <int, int, TankAction>(tankNumber, distanceCalc.Distance, tankActions[0]);
                }
            }

            int chosenTank;

            if (tankNumberDistanceAndActionArray[1].Item2 < tankNumberDistanceAndActionArray[0].Item2)
            {
                chosenTank = 1;
            }
            else
            {
                chosenTank = 0;
            }
            actionSet.Actions[chosenTank] = tankNumberDistanceAndActionArray[chosenTank].Item3;

            // The other bot can attack the closest enemy tank:
            Tank        killerTank      = You.Tanks[1 - chosenTank];
            MobileState killerTankState = currGameState.GetMobileState(killerTank.Index);

            if (killerTankState.IsActive)
            {
                Tank        enemyTank1      = Opponent.Tanks[0];
                MobileState enemyTankState1 = currGameState.GetMobileState(enemyTank1.Index);

                int        killerDistance1 = Constants.UNREACHABLE_DISTANCE;
                TankAction killerAction1   = TankAction.NONE;

                if (enemyTankState1.IsActive)
                {
                    DirectionalMatrix <DistanceCalculation> attackMatrix1
                        = currGameState.CalculationCache.GetIncomingAttackMatrixForTankByTankIndex(enemyTank1.Index);
                    if (attackMatrix1 != null)
                    {
                        DistanceCalculation attackCalculation1 = attackMatrix1[killerTankState.Dir, killerTankState.Pos];
                        killerDistance1 = attackCalculation1.Distance;
                        TankAction[] tankActions
                            = PathCalculator.GetTankActionsOnIncomingShortestPath(attackMatrix1, killerTankState, enemyTankState1.Pos,
                                                                                  currGameState.CalculationCache.FiringLinesForTanksMatrix, keepMovingCloserOnFiringLastBullet: true);
                        if (tankActions.Length > 0)
                        {
                            killerAction1 = tankActions[0];
                        }
                    }
                }

                Tank        enemyTank2      = Opponent.Tanks[1];
                MobileState enemyTankState2 = currGameState.GetMobileState(enemyTank2.Index);

                int        killerDistance2 = Constants.UNREACHABLE_DISTANCE;
                TankAction killerAction2   = TankAction.NONE;

                if (enemyTankState2.IsActive)
                {
                    DirectionalMatrix <DistanceCalculation> attackMatrix2
                        = currGameState.CalculationCache.GetIncomingAttackMatrixForTankByTankIndex(enemyTank2.Index);
                    if (attackMatrix2 != null)
                    {
                        DistanceCalculation attackCalculation2 = attackMatrix2[killerTankState.Dir, killerTankState.Pos];
                        killerDistance2 = attackCalculation2.Distance;
                        TankAction[] tankActions
                            = PathCalculator.GetTankActionsOnIncomingShortestPath(attackMatrix2, killerTankState, enemyTankState2.Pos,
                                                                                  currGameState.CalculationCache.FiringLinesForTanksMatrix, keepMovingCloserOnFiringLastBullet: true);
                        if (tankActions.Length > 0)
                        {
                            killerAction2 = tankActions[0];
                        }
                    }
                }

                actionSet.Actions[1 - chosenTank]
                    = (killerDistance1 <= killerDistance2)
                    ? killerAction1
                    : killerAction2;
            }

            Coordinator.SetBestMoveSoFar(actionSet);
        }
Beispiel #13
0
 /// <summary>
 ///   Calculates the distance (in km) between the current point and the <see cref="LatLng">point</see> specified.
 ///   By default this uses the Law of Cosines formula (http://en.wikipedia.org/wiki/Law_of_cosines).
 /// </summary>
 /// <param name="otherPoint">The point we want to calculate the distance to.</param>
 /// <param name="calculation">
 ///   <para>The distance calculation to use.</para>
 ///   <para>By default this uses the Law of Cosines formula.</para>
 /// </param>
 /// <returns>
 ///   The distance (in km) between the current point and the <paramref name="otherPoint"/> specified.
 /// </returns>
 /// <exception cref="ArgumentOutOfRangeException">
 ///   The specified <paramref name="calculation"/> is outside the allowable <see cref="DistanceCalculation">values</see>.
 /// </exception>
 public double DistanceTo(LatLng otherPoint, DistanceCalculation calculation = DistanceCalculation.LawOfCosines)
 {
     return Distance(this, otherPoint, calculation);
 }
Beispiel #14
0
        /// <summary>
        ///   Calculates the distance (in km) between two specified <see cref="LatLng">latlong points</see>.
        ///   By default this uses the Law of Cosines formula (http://en.wikipedia.org/wiki/Law_of_cosines).
        /// </summary>
        /// <param name="pointOne">The first point to use in the calculation.</param>
        /// <param name="pointTwo">The second point to use in the calculation.</param>
        /// <param name="calculation">
        ///   <para>The calculation to use.</para>
        ///   <para>By default this uses the Law of Cosines formula.</para>
        /// </param>
        /// <returns>
        ///   The distance (in km) between the two points specified.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        ///   The specified <paramref name="calculation"/> is outside the allowable <see cref="DistanceCalculation">values</see>.
        /// </exception>
        public static double Distance(
            LatLng pointOne,
            LatLng pointTwo,
            DistanceCalculation calculation = DistanceCalculation.LawOfCosines)
        {
            switch (calculation)
            {
                case DistanceCalculation.Haversine:
                    double pointOneLatitude = pointOne.Latitude.ToRadians();
                    double pointOneLongitude = pointOne.Longitude.ToRadians();
                    double pointTwoLatitude = pointTwo.Latitude.ToRadians();
                    double pointTwoLongitude = pointTwo.Longitude.ToRadians();

                    double longitude = pointTwoLongitude - pointOneLongitude;
                    double latitude = pointTwoLatitude - pointOneLatitude;

                    double intermediateResult = Math.Pow(Math.Sin(latitude / 2.0), 2.0) +
                                                Math.Cos(pointOneLatitude) * Math.Cos(pointTwoLatitude) *
                                                Math.Pow(Math.Sin(longitude / 2.0), 2.0);

                    // Intermediate result c (great circle distance in Radians).

                    double c = 2.0 * Math.Atan2(Math.Sqrt(intermediateResult), Math.Sqrt(1.0 - intermediateResult));

                    return EarthsRadiusInKilometers * c;
                case DistanceCalculation.LawOfCosines:
                    return (Math.Acos(
                        Math.Sin(pointOne.Latitude) * Math.Sin(pointTwo.Latitude) +
                        Math.Cos(pointOne.Latitude) * Math.Cos(pointTwo.Latitude) *
                        Math.Cos(pointTwo.Longitude - pointOne.Longitude)
                        ) * EarthsRadiusInKilometers).ToRadians();
                default:
                    throw new ArgumentOutOfRangeException("calculation");
            }
        }
Beispiel #15
0
 /// <summary>
 ///   Calculates the distance (in km) between the current point and the <see cref="LatLng">point</see> specified.
 ///   By default this uses the Law of Cosines formula (http://en.wikipedia.org/wiki/Law_of_cosines).
 /// </summary>
 /// <param name="otherPoint">The point we want to calculate the distance to.</param>
 /// <param name="calculation">
 ///   <para>The distance calculation to use.</para>
 ///   <para>By default this uses the Law of Cosines formula.</para>
 /// </param>
 /// <returns>
 ///   The distance (in km) between the current point and the <paramref name="otherPoint"/> specified.
 /// </returns>
 /// <exception cref="ArgumentOutOfRangeException">
 ///   The specified <paramref name="calculation"/> is outside the allowable <see cref="DistanceCalculation">values</see>.
 /// </exception>
 public double DistanceTo(LatLng otherPoint, DistanceCalculation calculation = DistanceCalculation.LawOfCosines)
 {
     return(Distance(this, otherPoint, calculation));
 }
Beispiel #16
0
        /// <summary>
        /// Create a version of nearest neighbor descent.
        /// </summary>
        public static NNDescentFn MakeNNDescent(DistanceCalculation distanceFn, IProvideRandomValues random)
        {
            return((data, leafArray, nNeighbors, nIters, maxCandidates, delta, rho, rpTreeInit, startingIteration) =>
            {
                var nVertices = data.Length;
                var currentGraph = MakeHeap(data.Length, nNeighbors);
                for (var i = 0; i < data.Length; i++)
                {
                    var indices = Utils.RejectionSample(nNeighbors, data.Length, random);
                    for (var j = 0; j < indices.Length; j++)
                    {
                        var d = distanceFn(data[i], data[indices[j]]);
                        HeapPush(currentGraph, i, d, indices[j], 1);
                        HeapPush(currentGraph, indices[j], d, i, 1);
                    }
                }
                if (rpTreeInit)
                {
                    for (var n = 0; n < leafArray.Length; n++)
                    {
                        for (var i = 0; i < leafArray[n].Length; i++)
                        {
                            if (leafArray[n][i] < 0)
                            {
                                break;
                            }

                            for (var j = i + 1; j < leafArray[n].Length; j++)
                            {
                                if (leafArray[n][j] < 0)
                                {
                                    break;
                                }

                                var d = distanceFn(data[leafArray[n][i]], data[leafArray[n][j]]);
                                HeapPush(currentGraph, leafArray[n][i], d, leafArray[n][j], 1);
                                HeapPush(currentGraph, leafArray[n][j], d, leafArray[n][i], 1);
                            }
                        }
                    }
                }
                for (var n = 0; n < nIters; n++)
                {
                    startingIteration?.Invoke(n, nIters);
                    var candidateNeighbors = BuildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random);
                    var c = 0;
                    for (var i = 0; i < nVertices; i++)
                    {
                        for (var j = 0; j < maxCandidates; j++)
                        {
                            var p = (int)Math.Floor(candidateNeighbors[0][i][j]);
                            if ((p < 0) || (random.NextFloat() < rho))
                            {
                                continue;
                            }

                            for (var k = 0; k < maxCandidates; k++)
                            {
                                var q = (int)Math.Floor(candidateNeighbors[0][i][k]);
                                var cj = candidateNeighbors[2][i][j];
                                var ck = candidateNeighbors[2][i][k];
                                if (q < 0 || ((cj == 0) && (ck == 0)))
                                {
                                    continue;
                                }

                                var d = distanceFn(data[p], data[q]);
                                c += HeapPush(currentGraph, p, d, q, 1);
                                c += HeapPush(currentGraph, q, d, p, 1);
                            }
                        }
                    }
                    if (c <= delta * nNeighbors * data.Length)
                    {
                        break;
                    }
                }
                return DeHeapSort(currentGraph);
            });
        }
        private static void CalculateBulletThreats(BulletCalculation bulletCalc, GameState gameState, Player you)
        {
            TurnCalculationCache turnCalcCache = Game.Current.Turns[gameState.Tick].CalculationCache;

            Tank[] tanks;
            if (you != null)
            {
                tanks = you.Tanks;
            }
            else
            {
                tanks = Game.Current.Tanks;
            }
            foreach (Tank tank in tanks)
            {
                MobileState tankState = gameState.GetMobileState(tank.Index);
                foreach (BulletPathCalculation bulletPathCalc in bulletCalc.BulletPaths)
                {
                    List <BulletThreat> bulletThreats = new List <BulletThreat>();
                    foreach (BulletPathPoint bulletPathPoint in bulletPathCalc.BulletPathPoints)
                    {
                        if (bulletPathPoint.DangerArea.ContainsPoint(tankState.Pos))
                        {
                            BulletThreat bulletThreat = new BulletThreat(bulletPathCalc)
                            {
                                FiringTank     = bulletPathCalc.Bullet.Tank,
                                TankThreatened = tank
                            };
                            bulletThreats.Add(bulletThreat);

                            // Take the bullet on:
                            FiringLineMatrix firingLineMatrix = gameState.CalculationCache.FiringLinesForPointsMatrix;
                            AttackTargetDistanceCalculator attackCalculator = new AttackTargetDistanceCalculator(
                                ElementType.BULLET, firingLineMatrix, gameState.CalculationCache, turnCalcCache);
                            attackCalculator.MovementDirections = new Direction[]
                            {
                                bulletPathCalc.BulletState.Dir.GetOpposite()
                            };
                            Cell bulletCell = turnCalcCache.CellMatrix[bulletPathCalc.BulletState.Pos];
                            DirectionalMatrix <DistanceCalculation> distanceCalcs
                                = attackCalculator.CalculateMatrixOfShortestDistancesToTargetCell(bulletCell);
                            DistanceCalculation distanceCalc = distanceCalcs[tankState];
                            if (distanceCalc.Distance <= bulletPathPoint.TicksToEscape)
                            {
                                Node[] nodes = PathCalculator.GetIncomingNodesOnShortestPath(
                                    distanceCalcs, tankState.Dir, tankState.Pos.X, tankState.Pos.Y,
                                    bulletPathCalc.BulletState.Pos.X, bulletPathCalc.BulletState.Pos.Y,
                                    firingLineMatrix, keepMovingCloserOnFiringLastBullet: true);
                                bulletThreat.NodePathToTakeOnBullet = nodes;
                                TankAction[] tankActions
                                    = PathCalculator.GetTankActionsOnIncomingShortestPath(distanceCalcs,
                                                                                          tankState.Dir, tankState.Pos.X, tankState.Pos.Y,
                                                                                          bulletPathCalc.BulletState.Pos.X, bulletPathCalc.BulletState.Pos.Y,
                                                                                          firingLineMatrix, keepMovingCloserOnFiringLastBullet: true);
                                bulletThreat.TankActionsToTakeOnBullet = tankActions;
                            }

                            // Move off his path in one direction:
                            Point tankOffset           = tankState.Pos - bulletPathCalc.BulletState.Pos;
                            Point bulletMovementOffset = bulletPathCalc.BulletState.Dir.GetOffset();

                            Point     newTankPoint1;
                            Point     newTankPoint2;
                            Direction newTankDir1;
                            Direction newTankDir2;

                            if (bulletPathCalc.BulletState.Dir.ToAxis() == Axis.Horizontal)
                            {
                                newTankPoint1 = new Point(
                                    (short)tankState.Pos.X,
                                    (short)(bulletPathCalc.BulletState.Pos.Y - Constants.TANK_OUTER_EDGE_OFFSET));
                                newTankDir1   = Direction.UP;
                                newTankPoint2 = new Point(
                                    (short)tankState.Pos.X,
                                    (short)(bulletPathCalc.BulletState.Pos.Y + Constants.TANK_OUTER_EDGE_OFFSET));
                                newTankDir2 = Direction.DOWN;
                            }
                            else
                            {
                                newTankPoint1 = new Point(
                                    (short)(bulletPathCalc.BulletState.Pos.X - Constants.TANK_OUTER_EDGE_OFFSET),
                                    (short)tankState.Pos.Y);
                                newTankDir1   = Direction.LEFT;
                                newTankPoint2 = new Point(
                                    (short)(bulletPathCalc.BulletState.Pos.X + Constants.TANK_OUTER_EDGE_OFFSET),
                                    (short)tankState.Pos.Y);
                                newTankDir2 = Direction.RIGHT;
                            }

                            DirectionalMatrix <DistanceCalculation> tankDistanceCalcs
                                = gameState.CalculationCache.GetDistanceMatrixFromTankByTankIndex(tank.Index);

                            distanceCalc = tankDistanceCalcs[newTankDir1, newTankPoint1.X, newTankPoint1.Y];
                            if (distanceCalc.Distance <= bulletPathPoint.TicksToEscape)
                            {
                                Node[] shortestPathsIn1Direction
                                    = PathCalculator.GetOutgoingNodesOnShortestPath(tankDistanceCalcs,
                                                                                    newTankDir1, newTankPoint1.X, newTankPoint1.Y);
                                bulletThreat.LateralMoveInOneDirection = shortestPathsIn1Direction;
                                TankAction[] tankActionsIn1Direction
                                    = PathCalculator.GetTankActionsOnOutgoingShortestPath(tankDistanceCalcs,
                                                                                          newTankDir1, newTankPoint1.X, newTankPoint1.Y);
                                bulletThreat.TankActionsForLateralMoveInOneDirection = tankActionsIn1Direction;
                            }

                            distanceCalc = tankDistanceCalcs[newTankDir2, newTankPoint2.X, newTankPoint2.Y];
                            if (distanceCalc.Distance <= bulletPathPoint.TicksToEscape)
                            {
                                Node[] shortestPathsInOtherDirection = PathCalculator.GetOutgoingNodesOnShortestPath(tankDistanceCalcs,
                                                                                                                     newTankDir2, newTankPoint2.X, newTankPoint2.Y);
                                bulletThreat.LateralMoveInOtherDirection = shortestPathsInOtherDirection;
                                TankAction[] tankActionsInOtherDirection
                                    = PathCalculator.GetTankActionsOnOutgoingShortestPath(tankDistanceCalcs,
                                                                                          newTankDir2, newTankPoint2.X, newTankPoint2.Y);
                                bulletThreat.TankActionsForLateralMoveInOtherDirection = tankActionsInOtherDirection;
                            }
                        }
                    }
                    bulletPathCalc.BulletThreats = bulletThreats.ToArray();
                }
            }
        }
        public double EvaluateSmallestAttackDistanceToEnemyBase()
        {
            int[]       minDistanceToAttackEnemyBaseByPlayerIndex = new int[Constants.PLAYERS_PER_GAME];
            int[]       minDistanceToDefendOwnBaseByPlayerIndex   = new int[Constants.PLAYERS_PER_GAME];
            bool[]      isUnmarked = new bool[Constants.PLAYERS_PER_GAME];
            Direction[] attackDirOnEnemyBaseByPlayerIndex = new Direction[Constants.PLAYERS_PER_GAME];
            double[]    score = new double[Constants.PLAYERS_PER_GAME];

            foreach (Player player in Game.Current.Players)
            {
                int minDistanceToEnemyBase = Constants.UNREACHABLE_DISTANCE;

                foreach (Tank tank in player.Tanks)
                {
                    MobileState tankState = GameState.GetMobileState(tank.Index);
                    if (tankState.IsActive)  // TODO: Check if locked in a firefight also
                    {
                        DistanceCalculation baseAttackCalc
                            = GameState.CalculationCache.GetIncomingDistanceMatrixForBase(1 - player.Index)[tankState];

                        int distanceToEnemyBase = baseAttackCalc.Distance;
                        if (distanceToEnemyBase < minDistanceToEnemyBase)
                        {
                            minDistanceToEnemyBase = distanceToEnemyBase;
                            attackDirOnEnemyBaseByPlayerIndex[player.Index] = baseAttackCalc.AdjacentNode.Dir;
                        }
                    }
                }
                minDistanceToAttackEnemyBaseByPlayerIndex[player.Index] = minDistanceToEnemyBase;
            }

            foreach (Player player in Game.Current.Players)
            {
                int minDistanceToDefendOwnBase = Constants.UNREACHABLE_DISTANCE;

                foreach (Tank tank in player.Tanks)
                {
                    MobileState tankState = GameState.GetMobileState(tank.Index);
                    if (tankState.IsActive)  // TODO: Check if locked in a firefight also
                    {
                        DirectionalMatrix <DistanceCalculation> distanceMatrix
                            = GameState.CalculationCache.GetDistanceMatrixFromTankByTankIndex(tank.Index);
                        Direction           attackDir       = attackDirOnEnemyBaseByPlayerIndex[1 - player.Index];
                        Direction           defenceDir      = attackDir.GetOpposite();
                        DistanceCalculation tankDefenceCalc = distanceMatrix[
                            defenceDir, player.Base.Pos + (Constants.SEGMENT_SIZE + 1) * defenceDir.GetOffset()];

                        int distance = tankDefenceCalc.Distance;
                        if (distance < minDistanceToDefendOwnBase)
                        {
                            minDistanceToDefendOwnBase = distance;
                        }
                    }
                }
                minDistanceToDefendOwnBaseByPlayerIndex[player.Index] = minDistanceToDefendOwnBase;
                if (minDistanceToAttackEnemyBaseByPlayerIndex[1 - player.Index] < minDistanceToDefendOwnBase)
                {
                    isUnmarked[1 - player.Index] = true;
                }
            }

            foreach (Player player in Game.Current.Players)
            {
                int minAttackDistance = minDistanceToAttackEnemyBaseByPlayerIndex[player.Index];
                int playerScore       = 0;
                if (!(Game.Current.CurrentTurn.Tick + minAttackDistance > Game.Current.FinalTickInGame))
                {
                    if (isUnmarked[Player.Index])
                    {
                        playerScore = 100000 * (250 - minAttackDistance);
                    }
                    else
                    {
                        playerScore = 100 * (minDistanceToDefendOwnBaseByPlayerIndex[1 - player.Index] - minAttackDistance);
                    }
                }
                score[player.Index] = playerScore;
            }

            return(score[Player.Index] - score[1 - Player.Index]);
        }
Beispiel #19
0
        static async Task Main(string[] args)
        {
            /*
             * Check if arguments are provided and try to parse them as the longitude and latitude to look for.
             * First argument should be Longitude. (North is positive, South is negative.)
             * Second argument should be Latitude. (East is positive, West is negative.)
             */
            if (args.Length > 0)
            {
                bool validLongitude = decimal.TryParse(args[0], out decimal longitude);
                bool validLatitude  = decimal.TryParse(args[1], out decimal latitude);
                // Try to parse and return an error message if this fails.
                if (!validLongitude || !validLatitude)
                {
                    Console.WriteLine("Failed to parse the command-line arguments.\n" +
                                      "Please make sure that the arguments are valid.\n" +
                                      "First argument should be Longitude. (North is positive, South is negative.)\n" +
                                      "Second argument should be Latitude. (East is positive, West is negative.)");
                }

                Console.WriteLine($"Looking for States near the {longitude} - {latitude}");
                var apiFetcher          = new ApiFetcher();
                var distanceCalculation = new DistanceCalculation();

                StatesResponse response = await apiFetcher.GetStatesNearCoordinates(longitude, latitude);

                var   shortestDistance = double.MaxValue;
                State foundState       = null;
                // Calculate the distances for every state and return the shortest.
                foreach (var state in response.ConvertedStates)
                {
                    var distance = distanceCalculation.CalculateGeodesicDistance(longitude, latitude, state.Longitude, state.Latitude);
                    // Overwrite the new shortest before checking other States.
                    if (distance < shortestDistance)
                    {
                        shortestDistance = distance;
                        foundState       = state;
                    }
                }

                Console.WriteLine($"Closest State to the given coordinates ({longitude}, {latitude}):\n" +
                                  $"Geodesic distance: {shortestDistance}\n" +
                                  $"Callsign: {foundState.CallSign}\n" +
                                  $"Longitude: {foundState.Longitude}\n" +
                                  $"Latitude: {foundState.Latitude}\n" +
                                  $"Geometric Altitude: {foundState.GeoAltitude}\n" +
                                  $"Country of Origin: {foundState.OriginCountry}\n" +
                                  $"ICAO24 ID: {foundState.ICAO24}");
            }
            // Otherwise test it out with the two given challenge inputs.
            else
            {
                var apiFetcher          = new ApiFetcher();
                var distanceCalculation = new DistanceCalculation();

                /*
                 * Eiffel Tower
                 * Longitude: 48.8584 N
                 * Latitude: 2.2945 E
                 */
                Console.WriteLine("Looking for States near the Eiffel Tower...");
                var            longitude = 48.8584M;
                var            latitude  = 2.2945M;
                StatesResponse response  = await apiFetcher.GetStatesNearCoordinates(longitude, latitude);

                var   shortestDistance = double.MaxValue;
                State foundState       = null;
                // Calculate the distances for every state and return the shortest.
                foreach (var state in response.ConvertedStates)
                {
                    var distance = distanceCalculation.CalculateGeodesicDistance(longitude, latitude, state.Longitude, state.Latitude);
                    // Overwrite the new shortest before checking other States.
                    if (distance < shortestDistance)
                    {
                        shortestDistance = distance;
                        foundState       = state;
                    }
                }

                Console.WriteLine($"Closest State to the Eiffel Tower:\n" +
                                  $"Geodesic distance: {shortestDistance}\n" +
                                  $"Callsign: {foundState.CallSign}\n" +
                                  $"Longitude: {foundState.Longitude}\n" +
                                  $"Latitude: {foundState.Latitude}\n" +
                                  $"Geometric Altitude: {foundState.GeoAltitude}\n" +
                                  $"Country of Origin: {foundState.OriginCountry}\n" +
                                  $"ICAO24 ID: {foundState.ICAO24}");

                /*
                 * John F. Kennedy Airport
                 * Longitude: 40.6413 N
                 * Latitude: 73.7781 W
                 */
                Console.WriteLine("Looking for States near the John F. Kennedy Airport...");
                longitude = 40.6413M;
                latitude  = -73.7781M;
                response  = await apiFetcher.GetStatesNearCoordinates(longitude, latitude);

                shortestDistance = double.MaxValue;
                foundState       = null;
                // Calculate the distances for every state and return the shortest.
                foreach (var state in response.ConvertedStates)
                {
                    var distance = distanceCalculation.CalculateGeodesicDistance(longitude, latitude, state.Longitude, state.Latitude);
                    // Overwrite the new shortest before checking other States.
                    if (distance < shortestDistance)
                    {
                        shortestDistance = distance;
                        foundState       = state;
                    }
                }

                Console.WriteLine($"Closest State to the John F. Kennedy Airport:\n" +
                                  $"Geodesic distance: {shortestDistance}\n" +
                                  $"Callsign: {foundState.CallSign}\n" +
                                  $"Longitude: {foundState.Longitude}\n" +
                                  $"Latitude: {foundState.Latitude}\n" +
                                  $"Geometric Altitude: {foundState.GeoAltitude}\n" +
                                  $"Country of Origin: {foundState.OriginCountry}\n" +
                                  $"ICAO24 ID: {foundState.ICAO24}");
            }
        }
        public void ChooseActions(GameState currGameState, TankActionSet actionSet, bool[] moveChosenByTankNumber)
        {
            int[]       minDistanceToAttackEnemyBaseByPlayerIndex = new int[Constants.PLAYERS_PER_GAME];
            int[]       minDistanceToDefendOwnBaseByPlayerIndex   = new int[Constants.PLAYERS_PER_GAME];
            bool[]      isUnmarked = new bool[Constants.PLAYERS_PER_GAME];
            Direction[] attackDirOnEnemyBaseByPlayerIndex = new Direction[Constants.PLAYERS_PER_GAME];
            for (int p = 0; p < 2; p++)
            {
                attackDirOnEnemyBaseByPlayerIndex[p] = Direction.NONE;
            }
            Tank closestFriendlyTankToAttackEnemyBase = null;
            Tank closestFriendlyTankToDefendOwnBase   = null;
            Tank closestEnemyTankToAttackYourBase     = null;

            TankAction[] tankActionsForClosestFriendlyTankToAttackEnemyBase = null;
            TankAction[] tankActionsForClosestFriendlyTankToDefendOwnBase   = null;

            foreach (Player player in Game.Current.Players)
            {
                int minDistanceToEnemyBase = Constants.UNREACHABLE_DISTANCE;

                foreach (Tank tank in player.Tanks)
                {
                    MobileState tankState = currGameState.GetMobileState(tank.Index);
                    if (!tankState.IsActive)  // TODO: Check if locked in a firefight also
                    {
                        continue;
                    }

                    DirectionalMatrix <DistanceCalculation> distanceCalcMatrix
                        = currGameState.CalculationCache.GetIncomingDistanceMatrixForBase(1 - player.Index);
                    DistanceCalculation baseAttackCalc = distanceCalcMatrix[tankState];

                    int distanceToEnemyBase = baseAttackCalc.Distance;
                    if (distanceToEnemyBase < minDistanceToEnemyBase)
                    {
                        minDistanceToEnemyBase = distanceToEnemyBase;
                        attackDirOnEnemyBaseByPlayerIndex[player.Index] = baseAttackCalc.AdjacentNode.Dir;
                        if (player == You)
                        {
                            closestFriendlyTankToAttackEnemyBase = tank;
                            Base             enemyBase        = Game.Current.Players[1 - You.Index].Base;
                            FiringLineMatrix firingLineMatrix = currGameState.CalculationCache.FiringLinesForPointsMatrix;
                            tankActionsForClosestFriendlyTankToAttackEnemyBase = PathCalculator.GetTankActionsOnIncomingShortestPath(
                                distanceCalcMatrix, tankState, enemyBase.Pos, firingLineMatrix, true);
                        }
                        else
                        {
                            closestEnemyTankToAttackYourBase = tank;
                        }
                    }
                }
                minDistanceToAttackEnemyBaseByPlayerIndex[player.Index] = minDistanceToEnemyBase;
            }

            foreach (Player player in Game.Current.Players)
            {
                int minDistanceToDefendOwnBase = Constants.UNREACHABLE_DISTANCE;

                foreach (Tank tank in player.Tanks)
                {
                    MobileState tankState = currGameState.GetMobileState(tank.Index);
                    if (tankState.IsActive)  // TODO: Check if locked in a firefight also
                    {
                        DirectionalMatrix <DistanceCalculation> distanceMatrix
                            = currGameState.CalculationCache.GetDistanceMatrixFromTankByTankIndex(tank.Index);
                        Direction attackDir  = attackDirOnEnemyBaseByPlayerIndex[1 - player.Index];
                        Direction defenceDir = attackDir.GetOpposite();
                        if (defenceDir == Direction.NONE)
                        {
                            defenceDir = Direction.RIGHT;
                        }
                        Point defencePos = player.Base.Pos + (Constants.SEGMENT_SIZE + 1) * defenceDir.GetOffset();
                        DistanceCalculation tankDefenceCalc = distanceMatrix[
                            defenceDir, defencePos];

                        int distance = tankDefenceCalc.Distance;
                        if (distance < minDistanceToDefendOwnBase)
                        {
                            minDistanceToDefendOwnBase = distance;
                            if (player == You)
                            {
                                closestFriendlyTankToDefendOwnBase = tank;
                                tankActionsForClosestFriendlyTankToDefendOwnBase = PathCalculator.GetTankActionsOnOutgoingShortestPath(
                                    distanceMatrix, defenceDir, defencePos.X, defencePos.Y);
                            }
                        }
                    }
                }
                minDistanceToDefendOwnBaseByPlayerIndex[player.Index] = minDistanceToDefendOwnBase;
                if (minDistanceToAttackEnemyBaseByPlayerIndex[1 - player.Index] < minDistanceToDefendOwnBase)
                {
                    isUnmarked[1 - player.Index] = true;
                }
            }

            /*
             * int minAttackDistance = minDistanceToAttackEnemyBaseByPlayerIndex[You.Index];
             * if (Game.Current.CurrentTurn.Tick + minAttackDistance > Game.Current.FinalTickInGame)
             * {
             *  // Can't attack in time, rather defend...
             *  return;
             * }
             */

            // You're unmarked...
            Tank attackTank = closestFriendlyTankToAttackEnemyBase;

            if (isUnmarked[You.Index] && attackTank != null)
            {
                bool shouldAttack = true;

                // Enemy is marked...
                if (!isUnmarked[1 - You.Index])
                {
                    int minAttackDistance      = minDistanceToAttackEnemyBaseByPlayerIndex[You.Index];
                    int minEnemyAttackDistance = minDistanceToAttackEnemyBaseByPlayerIndex[1 - You.Index];

                    // But if you stop marking them, by going for their base, they can get there first...
                    if ((minAttackDistance > minEnemyAttackDistance) &&
                        (closestFriendlyTankToDefendOwnBase == attackTank))
                    {
                        shouldAttack = false;
                        // TODO: See if your other tank can do defence duty instead...
                    }
                }

                if (shouldAttack && !moveChosenByTankNumber[attackTank.Number])
                {
                    actionSet.Actions[attackTank.Number]      = tankActionsForClosestFriendlyTankToAttackEnemyBase[0];
                    moveChosenByTankNumber[attackTank.Number] = true;
                }
            }

            // If there is a slack of less than 5 ticks to defend your base, get back to defend it:
            Tank defenceTank = closestFriendlyTankToDefendOwnBase;

            if ((defenceTank != null) &&
                (minDistanceToAttackEnemyBaseByPlayerIndex[1 - You.Index] < minDistanceToDefendOwnBaseByPlayerIndex[You.Index] + 5))
            {
                if (!moveChosenByTankNumber[defenceTank.Number])
                {
                    actionSet.Actions[defenceTank.Number]      = tankActionsForClosestFriendlyTankToAttackEnemyBase[0];
                    moveChosenByTankNumber[defenceTank.Number] = true;
                }
            }

            // Otherwise choose an enemy tank to attack:
            for (int t = 0; t < Constants.TANKS_PER_PLAYER; t++)
            {
                if ((closestEnemyTankToAttackYourBase != null) && (!moveChosenByTankNumber[t]))
                {
                    // Rather attack an enemy tank in a firefight with own tank..
                    Tank killerTank = You.Tanks[t];
                    AttackClosestEnemyTankToOwnBase(currGameState, killerTank,
                                                    closestEnemyTankToAttackYourBase, actionSet,
                                                    moveChosenByTankNumber);
                }
            }
        }