示例#1
0
def obstacle_is_attacked(context, est_pos):
    world = context.world
    tank = context.tank
    physics = context.physics

    obstacles = chain(filter(DEAD_TANK, world.tanks),
                      filter(ALLY_TANK(tank.id), world.tanks))
    for obstacle in obstacles:
        next_position = physics.estimate_target_position(obstacle, tank)
        next_unit = fictive_unit(obstacle, next_position[0], next_position[1])

        blocked = (
            (physics.will_hit(tank, next_unit, DEAD_TANK_OBSTACLE_FACTOR)
             or physics.will_hit(tank, obstacle, DEAD_TANK_OBSTACLE_FACTOR))
            and tank.get_distance_to_unit(obstacle) < tank.get_distance_to(
                est_pos.x, est_pos.y))
        if blocked:
            return obstacle

    for bonus in world.bonuses:
        if (physics.will_hit(tank, bonus, BONUS_FACTOR)):
            dist_tank_to_bonus = tank.get_distance_to_unit(bonus)
            dist_tank_to_pos = tank.get_distance_to(est_pos.x, est_pos.y)
            if dist_tank_to_bonus < dist_tank_to_pos:
                dist_bonus_to_pos = bonus.get_distance_to(est_pos.x, est_pos.y)
                free_to_hit = dist_tank_to_bonus > 300 and dist_tank_to_bonus > 2 * dist_bonus_to_pos
                if not free_to_hit:
                    return bonus

    bunker_obstacle = world.obstacles[0]
    if (physics.will_hit(tank, bunker_obstacle, 1.06)
            and tank.get_distance_to_unit(bunker_obstacle) <
            tank.get_distance_to(est_pos.x, est_pos.y)):
        return bunker_obstacle
    return False
示例#2
0
    def _make_turn(self, tank, world, move):
        # Precalc for estimation
        self.enemies = list(filter(ALIVE_ENEMY_TANK, world.tanks))
        self.allies = list(filter(ALLY_TANK(tank.id), world.tanks))
        self.health_fraction = tank.crew_health / tank.crew_max_health
        self.hull_fraction = tank.hull_durability / tank.hull_max_durability
        self.enemies_count = len(self.enemies)

        targets = filter(ALIVE_ENEMY_TANK, world.tanks)

        if not targets:
            return

        for e in self.target_estimators:
            e.context = self

        if self.debug_mode:
            targets = sorted(targets, key=lambda t: t.player_name)
            self.debug(' ' * 70, end='')
            for e in self.target_estimators:
                self.debug('%14s' % e.NAME, end='')
            self.debug('%14s' % 'RESULT', end='')
            self.debug('')

            def out_tgt(tgt):
                def tgt_to_str(tgt):
                    return "TARGET [%12s] (id=%2s, x=%8.2f, y=%8.2f, |v|=%8.2f))" % (
                        tgt.player_name, tgt.id, tgt.x, tgt.y,
                        hypot(tgt.speedX, tgt.speedY))

                self.debug('%-70s' % (tgt_to_str(tgt) + ' : '), end='')
                res = 0
                for e in self.target_estimators:
                    if e.debugging:
                        v = e.debug_value(tgt)
                        self.debug('%14s' % str(v), end='')
                    else:
                        v = e.value(tgt)
                        self.debug('%14.2f' % v, end='')
                    #self.debug('%14.2f' % v, end='')

                    if not e.debugging:
                        res += v
                self.debug('%14.2f' % res, end='')
                self.debug('')

            for tgt in targets:
                out_tgt(tgt)

        get_target_priority = lambda target: sum(
            [e.value(target) for e in self.target_estimators])

        targets_f = [(t, get_target_priority(t)) for t in targets]

        cur_target = max(targets_f, key=operator.itemgetter(1))[0]
        self.memory.last_turret_target_id = cur_target.id

        self.decision_maker.context = self
        self.decision_maker.process(cur_target, move)
示例#3
0
            def obstacle_is_attacked():
                obstacles = chain(filter(DEAD_TANK, world.tanks),
                                  filter(ALLY_TANK(tank.id), world.tanks),
                                  world.obstacles)
                for obstacle in obstacles:
                    next_position = self.physics.estimate_target_position(
                        obstacle, tank)
                    next_unit = fictive_unit(obstacle, next_position[0],
                                             next_position[1])

                    blocked = ((self.physics.will_hit(
                        tank, next_unit, DEAD_TANK_OBSTACLE_FACTOR)
                                or self.physics.will_hit(
                                    tank, obstacle, DEAD_TANK_OBSTACLE_FACTOR))
                               and tank.get_distance_to_unit(obstacle) <
                               tank.get_distance_to(*est_pos))
                    if blocked:
                        return obstacle
                return False
