示例#1
0
        public RobotAction Tick(int robotId, RoundConfig config, GameState state)
        {
            RobotState  self   = state.robots[robotId];
            RobotAction action = new RobotAction();

            action.targetId = -1;
            position mine             = new position();
            position charging_station = new position();
            position service_station  = new position();

            charging_station = getNearestChargingStation(state, self);
            service_station  = getNearestServiceStation(state, self);
            mine.x           = self.X;
            mine.y           = self.Y;
            HealthExchange(self, config, action, 0.0f, 0.4f, 0.6f);
            if (mine.x == charging_station.x &&
                mine.y == charging_station.y &&
                (self.attack + self.defence + self.speed) < 0.95 * config.max_health)
            {
                return(action);
            }
            if (mine.x == service_station.x &&
                mine.y == service_station.y &&
                self.energy < 0.99 * config.max_energy)
            {
                return(action);
            }
            //или пополняем энергию

            //MoveTo(charging_station, self, config, action);
            if (self.energy <= 0.8 * config.max_energy)
            {
                HealthExchange(self, config, action, 0.0f, 0.2f, 0.8f);
                MoveTo(getNearestServiceStation(state, self), self, config, action);
                return(action);
            }
            else
            {
                //или пополняем техн. состояние
                int service_sost = self.attack + self.defence + self.speed;
                if (service_sost <= 0.9 * config.max_health)
                {
                    MoveTo(getNearestChargingStation(state, self), self, config, action);
                    //записываем информацию о движении
                    return(action);
                }
                else
                {
                    int attack_range = (int)(config.max_radius) * 10 * self.speed * self.energy /
                                       (config.max_energy * config.max_health);
                    HealthExchange(self, config, action, 0.4f, 0.4f, 0.2f);
                    //или ищем цель  для удара и защиты
                    int  enemy_id     = -1;
                    bool under_attack = false;
                    for (int id = 0; id < state.robots.Count; id++)
                    {
                        RobotState rs = state.robots[id];
                        if (rs.name != self.name)
                        {
                            int enemy_distance_attack = 10 * config.max_radius * rs.speed * rs.energy / config.max_health / config.max_energy;
                            int distance = getDistance(self.X, self.Y, rs.X, rs.Y);
                            if (distance <= enemy_distance_attack && distance <= attack_range)
                            {
                                under_attack = true;
                                enemy_id     = id;
                            }
                        }
                    }


                    int target_id = GetNearestTarget(robotId, config, state, true, true);
                    HealthExchange(self, config, action, 0.4f, 0.4f, 0.2f);
                    if (target_id >= 0)
                    {
                        RobotState target     = state.robots[target_id];
                        position   target_pos = new position();
                        target_pos.x = target.X;
                        target_pos.y = target.Y;
                        MoveTo(target_pos, self, config, action);
                        position distance = new position();
                        distance.x = self.X + action.dX;
                        distance.y = self.Y + action.dY;

                        int dist = getDistance(self.X + action.dX, self.Y + action.dY, target_pos.x, target_pos.y);
                        if (dist <= attack_range)
                        {
                            action.targetId = target_id;
                        }
                    }
                }
            }
            return(action);
        }
        private async void Round_StatusChangedAsync(object sender, CoordinatorRoundStatus status)
        {
            try
            {
                var round = sender as CoordinatorRound;

                Money feePerInputs  = null;
                Money feePerOutputs = null;

                // If success save the coinjoin.
                if (status == CoordinatorRoundStatus.Succeded)
                {
                    uint256[] mempoolHashes = null;
                    try
                    {
                        mempoolHashes = await RpcClient.GetRawMempoolAsync().ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex);
                    }

                    using (await CoinJoinsLock.LockAsync().ConfigureAwait(false))
                    {
                        if (mempoolHashes is { })
                        {
                            var fallOuts = UnconfirmedCoinJoins.Where(x => !mempoolHashes.Contains(x));
                            CoinJoins.RemoveAll(x => fallOuts.Contains(x));
                            UnconfirmedCoinJoins.RemoveAll(x => fallOuts.Contains(x));
                        }

                        uint256 coinJoinHash = round.CoinJoin.GetHash();
                        CoinJoins.Add(coinJoinHash);
                        UnconfirmedCoinJoins.Add(coinJoinHash);
                        LastSuccessfulCoinJoinTime = DateTimeOffset.UtcNow;
                        await File.AppendAllLinesAsync(CoinJoinsFilePath, new[] { coinJoinHash.ToString() }).ConfigureAwait(false);

                        // When a round succeeded, adjust the denomination as to users still be able to register with the latest round's active output amount.
                        IEnumerable <(Money value, int count)> outputs = round.CoinJoin.GetIndistinguishableOutputs(includeSingle: true);
                        var bestOutput = outputs.OrderByDescending(x => x.count).FirstOrDefault();
                        if (bestOutput != default)
                        {
                            Money activeOutputAmount = bestOutput.value;

                            int currentConfirmationTarget = await AdjustConfirmationTargetAsync(lockCoinJoins : false).ConfigureAwait(false);

                            var fees = await CoordinatorRound.CalculateFeesAsync(RpcClient, currentConfirmationTarget).ConfigureAwait(false);

                            feePerInputs  = fees.feePerInputs;
                            feePerOutputs = fees.feePerOutputs;

                            Money newDenominationToGetInWithactiveOutputs = activeOutputAmount - (feePerInputs + (2 * feePerOutputs));
                            if (newDenominationToGetInWithactiveOutputs < RoundConfig.Denomination)
                            {
                                if (newDenominationToGetInWithactiveOutputs > Money.Coins(0.01m))
                                {
                                    RoundConfig.Denomination = newDenominationToGetInWithactiveOutputs;
                                    RoundConfig.ToFile();
                                }
                            }
                        }
                    }
示例#3
0
        private async void Round_StatusChangedAsync(object sender, CcjRoundStatus status)
        {
            try
            {
                var round = sender as CcjRound;

                Money feePerInputs  = null;
                Money feePerOutputs = null;

                // If success save the coinjoin.
                if (status == CcjRoundStatus.Succeded)
                {
                    using (await CoinJoinsLock.LockAsync())
                    {
                        uint256 coinJoinHash = round.SignedCoinJoin.GetHash();
                        CoinJoins.Add(coinJoinHash);
                        await File.AppendAllLinesAsync(CoinJoinsFilePath, new[] { coinJoinHash.ToString() });

                        // When a round succeeded, adjust the denomination as to users still be able to register with the latest round's active output amount.
                        IEnumerable <(Money value, int count)> outputs = round.SignedCoinJoin.GetIndistinguishableOutputs(includeSingle: true);
                        var bestOutput = outputs.OrderByDescending(x => x.count).FirstOrDefault();
                        if (bestOutput != default)
                        {
                            Money activeOutputAmount = bestOutput.value;

                            int currentConfirmationTarget = await AdjustConfirmationTargetAsync(lockCoinJoins : false);

                            var fees = await CcjRound.CalculateFeesAsync(RpcClient, currentConfirmationTarget);

                            feePerInputs  = fees.feePerInputs;
                            feePerOutputs = fees.feePerOutputs;

                            Money newDenominationToGetInWithactiveOutputs = activeOutputAmount - (feePerInputs + (2 * feePerOutputs));
                            if (newDenominationToGetInWithactiveOutputs < RoundConfig.Denomination)
                            {
                                if (newDenominationToGetInWithactiveOutputs > Money.Coins(0.01m))
                                {
                                    RoundConfig.Denomination = newDenominationToGetInWithactiveOutputs;
                                    await RoundConfig.ToFileAsync();
                                }
                            }
                        }
                    }
                }

                // If aborted in signing phase, then ban Alices that did not sign.
                if (status == CcjRoundStatus.Aborted && round.Phase == CcjRoundPhase.Signing)
                {
                    IEnumerable <Alice> alicesDidntSign = round.GetAlicesByNot(AliceState.SignedCoinJoin, syncLock: false);

                    CcjRound nextRound = GetCurrentInputRegisterableRoundOrDefault(syncLock: false);

                    if (nextRound != null)
                    {
                        int nextRoundAlicesCount = nextRound.CountAlices(syncLock: false);
                        var alicesSignedCount    = round.AnonymitySet - alicesDidntSign.Count();

                        // New round's anonset should be the number of alices that signed in this round.
                        // Except if the number of alices in the next round is already larger.
                        var newAnonymitySet = Math.Max(alicesSignedCount, nextRoundAlicesCount);
                        // But it cannot be larger than the current anonset of that round.
                        newAnonymitySet = Math.Min(newAnonymitySet, nextRound.AnonymitySet);

                        // Only change the anonymity set of the next round if new anonset does not equal and newanonset is larger than 1.
                        if (nextRound.AnonymitySet != newAnonymitySet && newAnonymitySet > 1)
                        {
                            nextRound.UpdateAnonymitySet(newAnonymitySet, syncLock: false);

                            if (nextRoundAlicesCount >= nextRound.AnonymitySet)
                            {
                                // Progress to the next phase, which will be OutputRegistration
                                await nextRound.ExecuteNextPhaseAsync(CcjRoundPhase.ConnectionConfirmation);
                            }
                        }
                    }

                    foreach (Alice alice in alicesDidntSign)                     // Because the event sometimes is raised from inside the lock.
                    {
                        // If it is from any coinjoin, then do not ban.
                        IEnumerable <OutPoint> utxosToBan = alice.Inputs.Select(x => x.Outpoint);
                        await UtxoReferee.BanUtxosAsync(1, DateTimeOffset.UtcNow, forceNoted : false, round.RoundId, utxosToBan.ToArray());
                    }
                }

                // If finished start a new round.
                if (status == CcjRoundStatus.Aborted || status == CcjRoundStatus.Succeded)
                {
                    round.StatusChanged       -= Round_StatusChangedAsync;
                    round.CoinJoinBroadcasted -= Round_CoinJoinBroadcasted;
                    await MakeSureTwoRunningRoundsAsync(feePerInputs, feePerOutputs);
                }
            }
            catch (Exception ex)
            {
                Logger.LogWarning(ex);
            }
        }
示例#4
0
        public RobotAction Tick(int robotId, RoundConfig config, GameState state)
        {
            RobotState selfRobot = state.robots[robotId];

            RobotAction action = new RobotAction();

            if (!selfRobot.isAlive)
            {
                return(action);
            }

            List <string> friendRobots = new List <string>()
            {
                "Ryzhov", "Haritonov", "Nikandrov", "Sinyavsky", "Frolov", "Orlov", "Kamshilov"
            };
            decimal MIN_ENERGY_TO_GO_RELOAD   = 0.85m;
            decimal MIN_HEALTH_TO_GO_RELOAD   = 0.85m;
            decimal MAX_ATTACK_DISTANCE_RATIO = 30m;

            List <Point> healthPoints     = state.points.Where(p => p.type == PointType.Health).ToList();
            List <Point> energyPoints     = state.points.Where(p => p.type == PointType.Energy).ToList();
            bool         hasNearestHealth = true;
            bool         hasNearestEnergy = true;

            Point   nearestHealth = null;
            decimal minDistH      = 10000000m;
            int     indexH        = -1;

            for (int i = 0; i < healthPoints.Count; i++)
            {
                Point   p    = healthPoints[i];
                decimal dist = GetDistance(p.X, p.Y, selfRobot.X, selfRobot.Y);
                if (dist < minDistH)
                {
                    minDistH = dist;
                    indexH   = i;
                }
            }

            if (indexH >= 0)
            {
                nearestHealth = healthPoints[indexH];
            }
            else
            {
                hasNearestHealth = false;
            }

            Point   nearestEnergy = null;
            decimal minDistE      = 10000000m;
            int     indexE        = -1;

            for (int i = 0; i < energyPoints.Count; i++)
            {
                Point   p    = energyPoints[i];
                decimal dist = GetDistance(p.X, p.Y, selfRobot.X, selfRobot.Y);
                if (dist < minDistE)
                {
                    minDistE = dist;
                    indexE   = i;
                }
            }

            if (indexE >= 0)
            {
                nearestEnergy = energyPoints[indexE];
            }
            else
            {
                hasNearestEnergy = false;
            }

            decimal energyRest = selfRobot.energy / (decimal)config.max_energy;
            decimal healthRest = (selfRobot.speed + selfRobot.defence + selfRobot.attack) / (decimal)config.max_health;

            decimal step         = GetMaxCurrentStep(selfRobot, config);
            decimal attackRadius = GetMaxCurrentAttackRadius(selfRobot, config);
            decimal attackPower  = GetMaxCurrentAttackPower(selfRobot, config);

            if ((energyRest <= MIN_ENERGY_TO_GO_RELOAD && hasNearestEnergy) || (healthRest <= MIN_HEALTH_TO_GO_RELOAD && hasNearestHealth) || !done)
            {
                int dx = 0;
                int dy = 0;
                done = false;

                if (energyRest >= 0.99m || healthRest >= 0.99m)
                {
                    done = true;
                }

                if (healthRest <= MIN_HEALTH_TO_GO_RELOAD && nearestHealth != null)
                {
                    Coord deltaCoord = GetCoordXYStepToPoint(nearestHealth, selfRobot, step);

                    if (Math.Abs(selfRobot.Y - nearestHealth.Y) <= 1)
                    {
                        deltaCoord.Y = (selfRobot.Y - nearestHealth.Y) * -1;
                    }

                    if (Math.Abs(selfRobot.X - nearestHealth.X) <= 1)
                    {
                        deltaCoord.X = (selfRobot.X - nearestHealth.X) * -1;
                    }

                    bool checkStep = CheckStepFieldBorders(selfRobot, config, deltaCoord);

                    if (checkStep)
                    {
                        action.dX       = deltaCoord.X;
                        action.dY       = deltaCoord.Y;
                        action.targetId = state.robots[robotId > 0 ? 0 : 1].id;
                    }
                }
                else if (energyRest <= MIN_ENERGY_TO_GO_RELOAD && nearestEnergy != null)
                {
                    Coord deltaCoord = GetCoordXYStepToPoint(nearestEnergy, selfRobot, step);

                    if (Math.Abs(selfRobot.Y - nearestEnergy.Y) <= 1)
                    {
                        deltaCoord.Y = (selfRobot.Y - nearestEnergy.Y) * -1;
                    }

                    if (Math.Abs(selfRobot.X - nearestEnergy.X) <= 1)
                    {
                        deltaCoord.X = (selfRobot.X - nearestEnergy.X) * -1;
                    }

                    bool checkStep = CheckStepFieldBorders(selfRobot, config, deltaCoord);

                    if (checkStep)
                    {
                        action.dX       = deltaCoord.X;
                        action.dY       = deltaCoord.Y;
                        action.targetId = state.robots[robotId > 0 ? 0 : 1].id;
                    }
                }
            }
            else
            {
                decimal           distToNearestAlienRobot = 10000000;
                List <RobotState> nearRobots = new List <RobotState>();
                foreach (RobotState item in state.robots)
                {
                    if (selfRobot.id != item.id && !friendRobots.Contains(item.name))
                    {
                        decimal dist = GetDistance(item.X, item.Y, selfRobot.X, selfRobot.Y);
                        if (dist <= attackRadius * MAX_ATTACK_DISTANCE_RATIO)
                        {
                            nearRobots.Add(item);
                        }
                    }
                }

                nearRobots = nearRobots.Where(r => r.isAlive == true).OrderBy(r => r.defence).ToList();

                bool foundAlienToAtack = false;

                int prevA = selfRobot.attack;
                int prevD = selfRobot.defence;

                foundAlienToAtack = CountAction(config, selfRobot, action, step, attackRadius, attackPower, nearRobots);

                if (!foundAlienToAtack)
                {
                    RobotState ar = GetNearestAlienRobotId(state, selfRobot, friendRobots);

                    Coord deltaCoord = GetCoordXYStepToPoint(new Point()
                    {
                        X = ar.X, Y = ar.Y
                    }, selfRobot, step);

                    bool checkStep = CheckStepFieldBorders(selfRobot, config, deltaCoord);

                    if (checkStep)
                    {
                        action.dX       = deltaCoord.X;
                        action.dY       = deltaCoord.Y;
                        action.targetId = ar.id;
                    }
                    else
                    {
                        action.dX = 0;
                    }
                }
            }

            battlestep++;
            return(action);
        }
示例#5
0
        public RobotAction Tick(int robotId, RoundConfig config, GameState state)
        {
            int    MinDistance = 999999;
            coords NextCoords  = new coords();

            RobotState  self   = state.robots[robotId];
            RobotAction action = new RobotAction();


            action.targetId = -1;



            foreach (Point P in state.points)
            {
                int a = TakeDistance(self.X, self.Y, P.X, P.Y);
                if (P.type == PointType.Energy && (a < MinDistance))
                {
                    MinDistance  = a;
                    NextCoords.x = P.X;
                    NextCoords.y = P.Y;
                }
            }

            int    enemy_id    = -1;
            coords destination = new coords();

            destination = MoveTo(self, config, NextCoords);

            coords destination2 = new coords();

            destination2 = MoveTo(self, config, NextCoords);

            action.dX = destination.x;
            action.dY = destination.y;

            int  maxdefdistance = 10 * config.max_radius * self.speed / config.max_health * self.energy / config.max_energy;
            bool attacked       = false;
            int  enemy_id1      = -1;

            for (int id = 0; id < state.robots.Count; id++)
            {
                RobotState rstates = state.robots[id];
                if (rstates.name != self.name)
                {
                    int enemy_distance_attack = 10 * config.max_radius * rstates.speed / config.max_health * rstates.energy / config.max_energy;
                    int distance = TakeDistance(self.X, self.Y, rstates.X, rstates.Y);
                    if (distance <= enemy_distance_attack && distance <= maxdefdistance)
                    {
                        attacked        = true;
                        enemy_id        = id;
                        action.targetId = enemy_id;
                    }
                }
            }

            if ((self.attack + self.defence + self.speed) < 0.4 * config.max_health)
            {
                action.dX = destination2.x;
                action.dY = destination2.y;
            }
            else if (self.energy < 0.4 * config.max_energy)
            {
                action.dX = destination.x;
                action.dY = destination.y;
            }
            return(action);
        }
示例#6
0
        private bool CountAction(RoundConfig config, RobotState selfRobot, RobotAction action, decimal step, decimal attackRadius, decimal attackPower, List <RobotState> nearRobots)
        {
            bool foundAlienToAtack = false;

            foreach (RobotState nrb in nearRobots)
            {
                if (nrb.defence <= attackPower)
                {
                    decimal dist        = GetDistance(nrb.X, nrb.Y, selfRobot.X, selfRobot.Y);
                    decimal currentStep = 0;
                    if (dist > attackRadius)
                    {
                        decimal dtoa = dist - attackRadius;
                        if (step > dtoa)
                        {
                            currentStep = step - dtoa;
                        }
                        else
                        {
                            currentStep = step;
                        }
                    }

                    if (currentStep > 0)
                    {
                        Coord deltaCoord = GetCoordXYStepToPoint(new Point()
                        {
                            X = nrb.X, Y = nrb.Y
                        }, selfRobot, currentStep);

                        bool checkStep = CheckStepFieldBorders(selfRobot, config, deltaCoord);

                        decimal diff = step - currentStep;
                        if (diff > 0)
                        {
                            decimal energyPart = selfRobot.energy / (decimal)config.max_energy;
                            decimal healthPart = (config.max_radius * selfRobot.speed) / (decimal)config.max_health;
                            decimal necessaryV = (config.max_health * (attackRadius - diff)) / (decimal)(energyPart * config.max_radius);
                        }

                        if (checkStep)
                        {
                            action.dX         = deltaCoord.X;
                            action.dY         = deltaCoord.Y;
                            action.targetId   = nrb.id;
                            foundAlienToAtack = true;
                            break;
                        }
                        else
                        {
                            action.dY = 0;
                        }
                    }
                    else
                    {
                        action.dX         = 0;
                        action.dY         = 0;
                        action.targetId   = nrb.id;
                        foundAlienToAtack = true;
                        break;
                    }
                }
            }

            return(foundAlienToAtack);
        }
示例#7
0
        public RobotAction Tick(int robotId, RoundConfig config, GameState state)
        {
            RobotState  self   = state.robots[robotId];
            RobotAction action = new RobotAction();

            action.targetId = -1;

            if (self.energy > 0 && self.isAlive)
            {
                int max_distance_attack = (int)Math.Round(10 * (float)config.max_radius * (float)self.speed / (float)config.max_health * (float)self.energy / (float)config.max_energy);
                int health = self.attack + self.defence + self.speed;

                int enemy_id = -1;
                if (self.energy > 0.7 * config.max_energy && health > 0.7 * config.max_health)
                {
                    for (int id = 0; id < state.robots.Count; id++)
                    {
                        RobotState rs = state.robots[id];
                        if (rs.name != self.name && rs.isAlive)
                        {
                            int enemy_distance_attack = (int)Math.Round(10 * (float)config.max_radius * (float)rs.speed / (float)config.max_health * (float)rs.energy / (float)config.max_energy);
                            int distance = CalcDistance(self.X, self.Y, rs.X, rs.Y);
                            if (distance <= enemy_distance_attack && distance <= max_distance_attack)
                            {
                                enemy_id = id;
                            }
                        }
                    }
                }

                if (enemy_id > 0)
                {
                    HealthRedestribution(self, config, action, 0.4f, 0.4f, 0.2f);

                    action.targetId = enemy_id;

                    MoveTo(robotId, config, state, action, state.robots[enemy_id].X, state.robots[enemy_id].Y);
                }
                else
                {
                    bool attack_mode = false;

                    HealthRedestribution(self, config, action, 0.0f, 0.4f, 0.6f);

                    if (self.energy < 0.95 * config.max_energy)
                    {
                        Point target = GetNearestStation(robotId, config, state, PointType.Energy);
                        MoveTo(robotId, config, state, action, target.X, target.Y);
                    }
                    else
                    {
                        if (health < 0.8 * config.max_health)
                        {
                            Point target_station = GetNearestStation(robotId, config, state, PointType.Health);

                            int X = target_station.X;
                            int Y = target_station.Y;

                            int target_robot_id = -1;

                            if (health > 0.4 * config.max_health)
                            {
                                int target_robot_dist = config.width * config.height;
                                for (int id = 0; id < state.robots.Count; id++)
                                {
                                    RobotState rs = state.robots[id];
                                    if (rs.isAlive == false && (rs.attack + rs.defence + rs.speed) > 0.4 * config.max_health)
                                    {
                                        int distance = CalcDistance(self.X, self.Y, rs.X, rs.Y);
                                        if (distance < target_robot_dist)
                                        {
                                            target_robot_id   = id;
                                            target_robot_dist = distance;
                                        }
                                    }
                                }
                            }

                            if (target_robot_id >= 0)
                            {
                                RobotState taregt_robot = state.robots[target_robot_id];
                                if (CalcDistance(self.X, self.Y, X, Y) > CalcDistance(self.X, self.Y, taregt_robot.X, taregt_robot.Y))
                                {
                                    X = taregt_robot.X;
                                    Y = taregt_robot.Y;
                                }
                            }

                            MoveTo(robotId, config, state, action, X, Y);
                        }
                        else
                        {
                            int targetId = GetNearestRobot(robotId, config, state);
                            if (targetId >= 0)
                            {
                                attack_mode = true;

                                RobotState target = state.robots[targetId];
                                MoveTo(robotId, config, state, action, target.X, target.Y);

                                int distance = CalcDistance(self.X + action.dX, self.Y + action.dY, target.X, target.Y);
                                if (distance <= max_distance_attack)
                                {
                                    action.targetId = targetId;
                                }
                            }
                        }
                    }

                    if (!attack_mode)
                    {
                        int target_id = -1;
                        for (int id = 0; id < state.robots.Count; id++)
                        {
                            RobotState rs = state.robots[id];
                            if (rs.name != self.name)
                            {
                                int distance = CalcDistance(self.X + action.dX, self.Y + action.dY, rs.X, rs.Y);
                                if (distance <= max_distance_attack)
                                {
                                    target_id = id;
                                }
                            }
                        }

                        if (target_id >= 0)
                        {
                            action.targetId = target_id;
                        }
                    }
                }
            }

            return(action);
        }
示例#8
0
        public coordinates MoveTo(RoundConfig rc, RobotState self, coordinates coords)
        {
            int         max_distance = 10 * rc.max_speed * self.speed / rc.max_health * self.energy / rc.max_energy;
            coordinates coordsRes    = new coordinates();
            coordinates coordsTry    = new coordinates();


            int dX = coords.x - self.X;

            int dY = coords.y - self.Y;



            coordinates coordsSign = new coordinates();

            coordsSign.x = sign(dX);
            coordsSign.y = sign(dY);

            coordsRes.x = 0;
            coordsRes.y = 0;
            if (Distance(self.X, self.Y, coords.x, coords.y) <= max_distance)
            {
                coordsRes.x = dX;
                coordsRes.y = dY;
            }
            else
            {
                coordsTry.x = 0;
                coordsTry.y = 0;
                bool ch = false;
                while (Pifagor(coordsTry.x, coordsTry.y) <= max_distance)
                {
                    if (ch)
                    {
                        coordsTry.x += coordsSign.x;
                        if (Pifagor(coordsTry.x, coordsTry.y) > max_distance)
                        {
                            break;
                        }
                        else
                        {
                            coordsRes.x += coordsSign.x;
                        }
                    }
                    else
                    {
                        coordsTry.y += coordsSign.y;
                        if (Pifagor(coordsTry.x, coordsTry.y) > max_distance)
                        {
                            break;
                        }
                        else
                        {
                            coordsRes.y += coordsSign.y;
                        }
                    }
                    ch = !ch;
                }
            }
            return(coordsRes);
        }
示例#9
0
        public RobotAction Tick(int robotId, RoundConfig config, GameState state)
        {
            RobotState  self   = state.robots[robotId];
            RobotAction action = new RobotAction();

            action.targetId = -1;

            if (self.energy > 0 && self.isAlive)
            {
                // find nearest energy station
                int pointId   = 0;
                int pointDist = config.height * config.width;
                for (int ptId = 0; ptId < state.points.Count; ptId++)
                {
                    Point pt = state.points[ptId];
                    if (pt.type == PointType.Energy)
                    {
                        int ptDist = CalcDistance(self.X, self.Y, pt.X, pt.Y);
                        if (ptDist < pointDist)
                        {
                            pointDist = ptDist;
                            pointId   = ptId;
                        }
                    }
                }

                Point targetPoint = state.points[pointId];

                int maxDistance = 10 * config.max_speed * self.speed / config.max_health * self.energy / config.max_energy;
                if (maxDistance > 0)
                {
                    if (pointDist <= maxDistance)
                    {
                        action.dX = targetPoint.X - self.X;
                        action.dY = targetPoint.Y - self.Y;
                    }
                    else
                    {
                        int steps = pointDist / maxDistance + 1;
                        action.dX = (targetPoint.X - self.X) / steps;
                        action.dY = (targetPoint.Y - self.Y) / steps;
                    }
                }

                // defense
                int targetId   = -1;
                int targetDist = config.width * config.height;
                for (int rsId = 0; rsId < state.robots.Count; rsId++)
                {
                    RobotState rs     = state.robots[rsId];
                    int        rsDist = CalcDistance(self.X, self.Y, rs.X, rs.Y);
                    if (rs.name != self.name && rs.energy > 0 && rsDist < targetDist)
                    {
                        targetDist = rsDist;
                        targetId   = rsId;
                    }
                }

                int maxDistanceAttack = 10 * config.max_radius * self.speed / config.max_health * self.energy / config.max_energy;
                if (targetDist <= maxDistanceAttack)
                {
                    action.targetId = targetId;
                }
            }

            return(action);
        }
示例#10
0
 public void UpdateRoundConfig(CcjRoundConfig roundConfig)
 {
     RoundConfig.UpdateOrDefault(roundConfig);
 }