def shot(self, enemy):
        vector = Vector.from_points(self.coord, enemy.coord, module=1)
        self.vector = vector
        able_to_shot = True

        if any(self.point_in_circle(self.coord, teammate) for teammate in self.teammates) or \
                any(self.point_in_circle(self.coord, mother_ship.coord) for mother_ship in self.scene.motherships):
            point = self.make_a_step(
                self.coord,
                Point(scene.theme.FIELD_WIDTH / 2,
                      scene.theme.FIELD_HEIGHT / 2))
            self.move_at(point)
            return

        for teammate in self.teammates:
            vector = Vector.from_points(self.coord, teammate.coord, module=1)
            difference = abs(self.vector.direction - vector.direction)
            distance = self.distance_to(teammate)

            if difference < 15 and distance < self.gun.shot_distance:
                able_to_shot = False
                break

        if able_to_shot and self.distance_to(enemy) <= self.gun.shot_distance:
            if enemy.is_moving:
                self.gun.shot(
                    Point(enemy.coord.x + enemy.vector.x**enemy.vector.module,
                          enemy.coord.y + enemy.vector.y**enemy.vector.module))
            else:
                self.gun.shot(enemy)
Пример #2
0
    def check_not_friendly_fire(self, potential_target: object):
        """
        Проверка выстрела на friendly fair (циклом просматривает всех сокомандников и,
        если хотя бы один не проходит все проверки то возвращает False)

        :param potential_target: Цель, по которой дрону отдан приказ стрелять
        :type potential_target: Object
        :return: возвращает True, если выстрелить можно, и возвращает False, если стрелять нельзя
        :rtype: bool
        """

        vector_to_target = Vector.from_points(
            self.coord, potential_target.coord)  # ветор от дрона до цели
        for my_team_drone in self.my_brain_center.ret_drones_by_status(
                filter_alive=True, filter_our=True):
            if my_team_drone != self:  # в себя никак не попадешь, поэтому себя проверять на friendly fair не нужно
                if self.distance_to(potential_target) > self.distance_to(
                        my_team_drone
                ):  # если дистанция от дрона до цели больше, чем до сокомандника, то теоретически сокомандник может быть прямо между вами и целью - требуется дальнейшая проверка
                    if my_team_drone.near(
                            potential_target
                    ) is False:  # если цель и сокомандник находятся слишком близко друг к другу, то игра засчитает урон дрону или базе из другой команды
                        vector_to_teammate = Vector.from_points(
                            self.coord, my_team_drone.coord)
                        if vector_to_target.direction - self.ACCURACY_CANCEL_SHOT_FRIENDLY_FIRE <= \
                                vector_to_teammate.direction <= \
                                vector_to_target.direction + self.ACCURACY_CANCEL_SHOT_FRIENDLY_FIRE:  # проверка на зону поражения - если сокомандник находится в зоне поражения, то при выстреле с высокой вероятностью будет поражен
                            return False  # возвращаем False - нельзя стрелять
        return True  # возвращаем True, если все дроны прошли все проверки в цикле
Пример #3
0
    def game_step(self):
        if not self.have_gun:
            super(HunterDrone, self).game_step()
            return

        self.native_game_step()
        if self._hunting_strategy is None:
            return
        self._hunting_strategy.game_step(self)
        if self.victim is not None:
            vector = Vector.from_points(self.coord,
                                        self.victim.coord,
                                        module=self.gun.shot_distance)
            if int(self.distance_to(self.victim)) < 1 or (
                    self.distance_to(self.victim) < vector.module and abs(
                        nearest_angle_distance(vector.direction,
                                               self.direction)) < 7):
                self.gun.shot(self.victim)
        else:
            enemies = [
                enemy for enemy in self.scene.drones
                if enemy.team != self.team and enemy.is_alive
                and enemy.distance_to(self) < self.gun.shot_distance
            ]
            enemie = sorted(enemies, key=lambda x: -x.cargo.payload)
            for enemy in enemies:
                vector = Vector.from_points(self.coord, enemy.coord)
                if abs(nearest_angle_distance(vector.direction,
                                              self.direction)) < 7:
                    self.gun.shot(enemy)
                    break
        pass