示例#4
0
    def _make_turn(self, tank, world, move):
        # Precalc for estimation
        self.enemies = list(filter(ALIVE_ENEMY_TANK, world.tanks))
        self.allies = list(filter(ALLY_TANK(tank.id), world.tanks))
        self.health_fraction = tank.crew_health / tank.crew_max_health
        self.hull_fraction = tank.hull_durability / tank.hull_max_durability
        self.enemies_count = len(self.enemies)
        self.EA_cache = {}
        self.est_time_cache = {}

        def process_moving():
            positions = []
            for pg in self.position_getters:
                positions += pg.positions(tank, world)
            self.debug('Got %d positions' % len(positions))
            if not positions:
                return

            for e in self.position_estimators:
                e.context = self
            pos_and_values = [
                (pos, sum([e.value(pos) for e in self.position_estimators]))
                for pos in positions
            ]

            if self.debug_mode:
                top_pos = [
                    item[0] for item in list(
                        reversed(
                            sorted(pos_and_values, key=operator.itemgetter(
                                1))))[:6]
                ]

                self.debug(' ' * 50, end='')
                for e in self.position_estimators:
                    self.debug('%14s' % e.NAME, end='')
                self.debug('%14s' % 'RESULT', end='')
                self.debug('')

                def out_pos(pos):
                    self.debug('%-50s' % (str(pos) + ' : '), end='')
                    res = 0
                    for e in self.position_estimators:
                        v = e.value(pos)
                        self.debug('%14.2f' % v, end='')
                        res += v
                    self.debug('%14.2f' % res, end='')
                    self.debug('')

                for pos in top_pos:
                    out_pos(pos)
                self.debug('=' * 16)
                for pos in positions:
                    if pos.name.find('BONUS') != -1:
                        out_pos(pos)
                self.debug('=' * 16)
                for pos in positions:
                    if pos.name == 'FORWARD' or pos.name == 'BACKWARD' or pos.name == 'CURRENT':
                        out_pos(pos)

                self.debug('=' * 16)
                for pos in positions:
                    if pos.name.find('BORDER') != -1:
                        out_pos(pos)

            next_position = None

            position_iteration = 0
            #average_F = sum([pos[0] for pos in pos_f])/len(pos_f)
            pos_queue = PriorityQueue()
            for p_v in pos_and_values:
                pos_queue.put((-p_v[1] + random() * 1e-3, p_v[0]))

            while True:
                cur = pos_queue.get()[1]
                if not self.physics.position_is_blocked(
                        cur.x, cur.y, tank, world
                ) or position_iteration >= MAX_POSITION_ITERATIONS:
                    next_position = cur
                    break
                position_iteration += 1
                self.debug('!!! Skipping best position, iteration %d' %
                           position_iteration)
                if self.debug_mode:
                    self.debug('(blocked by %s)' % str(
                        self.physics.position_is_blocked(
                            cur.x, cur.y, tank, world)))

            self.debug(
                "GOING TO [%10s] (%8.2f, %8.2f); distance=%8.2f, ETA=%8.2f" %
                (next_position.name, next_position.x, next_position.y,
                 self.tank.get_distance_to(next_position.x, next_position.y),
                 self.physics.estimate_time_to_position(
                     next_position.x, next_position.y, tank)))
            self.memory.last_target_position[tank.id] = next_position
            self.physics.move_to_position(next_position.x, next_position.y,
                                          tank, move)

        def process_shooting():
            targets = filter(ALIVE_ENEMY_TANK, world.tanks)

            if not targets:
                return

            def get_target_priority(tank, target):
                health_fraction = tank.crew_health / tank.crew_max_health

                # ================
                # DISTANCE
                # ================
                angle_penalty_factor = (
                    1 + (1 - health_fraction) * 1.5 -
                    (1 - max(0, 150 - tank.remaining_reloading_time) / 150) *
                    1)

                angle_degrees = fabs(
                    tank.get_turret_angle_to_unit(target)) / PI * 180

                distance_penalty = tank.get_distance_to_unit(target) / 10
                angle_penalty = angle_penalty_factor * (angle_degrees**1.2) / 2

                # ================
                # FINISH
                # ================
                if ((target.crew_health <= 20 or target.hull_durability <= 20)
                        or (tank.premium_shell_count > 0 and
                            (target.crew_health <= 35
                             or target.hull_durability <= 35))):
                    finish_bonus = 30
                else:
                    finish_bonus = 0

                # ================
                # RESPONSE
                # ================
                if self.physics.attacked_area(
                        tank.x, tank.y, target, cache=self.EA_cache) > 0.5:
                    attacking_me_bonus = 20
                else:
                    attacking_me_bonus = 0

                # ================
                # LAST TARGET
                # ================
                last_target_bonus = 0
                if self.memory.last_turret_target_id:
                    if self.memory.last_turret_target_id == target.id:
                        last_target_bonus = 5

                result = 180 + finish_bonus + attacking_me_bonus + last_target_bonus - distance_penalty - angle_penalty
                self.debug(
                    'TARGET [%20s] (x=%8.2f, y=%8.2f, |v|=%8.2f) finish_B=%8.2f, AM_B=%8.2f, LT_B=%8.2f, D_P=%8.2f, A_P=%8.2f, APF=%8.2f, result=%8.2f'
                    % (target.player_name, target.x, target.y,
                       hypot(target.speedX, target.speedY), finish_bonus,
                       attacking_me_bonus, last_target_bonus, distance_penalty,
                       angle_penalty, angle_penalty_factor, result))
                return result

            if self.debug_mode:
                targets = sorted(targets, key=lambda t: t.player_name)
            targets_f = [(t, get_target_priority(tank, t)) for t in targets]

            cur_target = max(targets_f, key=operator.itemgetter(1))[0]
            self.memory.last_turret_target_id = cur_target.id

            est_pos = self.physics.estimate_target_position(cur_target, tank)

            def bonus_is_attacked():
                for bonus in world.bonuses:
                    if (self.physics.will_hit(tank, bonus, BONUS_FACTOR)
                            and tank.get_distance_to_unit(bonus) <
                            tank.get_distance_to(*est_pos)):
                        return bonus
                return False

            def obstacle_is_attacked():
                obstacles = chain(filter(DEAD_TANK, world.tanks),
                                  filter(ALLY_TANK(tank.id), world.tanks),
                                  world.obstacles)
                for obstacle in obstacles:
                    next_position = self.physics.estimate_target_position(
                        obstacle, tank)
                    next_unit = fictive_unit(obstacle, next_position[0],
                                             next_position[1])

                    blocked = ((self.physics.will_hit(
                        tank, next_unit, DEAD_TANK_OBSTACLE_FACTOR)
                                or self.physics.will_hit(
                                    tank, obstacle, DEAD_TANK_OBSTACLE_FACTOR))
                               and tank.get_distance_to_unit(obstacle) <
                               tank.get_distance_to(*est_pos))
                    if blocked:
                        return obstacle
                return False

            cur_angle = tank.get_turret_angle_to(*est_pos)
            good_to_shoot = self.physics.will_hit(
                tank, fictive_unit(cur_target, est_pos[0], est_pos[1]),
                TARGETING_FACTOR)
            if good_to_shoot:
                if self.health_fraction > 0.8 and self.hull_fraction > 0.5 and tank.get_distance_to_unit(
                        cur_target) > 400 and tank.premium_shell_count <= 3:
                    move.fire_type = FireType.REGULAR
                else:
                    move.fire_type = FireType.PREMIUM_PREFERRED
            else:
                move.fire_type = FireType.NONE

            if bonus_is_attacked() or obstacle_is_attacked():
                self.debug('!!! Obstacle is attacked, don\'t shoot')
                move.fire_type = FireType.NONE

            if world.tick < 10 + tank.teammate_index * 10:
                move.fire_type = FireType.NONE

            if fabs(cur_angle) > PI / 180 * 0.5:
                move.turret_turn = sign(cur_angle)

        process_moving()
        self.debug('=' * 16)
        process_shooting()
示例#5
0
    def _make_turn(self, tank, world, move):
        # Precalc for estimation
        self.enemies = list(filter(ALIVE_ENEMY_TANK, world.tanks))
        self.allies = list(filter(ALLY_TANK(tank.id), world.tanks))
        self.health_fraction = tank.crew_health / tank.crew_max_health
        self.hull_fraction = tank.hull_durability / tank.hull_max_durability
        self.enemies_count = len(self.enemies)
        self.est_time_cache = {}

        positions = []
        for pg in self.position_getters:
            positions += pg.positions(tank, world)
        self.debug('Got %d positions' % len(positions))
        if not positions:
            return

        for e in self.position_estimators:
            e.context = self
        pos_and_values = [
            (pos, sum([e.value(pos) for e in self.position_estimators]))
            for pos in positions
        ]

        if self.debug_mode:
            top_pos = [
                item[0] for item in list(
                    reversed(sorted(pos_and_values, key=operator.itemgetter(
                        1))))[:6]
            ]

            self.debug(' ' * 50, end='')
            for e in self.position_estimators:
                self.debug('%14s' % e.NAME, end='')
            self.debug('%14s' % 'RESULT', end='')
            self.debug('')

            def out_pos(pos):
                self.debug('%-50s' % (str(pos) + ' : '), end='')
                res = 0
                for e in self.position_estimators:
                    v = e.value(pos)
                    self.debug('%14.2f' % v, end='')
                    res += v
                self.debug('%14.2f' % res, end='')
                self.debug('')

            for pos in top_pos:
                out_pos(pos)
            self.debug('=' * 16)
            for pos in positions:
                if pos.name.find('BONUS') != -1:
                    out_pos(pos)
            self.debug('=' * 16)
            for pos in positions:
                if pos.name == 'FORWARD' or pos.name == 'BACKWARD' or pos.name == 'CURRENT':
                    out_pos(pos)

            self.debug('=' * 16)
            for pos in positions:
                if pos.name.find('BORDER') != -1:
                    out_pos(pos)

        next_position = None

        position_iteration = 0
        #average_F = sum([pos[0] for pos in pos_f])/len(pos_f)
        pos_queue = PriorityQueue()
        for p_v in pos_and_values:
            pos_queue.put((-p_v[1] + random() * 1e-3, p_v[0]))

        while True:
            cur = pos_queue.get()[1]
            if not self.physics.position_is_blocked(
                    cur.x, cur.y, tank,
                    world) or position_iteration >= MAX_POSITION_ITERATIONS:
                next_position = cur
                break
            position_iteration += 1
            self.debug('!!! Skipping best position, iteration %d' %
                       position_iteration)
            if self.debug_mode:
                self.debug('(blocked by %s)' % str(
                    self.physics.position_is_blocked(cur.x, cur.y, tank,
                                                     world)))

        self.debug(
            "GOING TO [%10s] (%8.2f, %8.2f); distance=%8.2f, ETA=%8.2f" %
            (next_position.name, next_position.x, next_position.y,
             self.tank.get_distance_to(next_position.x, next_position.y),
             self.physics.estimate_time_to_position(next_position.x,
                                                    next_position.y, tank)))
        self.memory.last_target_position[tank.id] = next_position
        self.physics.move_to_position(next_position.x, next_position.y, tank,
                                      move)

        self.debug('=' * 16)
        if self.debug_mode:
            for shell in world.shells:
                v0 = hypot(shell.speedX, shell.speedY)
                a = SHELL_ACCELERATION
                d = tank.get_distance_to_unit(shell)
                tank_v = Vector(tank.x, tank.y)
                shell_v = Vector(shell.x, shell.y)
                shell_speed = Vector(shell.speedX, shell.speedY)
                #d = shell.get_distance_to(x, y)
                t = solve_quadratic(a / 2, v0, -d)

                self.debug(
                    'SHELL [%12s] (%8.2f, %8.2f) v=%s, will hit=%s, hit time=%8.2f'
                    %
                    (shell.player_name, shell.x, shell.y, shell_speed.length(),
                     str(self.physics.shell_will_hit(shell, tank,
                                                     factor=1.05)), t))

            self.debug('=' * 16)