Пример #4
0
 def _get_point_nearby_enemy(self, target):
     """
     Находит и возвращает валидную точку, которую можно занять для атаки цели
     :param target: цель атаки
     :return: оптимальную(нет) точку рядом с врагом
     """
     if isinstance(target, GameObject):
         vec = Vector.from_points(target.coord, self.drone.coord)
     elif isinstance(target, Point):
         vec = Vector.from_points(target, self.drone.coord)
     else:
         raise Exception("target must be GameObject or Point!".format(target, ))
     dist = vec.module
     _koef = 1 / dist
     norm_vec = Vector(vec.x * _koef, vec.y * _koef)
     vec_gunshot = norm_vec * min(int(self.drone.attack_range), int(dist))
     purpose = Point(target.coord.x + vec_gunshot.x, target.coord.y + vec_gunshot.y)
     angles = [0, 60, -60, 40, -40, 20, -20]
     shuffle(angles)
     if self.drone.drone_number == 1:
         place = self.get_place_near(purpose, target, angles[self.drone.drone_number])
         return place
     for ang in angles:
         place = self.get_place_near(purpose, target, ang)
         if place and self.valid_place(place):
             return place
     return Point(theme.FIELD_WIDTH // 2, theme.FIELD_HEIGHT // 2)
Пример #5
0
    def get_place_for_attack(self, soldier, target):
        """
        Выбор места для атаки цели, если цель не в радиусе атаки

        :param soldier: атакующий
        :param target: цель/объект атаки
        :return: Point  - место атаки или None - если не выбрано место атаки
        """
        if isinstance(target, GameObject):
            vec = Vector.from_points(target.coord, soldier.coord)
        elif isinstance(target, Point):
            vec = Vector.from_points(target, soldier.coord)
        else:
            raise Exception("target must be GameObject or Point!".format(
                target, ))

        dist = vec.module
        _koef = 1 / dist
        norm_vec = Vector(vec.x * _koef, vec.y * _koef)
        vec_gunshot = norm_vec * min(int(soldier.attack_range), int(dist))
        purpose = Point(target.coord.x + vec_gunshot.x,
                        target.coord.y + vec_gunshot.y)
        angles = [0, 60, -60, 30, -30]
        random.shuffle(angles)
        for ang in angles:
            place = self.get_place_near(purpose, target, ang)
            if place and soldier.validate_place(place):
                return place
        return None
Пример #6
0
    def devide_step_path(self, drone, target):

        if drone.distance_to(target) > 150:
            for angle_delta in range(12):
                vec = Vector.from_points(drone.coord, target.coord)
                vec = Vector.from_direction(
                    vec.direction + randint(angle_delta * 5, angle_delta * 5),
                    150)
                flag = True
                for d in drone.scene.drones:
                    if d.team != drone.team and drone.distance_to(
                            d) < drone.gun.shot_distance:
                        vec2 = Vector.from_points(d.coord, target.coord)
                        if ((abs(180 - abs(d.direction - vec.direction)) < 5 or
                             (abs(d.direction - vec.direction) < 5
                              and abs(vec2.direction - vec.direction) < 5))):
                            flag = False
                if flag:
                    break
            else:
                vec = Vector.from_points(drone.coord, target.coord)
                vec = Vector.from_direction(vec.direction, 150)
                new_coord = Point(x=drone.coord.x + vec.x,
                                  y=drone.coord.y + vec.y)
                drone.actions.append(['move_step', new_coord])
                return
            # передвигаемся не по прямой до цели, а по 150 точек, со случайным углом
            new_coord = Point(x=drone.coord.x + vec.x, y=drone.coord.y + vec.y)
            drone.actions.append(['move_step', new_coord])
        else:
            if drone.distance_to(target) > 1:
                drone.actions.append(['move', target])
Пример #7
0
 def move_to(self, object):
     self.cost_forpost = 0
     self.target_move_to = object
     self.headquarters.save_static_move(self, object)
     vector_target = Vector.from_points(self.coord, object, module=1) if isinstance(object, Point) else \
         Vector.from_points(self.coord, object.coord, module=1)
     self.vector = vector_target
     super().move_at(object)
Пример #8
0
 def get_coords_for_attak(self, drones_in_my_team, mothership_name):
     mothership = self.scene.get_mothership(mothership_name)
     drones = list(d for d in self.scene.drones
                   if d.team == mothership.team)
     quantity = drones_in_my_team
     if mothership != self.mothership:
         distance = 400
     else:
         distance = 300
         angle = 85 / (quantity - 1)
         rotate = -5
         self.target_for_attack = None
     if mothership.x > self.scene.field[
             0] / 2 and mothership.y > self.scene.field[1] / 2:
         p = Point(mothership.x, mothership.y - distance)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = 0
     elif mothership.x > self.scene.field[
             0] / 2 and mothership.y < self.scene.field[1] / 2:
         p = Point(mothership.x - distance, mothership.y)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = -50
     elif mothership.x < self.scene.field[
             0] / 2 and mothership.y > self.scene.field[1] / 2:
         p = Point(mothership.x + distance, mothership.y)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = -50
     elif mothership.x < self.scene.field[
             0] / 2 and mothership.y < self.scene.field[1] / 2:
         p = Point(mothership.x, mothership.y + distance)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = 0
     len_alive = len(set(m for m in self.scene.motherships if m.is_alive))
     if len_alive == 2:
         angle = 90 / (quantity - 1)
         rotate = 0
     v.rotate(rotate)
     p = Point(mothership.x + v.x, mothership.y + v.y)
     points_to_stop = [p]
     difference = angle
     while len(points_to_stop) < quantity:
         next_v = Vector.from_direction(v.direction - angle, v.module)
         next_p = Point(mothership.x + next_v.x, mothership.y + next_v.y)
         points_to_stop.append(next_p)
         angle += difference
     for d in my_team:
         d.point_to_attack_mothership = points_to_stop.pop()
         d.move_at(self.point_to_attack_mothership)
         self.action = 'move_to_plase_for_attack'
Пример #9
0
 def _friendly_fire(self, enemy):
     enemy_vector = Vector.from_points(self.drone.coord, enemy.coord)
     for mate in self.drone.teammates:
         if self.drone.near(mate):
             return True
         mate_vector = Vector.from_points(self.drone.coord, mate.coord)
         scalar = int(enemy_vector.x * mate_vector.x +
                      enemy_vector.y * mate_vector.y)
         modules = int(enemy_vector.module * mate_vector.module)
         angle = math.degrees(math.acos(min(scalar / modules, 1)))
         if angle < 20 and self.drone.distance_to(enemy) > self.drone.distance_to(mate) \
                 and not isinstance(mate.state, StateMoving):
             return True
     return False
Пример #10
0
    def get_angle_delta(self, friend_drone):
        """
        Метод возвращает дельту углов между углом дрона к цели и углом дрона к союзнику.
        Используется для дальнейшей проверки не находится ли союзник на линии огня.

        :param friend_drone: Drone-class instance
        :return: float

        """
        my_aim_vec = Vector.from_points(self.drone.coord, self.drone.aim.coord)
        my_aim_direction = my_aim_vec.direction

        friend_drone_vec = Vector.from_points(self.drone.coord, friend_drone.coord)
        friend_drone_direction = friend_drone_vec.direction
        result = abs(friend_drone_direction - my_aim_direction)
        return result
Пример #11
0
    def get_place_for_attack(self, drone, purpose):
        """
        Получение места для атаки
        :param drone: экземпляр класса OkhotnikovFNDrone
        :param purpose: обект, колученный в методе next_purpose
        :return: точка на карте, из которой будет вестись огонь по цели
        """
        safe_distance = round(drone.radius * 1.6)

        vec = Vector.from_points(purpose.coord, drone.coord, module=1)
        dist = drone.distance_to(purpose)
        vec_gunshot = vec * min(int(drone.attack_range), int(dist))
        target = Point(purpose.coord.x + vec_gunshot.x,
                       purpose.coord.y + vec_gunshot.y)

        possible_points_attack = self._get_possible_points_attack(
            target, purpose, drone)
        # print(possible_points_attack)
        for point_attack in possible_points_attack:
            place_free = True
            for occupied_point in self.occupied_points_attack:
                place_free = place_free and point_attack.distance_to(
                    occupied_point) >= safe_distance

            if (point_attack and self.valid_place(point_attack)
                    and self.valid_bullet_trajectory(point_attack, purpose)
                    and place_free):
                self.occupied_points_attack.append(point_attack)
                return point_attack

        return None
Пример #12
0
    def is_safe_way_to_target(self,
                              target):  # проверяет безопасно ли лететь до цели
        enemies = [
            drone for drone in self.scene.drones
            if self.team != drone.team and drone.is_alive
        ]

        vector_to_target = Vector.from_points(
            self.coord,
            target.coord if not isinstance(target, Point) else target)
        distance_to_target = vector_to_target.module if vector_to_target.module > 1 else 1
        _koef = 1 / distance_to_target
        normalize_vector = Vector(vector_to_target.x * _koef,
                                  vector_to_target.y * _koef)
        start_distance = 100 if self.is_near_base() else 1
        drones_on_way = []
        for i in range(start_distance, int(distance_to_target),
                       self.radius // 2):
            current_vector = normalize_vector * i
            check_point = Point(self.x + current_vector.x,
                                self.y + current_vector.y)
            for drone in enemies:
                if drone.distance_to(
                        check_point
                ) <= self.attack_range + 2 * self.radius:  # если по пути будем под обстрелом, то небезопасно
                    drones_on_way.append(drone.id)

        drones_on_way = set(drones_on_way)
        if len(
                drones_on_way
        ) <= 1:  # если во время перелёта по дрону будет стретять не больше 1 врага, то можно лететь
            return True
        else:
            return False
Пример #13
0
 def move_to(self, target):
     if isinstance(target, Point):
         coord = target
     else:
         coord = target.coord
     self.vector = Vector.from_points(self.coord, coord, module=0.1)
     self.move_at(target)
Пример #14
0
    def _shoot_or_move(self, drone, purpose):
        """
        Происходит выбор делать выстрел или сменить позицию
        :param drone: экземпляр класса OkhotnikovFNDrone
        :param purpose: обект, колученный в методе next_purpose
        """
        safe_mothership_radius = round(drone.mothership.radius * 1.6)

        if self.valid_place(drone.coord) and self.valid_bullet_trajectory(
                drone.coord, purpose):
            if drone.mothership.distance_to(
                    drone.coord) < safe_mothership_radius:
                safe_mothership_vec = Vector.from_points(
                    drone.mothership.coord, purpose.coord, module=1)
                dist_to_move = round(safe_mothership_radius -
                                     drone.distance_to(drone.mothership) + 2)
                safe_mothership_vec = safe_mothership_vec * dist_to_move
                point_attack = Point(drone.coord.x + safe_mothership_vec.x,
                                     drone.coord.y + safe_mothership_vec.y)
                drone.actions.append(['move', point_attack])
                return
            drone.actions.append(['shoot', purpose])
        else:
            point_attack = self.get_place_for_attack(drone, purpose)
            if point_attack:
                self.remove_occupied_point_attack(drone)
                drone.actions.append(['move', point_attack])
Пример #15
0
def get_point_on_way_to(unit, target, at_distance=None):
    if at_distance is None:
        at_distance = theme.CARGO_TRANSITION_DISTANCE * 0.9
    va = Vector.from_points(unit.coord, target.coord)
    vb = Vector.from_direction(va.direction, at_distance)
    vb.rotate(180.0)
    return Point(unit.x + va.x + vb.x, unit.y + va.y + vb.y)
Пример #16
0
 def on_overlap_with(self, obj_status):
     if not hasattr(obj_status, "damage_taken"):
         return
     # Пролетаем некомандные объекты
     if obj_status.team is None:
         return
     if theme.TEAM_DRONES_FRIENDLY_FIRE:
         # Не наносим урон себе
         if obj_status.id == self._owner.id:
             return
     else:
         # Пролетаем свои объекты
         if obj_status.team == self._owner.team:
             return
     # За премя жизни ни в кого не попали
     if not obj_status.is_alive or not self.is_alive:
         return
     self.__ttl = 0
     self.stop()
     self.state.stop()
     obj_status.damage_taken(theme.PROJECTILE_DAMAGE)
     if self.death_animation is not None:
         self.__attached = self.death_animation(
             projectile=self,
             target=obj_status,
             distance=int(obj_status.distance_to(self) / 2),
             direction=Vector.from_points(obj_status.coord,
                                          self.coord).direction,
             ttl=self.__attached_ttl)
Пример #17
0
    def on_born(self):

        self.born_soldier()
        nearesst_aster = [(self.distance_to(aster), aster) for aster in self.asteroids]
        nearesst_aster.sort(key=lambda x: x[0])
        idx = len(self.headquarters.soldiers) - 1

        if self.have_gun:

            vec = self.headquarters.get_vec_near_mothership(self, self.basa)
            angles = []
            if isinstance(self.role, Turel):
                angles = self.headquarters.angles_turel.copy()
                self.headquarters.angles_turel.remove(angles[0])
            elif isinstance(self.role, Collector):
                angles = self.headquarters.angles_collector.copy()
                self.headquarters.angles_collector.remove(angles[0])

            self.start_angle = angles[0]
            vec.rotate(angles[0])
            point_attack = self.headquarters.get_place_near_mothership(self, vec)
            self.start_point = point_attack
            self.vector = Vector.from_points(self.coord, self.headquarters.center_map, module=1)

            if point_attack:
                self.actions.append(['move_to', point_attack, 1, 1])
        else:
            self.actions.append(["move_to", nearesst_aster[idx][1], 1, 1])

        self.next_action()
Пример #18
0
 def shot(self, target):
     vector_to_target = Vector.from_points(self.coord, target.coord)
     self.turn_to(target)
     if vector_to_target.direction - 2 <= self.direction <= vector_to_target.direction + 2:
         self.gun.shot(target)
     else:
         self.turn_to(target)
Пример #19
0
 def pursue(self, target_coord):
     """Двигаемся немного вперед к цели"""
     vec1 = Vector.from_points(self.coord, target_coord, module=20)
     new_coord = Point(round(int(self.x + vec1.x)),
                       y=round(int(self.y + vec1.y)))
     self.task = (self.move_to, new_coord)
     self.next_action()
Пример #20
0
    def valid_bullet_trajectory(self, point, purpose):
        """
        Проверка, нету ли дронов из своей команды на траектории выстрела из точки point
        :param point: одна из точек на карте из списка полученного в _get_possible_points_attack
        :param purpose: обект, колученный в методе next_purpose
        :return: булевое значение, валидна или нет
        """
        drone = self.unit
        safe_distance = round(drone.radius * 1.2)
        is_valid = 0 < point.x < theme.FIELD_WIDTH and 0 < point.y < theme.FIELD_HEIGHT
        mothership = drone.mothership
        is_valid = is_valid and (mothership.distance_to(purpose) >
                                 mothership.radius)

        for length in range(1, round(point.distance_to(purpose.coord)),
                            round(safe_distance / 2)):
            attack_vec = Vector.from_points(point, purpose.coord, module=1)
            vec_gunshot = attack_vec * length
            point_on_trajectory = Point(point.x + vec_gunshot.x,
                                        point.y + vec_gunshot.y)
            for team_mate in drone.headquarters.drones:
                if not team_mate.is_alive or team_mate is drone:
                    continue
                is_valid = is_valid and (
                    team_mate.distance_to(point_on_trajectory) >=
                    safe_distance)

        return is_valid
Пример #21
0
 def get_distance_from_points(cls, first_point, second_point):
     first_point, second_point = cls.check_on_points_errors(
         first_point, second_point)
     enemy_vector = Vector.from_points(first_point, second_point)
     enemy_distance_to_target = Vector.calc_module(enemy_vector.x,
                                                   enemy_vector.y)
     return enemy_distance_to_target
Пример #22
0
    def _turn_to_purpose(self, drone, purpose):
        """
        Поворот к цели
        :param drone: экземпляр класса OkhotnikovFNDrone
        :param purpose: обект, колученный в методе next_purpose
        """
        if hasattr(purpose, 'is_moving') and purpose.is_moving:
            purpose_vec = Vector.from_direction(direction=purpose.direction,
                                                module=1)
            drone_purpose_vec = Vector.from_points(purpose.coord, drone.coord)

            length = drone_purpose_vec.module if drone_purpose_vec.module > 0 else 1
            _cos = ((purpose_vec.x * drone_purpose_vec.x +
                     purpose_vec.y * drone_purpose_vec.y) /
                    (length * purpose_vec.module))
            coef_b = (PROJECTILE_SPEED**2 - DRONE_SPEED**2)
            coef_d = (2 * DRONE_SPEED * length *
                      _cos)**2 + 4 * coef_b * (length**2)
            coef = round((-2 * DRONE_SPEED * length + coef_d**0.5) /
                         (2 * coef_b) * DRONE_SPEED)
            purpose_vec = purpose_vec * coef
            possible_purpose = Point(purpose.coord.x + purpose_vec.x,
                                     purpose.coord.y + purpose_vec.y)

            drone.actions.append(['turn', possible_purpose])
        else:
            drone.actions.append(['turn', purpose])
Пример #23
0
 def shoot(self, target):
     vec = Vector.from_points(self.coord,
                              target.coord,
                              module=self.attack_range)
     for base in self.scene.motherships:
         if target is base and self.distance_to(base) < 250:
             self.task = (self.change_locate, self.center_map)
             return self.next_action()
         if hasattr(target, 'distance_to') and target.distance_to(
                 base) < 300 and self.distance_to(base) < 300:
             self.task = (self.change_locate, self.center_map)
             return self.next_action()
         if self.distance_to(base) < 150:
             self.task = (self.pursue, target.coord)
             return self.next_action()
     if not self.check_shoot(target, vec):
         return self.next_action()
     if self.distance_to(target.coord) > self.attack_range:
         self.task = (self.pursue, target.coord)
         return self.next_action()
     if self.gun_cooldown:
         self.task = (self.turn_to, target)
         return self.next_action()
     if target.is_alive:
         self.vector = vec
         self.shot_count += 1
         self.gun.shot(target)
     else:
         self.task = (self.change_locate, self.center_map)
     self.next_action()
Пример #24
0
 def fast_turning_to(self, point):
     vector_to_shot = Vector.from_points(self.coord, point)
     point_from_shooting = self.get_near_point(point=point,
                                               x_distance=10**-10)
     self.move_at(point_from_shooting)
     if math.fabs(self.vector.direction - vector_to_shot.direction) < 10:
         return True
Пример #25
0
 def _shoot_to_the_enemy(self):
     """Дрон стреляет"""
     self.drone.turn_to(self.drone.enemy)
     vector = Vector.from_points(self.drone.coord, self.drone.enemy.coord)
     if abs(self.drone.direction - vector.direction) <= 5 and self.drone.checking_the_trajectory_of_the_shot(
             enemy=self.drone.enemy):
         self.drone.gun.shot(self.drone.enemy)
     SivkovDrone.shots_at_enemy += 1
 def create_point_behind_comandor(self):
     """Создание точки между командиром и базой"""
     vec = Vector.from_points(OlshannikovDron.our_commander.coord,
                              self.my_mothership.coord)
     vec.rotate(180)
     self.point_bihind_comandor = Point(
         self.my_mothership.coord.x + vec.x / 3,
         self.my_mothership.coord.y + vec.y / 3)
Пример #27
0
 def has_any_enemy_going_harvest(self):
     if not self._target_point:
         return False
     enemy_drones = [d for d in self.unit.scene.drones if d.team != self.unit.team and d.is_alive and
                     d.distance_to(self._target) < theme.CARGO_TRANSITION_DISTANCE * 4.0 and
                     math.fabs(d.direction - Vector.from_points(
                         d.coord, self._target.coord.copy()
                     ).direction) < (math.pi / 180.0)]  # 1 degree
     return len(enemy_drones) > 0
Пример #28
0
 def get_place_near_mothership(self, soldier):
     center_field = Point(theme.FIELD_WIDTH // 2, theme.FIELD_HEIGHT // 2)
     vec = Vector.from_points(soldier.my_mothership.coord, center_field)
     dist = vec.module
     _koef = 1 / dist
     norm_vec = Vector(vec.x * _koef, vec.y * _koef)
     vec_position = norm_vec * MOTHERSHIP_HEALING_DISTANCE * 0.9
     position = Point(soldier.my_mothership.coord.x + vec_position.x, soldier.my_mothership.coord.y + vec_position.y)
     return position
Пример #29
0
 def check_count_drone_attack(self):
     result = 0
     for d in self.scene.drones:
         if d.team != self.team and d.is_alive and self.distance_to(
                 d) < self.gun.shot_distance + 50:
             vec2 = Vector.from_points(d.coord, self.coord)
             if abs(d.direction - vec2.direction) < 5:
                 result += 1
     return result
Пример #30
0
 def get_place_for_attack(self, soldier, target):
     if isinstance(target, GameObject):
         vec = Vector.from_points(target.coord, soldier.coord)
     elif isinstance(target, Point):
         vec = Vector.from_points(target, soldier.coord)
     else:
         raise Exception("target must be GameObject or Point!".format(target, ))
     dist = vec.module
     _koef = 1 / dist
     norm_vec = Vector(vec.x * _koef, vec.y * _koef)
     vec_gunshot = norm_vec * min(self.unit.gun_range, int(dist))
     purpose = Point(target.coord.x + vec_gunshot.x, target.coord.y + vec_gunshot.y)
     angles = [0, 60, -60, 30, -30, 15, -15, 45, -45]
     random.shuffle(angles)
     for ang in angles:
         place = self.get_place_near(purpose, target, ang)
         if place and self.valide_place(place):
             return place
     return None