示例#6
0
    def move(self, tank, world, move):
        self.world = world

        #if world.tick % 500 == 0:
        #    print('tick %d' % world.tick)

        if DEBUG_MODE:
            try:
                self.memory.battle_id
            except:
                self.memory.battle_id = random.randint(1, 10**6)
                self.debug('#' * 64)
                self.debug("BATTLE ID : " + str(self.memory.battle_id))
                self.debug('#' * 64)

        self.debug('')
        self.debug('#' * 64)
        self.debug(
            '======================== (Tick) T%s#%-4s ========================'
            % (tank.teammate_index, world.tick))
        self.debug(
            'Tank %s (id=%s, x=%s, y=%s, health=%4s/%4s, hull=%4s/%4s, super_shells=%2s, reload=%3s/%3s, gts=%s), prec=%8.2f'
            % (tank.teammate_index, tank.id, tank.x, tank.y, tank.crew_health,
               tank.crew_max_health, tank.hull_durability,
               tank.hull_max_durability, tank.premium_shell_count,
               tank.remaining_reloading_time, tank.reloading_time,
               self.memory.good_to_shoot.get(
                   tank.id), self.memory.tank_precision[tank.id]))
        self.debug('#' * 64)

        if DEAD_TANK(tank):
            self.memory.target_id[tank.id] = None
            self.debug('DEAD x_x')
            return

        tanks = world.tanks

        allies = list(filter(ALLY_TANK(tank.id), tanks))
        enemies = list(filter(ALIVE_ENEMY_TANK, tanks))

        if len(world.players) == 2:
            # MAIN
            allies = list(filter(ALIVE_ALLY_TANK, allies))
            if len(allies) == 2:
                if len(enemies) == 3:
                    strategy = strategy_third_round
                elif len(enemies) == 2:
                    res = 0
                    for t in allies:
                        for enemy in enemies:
                            res += target_dangerousness_for_tank(enemy, t)
                    if res < -0.3:
                        strategy = strategy_third_round_prevail
                    else:
                        strategy = strategy_third_round
                else:
                    strategy = strategy_third_round_total_prevail

            elif len(allies) == 1:
                if len(enemies) > 1:
                    strategy = strategy_third_round_two_left
                else:
                    strategy = strategy_third_round_two_left_prevail

            else:
                if len(enemies) > 1:
                    strategy = strategy_third_round_last_man_standing
                else:
                    strategy = strategy_third_round_last_man_standing

        elif len(allies) == 1 and not DEAD_TANK(allies[0]):
            if len(enemies) > 2:
                strategy = StrategySecondRound4Enemies(tank, world,
                                                       self.memory, DEBUG_MODE)
            elif len(enemies) > 1:
                strategy = StrategySecondRound2Enemies(tank, world,
                                                       self.memory, DEBUG_MODE)
            else:
                strategy = StrategyOnePlayerDuel(tank, world, self.memory,
                                                 DEBUG_MODE)
        else:
            if len(enemies) > 3:
                strategy = StrategyOnePlayer5Enemies(tank, world, self.memory,
                                                     DEBUG_MODE)
            elif len(enemies) > 1:
                strategy = StrategyOnePlayer2Enemies(tank, world, self.memory,
                                                     DEBUG_MODE)
            else:
                strategy = StrategyOnePlayerDuel(tank, world, self.memory,
                                                 DEBUG_MODE)

        try:
            self.debug("Strategy: %s" % strategy.name)
        except:
            pass
        strategy.change_state(tank, world, self.memory, DEBUG_MODE)
        strategy.make_turn(move)

        self.debug('_' * 64)
        self.debug(
            'Output: left: %5.2f, right: %5.2f, fire type: %d, turret turn: %8.2f'
            % (move.left_track_power, move.right_track_power, move.fire_type,
               move.turret_turn))

        #self.analysis.store_shell_velocity(world)

        if PHYSICS_RESEARCH_MODE:
            for tank in world.tanks:
                if tank.player_name == "EmptyPlayer":
                    print(Vector(tank.speedX, tank.speedY).length())
示例#7
0
    def _make_turn(self, tank, world, move):
        # Precalc for estimation
        self.enemies = list(filter(ALIVE_ENEMY_TANK, world.tanks))
        self.allies = list(filter(ALLY_TANK(tank.id), world.tanks))
        self.health_fraction = tank.crew_health / tank.crew_max_health
        self.hull_fraction = tank.hull_durability / tank.hull_max_durability
        self.enemies_count = len(self.enemies)

        def process_shooting():
            targets = filter(ALIVE_ENEMY_TANK, world.tanks)

            if not targets:
                return

            def get_target_priority(tank, target):
                health_fraction = tank.crew_health / tank.crew_max_health

                # ================
                # DISTANCE
                # ================
                angle_penalty_factor = (
                    1 + (1 - health_fraction) * 1.5 -
                    (1 - max(0, 150 - tank.remaining_reloading_time) / 150) *
                    1)

                angle_degrees = fabs(
                    tank.get_turret_angle_to_unit(target)) / PI * 180

                distance_penalty = tank.get_distance_to_unit(target) / 10
                angle_penalty = angle_penalty_factor * (angle_degrees**1.2) / 2

                # ================
                # FINISH
                # ================
                if ((target.crew_health <= 20 or target.hull_durability <= 20)
                        or (tank.premium_shell_count > 0 and
                            (target.crew_health <= 35
                             or target.hull_durability <= 35))):
                    finish_bonus = 30
                else:
                    finish_bonus = 0

                # ================
                # RESPONSE
                # ================
                if self.physics.attacked_area(
                        tank.x, tank.y, target, cache=self.EA_cache) > 0.5:
                    attacking_me_bonus = 20
                else:
                    attacking_me_bonus = 0

                # ================
                # LAST TARGET
                # ================
                last_target_bonus = 0
                if self.memory.last_turret_target_id:
                    if self.memory.last_turret_target_id == target.id:
                        last_target_bonus = 5

                result = 180 + finish_bonus + attacking_me_bonus + last_target_bonus - distance_penalty - angle_penalty
                self.debug(
                    'TARGET [%20s] (x=%8.2f, y=%8.2f, |v|=%8.2f) finish_B=%8.2f, AM_B=%8.2f, LT_B=%8.2f, D_P=%8.2f, A_P=%8.2f, APF=%8.2f, result=%8.2f'
                    % (target.player_name, target.x, target.y,
                       hypot(target.speedX, target.speedY), finish_bonus,
                       attacking_me_bonus, last_target_bonus, distance_penalty,
                       angle_penalty, angle_penalty_factor, result))
                return result

            if self.debug_mode:
                targets = sorted(targets, key=lambda t: t.player_name)
            targets_f = [(t, get_target_priority(tank, t)) for t in targets]

            cur_target = max(targets_f, key=operator.itemgetter(1))[0]
            self.memory.last_turret_target_id = cur_target.id

            est_pos = self.physics.estimate_target_position(cur_target, tank)

            def bonus_is_attacked():
                for bonus in world.bonuses:
                    if (self.physics.will_hit(tank, bonus, BONUS_FACTOR)
                            and tank.get_distance_to_unit(bonus) <
                            tank.get_distance_to(*est_pos)):
                        return bonus
                return False

            def obstacle_is_attacked():
                obstacles = chain(filter(DEAD_TANK, world.tanks),
                                  filter(ALLY_TANK(tank.id), world.tanks),
                                  world.obstacles)
                for obstacle in obstacles:
                    next_position = self.physics.estimate_target_position(
                        obstacle, tank)
                    next_unit = fictive_unit(obstacle, next_position[0],
                                             next_position[1])

                    blocked = ((self.physics.will_hit(
                        tank, next_unit, DEAD_TANK_OBSTACLE_FACTOR)
                                or self.physics.will_hit(
                                    tank, obstacle, DEAD_TANK_OBSTACLE_FACTOR))
                               and tank.get_distance_to_unit(obstacle) <
                               tank.get_distance_to(*est_pos))
                    if blocked:
                        return obstacle
                return False

            cur_angle = tank.get_turret_angle_to(*est_pos)
            good_to_shoot = self.physics.will_hit(
                tank, fictive_unit(cur_target, est_pos[0], est_pos[1]),
                TARGETING_FACTOR)
            if good_to_shoot:
                if self.health_fraction > 0.8 and self.hull_fraction > 0.5 and tank.get_distance_to_unit(
                        cur_target) > 400 and tank.premium_shell_count <= 3:
                    move.fire_type = FireType.REGULAR
                else:
                    move.fire_type = FireType.PREMIUM_PREFERRED
            else:
                move.fire_type = FireType.NONE

            if bonus_is_attacked() or obstacle_is_attacked():
                self.debug('!!! Obstacle is attacked, don\'t shoot')
                move.fire_type = FireType.NONE

            if world.tick < 10 + tank.teammate_index * 10:
                move.fire_type = FireType.NONE

            if fabs(cur_angle) > PI / 180 * 0.5:
                move.turret_turn = sign(cur_angle)

        process_shooting()