예제 #1
0
 def test_boundary_speed_more_radius(self):
     obj = GameObject(coord=Point(x=5, y=10), radius=2)
     obj.move_at(target=Point(x=-5, y=10), speed=3)
     for i in range(5):
         self.scene.game_step()
     # 5 - 3 - 3 (выход за границы) + 2 (отталкивание) и стоп
     self.assertEqual(obj.x, 3)
예제 #2
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)
예제 #3
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])
    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)
예제 #5
0
 def on_born(self):
     self.my_team.append(self)
     self.update_all_data()
     max_id = len(self.scene.drones) // self.scene.teams_count
     near_aster = sorted(self.asteroids,
                         key=lambda asteroid: self.distance_to(asteroid))
     near_aster = near_aster[:7]
     vec = Vector.from_direction(self.direction, 250)
     self.first_coord = Point(x=int(self.x + vec.x), y=int(self.y + vec.y))
     coord_1 = [[-100, -100], [100, 100], [-250, -250], [250, 250],
                [-400, -400], [400, 400]]
     coord_2 = [[100, -100], [-100, 100], [250, -250], [-250, 250],
                [400, -400], [-400, 400]]
     if 1 < self.team_number < 4:
         self.optimal_coord = [
             Point(x=int(self.first_coord.x + coord[0]),
                   y=int(self.first_coord.y + coord[1]))
             for coord in coord_1
         ]
     else:
         self.optimal_coord = [
             Point(x=int(self.first_coord.x + coord[0]),
                   y=int(self.first_coord.y + coord[1]))
             for coord in coord_2
         ]
     if self.have_gun:
         self.attack_range = self.gun.shot_distance
         self.move_to_optimal_position()
         return
     elif len(near_aster) >= max_id:
         self.task = (self.move_to, near_aster[self.my_team.index(self)])
         return self.next_action()
     else:
         self.task = (self.move_to, choice(near_aster))
         self.next_action()
예제 #6
0
    def get_prepare_position(self, enemy):
        if self.me.distance_to(enemy) <= self.me.attack_range:
            return self.me.coord
        circle_radius = self.me.attack_range + self.me.radius
        angle_step = 2 * math.degrees(math.asin(
            self.me.radius / circle_radius))
        possible_positions = []  # возможные позиции для атаки по цели
        current_angle = 0
        while current_angle < 360:

            angle_radians = math.radians(current_angle)
            x = math.cos(angle_radians) * circle_radius
            y = math.sin(angle_radians) * circle_radius
            possible_attack_point = Point(enemy.x + x, enemy.y + y)

            if not self.is_collision_with_field_size(possible_attack_point) \
                    and not self.is_collision_with_my_mother_ship(possible_attack_point):
                possible_positions.append(
                    (possible_attack_point,
                     possible_attack_point.distance_to(self.me.mothership)))

            current_angle += angle_step

        if len(possible_positions) >= self.me.priority:
            possible_positions.sort(key=lambda x: x[1])
            return possible_positions[self.me.priority - 1][
                0]  # выбираем позицию, которая ближе к своей базе
        return self.me.get_start_point()
예제 #7
0
    def get_coordinate_for_step(self):
        """
            Создает точки для трех дронов, на которые они перемещаются, когда self.role == FORWARD
        """
        x = self.coord.x
        y = self.coord.y

        if x <= (theme.FIELD_WIDTH - 580):
            new_x1 = x + 40
            new_x2 = new_x1 + 120
            new_x3 = new_x2 + 120
        else:
            new_x1 = theme.FIELD_WIDTH - 570
            new_x2 = theme.FIELD_WIDTH - 640
            new_x3 = theme.FIELD_WIDTH - 710

        if y <= (theme.FIELD_HEIGHT - 580):
            new_y1 = y + 190
            new_y2 = new_y1 + 50
            new_y3 = new_y2 + 50
        else:
            new_y1 = theme.FIELD_HEIGHT - 570
            new_y2 = new_y1 - 640
            new_y3 = new_y2 - 710

        point_1 = Point(new_x1, new_y1)
        point_2 = Point(new_x2, new_y2)
        point_3 = Point(new_x3, new_y3)
        DemintsevDrone.positions_for_attack = [point_1, point_2, point_3]
예제 #8
0
 def get_win_position(self, person, point):
     self.update_army_quantity()
     if self.army_quantity < 5:
         quantity = 5
     else:
         quantity = self.army_quantity
     center_field = Point(theme.FIELD_WIDTH // 2, theme.FIELD_HEIGHT // 2)
     Radius = ((point.x - center_field.x)**2 +
               (point.y - center_field.y)**2)**0.5
     radius = Radius * 0.8
     pfi = [(10 + 20 * i) * 3.14 / 180 for i in range(quantity)]
     win_position = []
     if (person.distance_to(point) > radius and person.distance_to(point) < 1.5*radius) or self.win_position == [] or\
             (person.distance_to(point) < radius and person.distance_to(point) > 0.3*radius):
         for fi in pfi:
             x_circle = radius * cos(fi)
             y_circle = radius * sin(fi)
             if point.x <= theme.FIELD_WIDTH // 2 and point.y <= theme.FIELD_HEIGHT // 2:
                 win_position.append(
                     Point(x=point.x + x_circle, y=point.y + y_circle))
             elif point.x >= theme.FIELD_WIDTH // 2 and point.y <= theme.FIELD_HEIGHT // 2:
                 win_position.append(
                     Point(x=point.x - x_circle, y=point.y + y_circle))
             elif point.x >= theme.FIELD_WIDTH // 2 and point.y >= theme.FIELD_HEIGHT // 2:
                 win_position.append(
                     Point(x=point.x - x_circle, y=point.y - y_circle))
             elif point.x <= theme.FIELD_WIDTH // 2 and point.y >= theme.FIELD_HEIGHT // 2:
                 win_position.append(
                     Point(x=point.x + x_circle, y=point.y - y_circle))
         self.win_position = win_position
예제 #9
0
 def find_the_nearest(self):
     if self.status == "born" or self.status == "change":
         self.check_standers()
         if self.standers <= self.soldiers_count // 2:
             self.check_defenders()
             if self.defenders > 0:
                 self.target_coord_x = (self.coord.x + 150)
                 target_point = Point(x=self.target_coord_x, y=self.coord.y)
                 return target_point
             else:
                 self.target_coord_y = (self.coord.y + 150) * self.standers
                 target_point = Point(x=self.coord.x, y=self.target_coord_y)
                 return target_point
         else:
             self.status = "stay_near_base"
     elif self.status == "go":
         self.sorting_asteroids()
         if not self.distances:
             return False
         else:
             self.target_distance = random.choice(self.distances)
             self.check_asteroids()
             return self.target
     else:
         return False
예제 #10
0
    def on_born(self):
        self.my_team.append(self)
        self.my_number = len(self.my_team)
        if self.my_mothership.coord.x <= 100 and self.my_mothership.coord.y <= 100:
            self.start_destination = Point(
                self.my_mothership.coord.x +
                self.destinations[self.my_number]['x'],
                self.my_mothership.coord.y +
                self.destinations[self.my_number]['y'])
        if self.my_mothership.coord.x <= 100 and self.my_mothership.coord.y > 100:
            self.start_destination = Point(
                self.my_mothership.coord.x +
                self.destinations[self.my_number]['x'],
                self.my_mothership.coord.y -
                self.destinations[self.my_number]['y'])
        if self.my_mothership.coord.x > 100 and self.my_mothership.coord.y <= 100:
            self.start_destination = Point(
                self.my_mothership.coord.x -
                self.destinations[self.my_number]['x'],
                self.my_mothership.coord.y +
                self.destinations[self.my_number]['y'])
        if self.my_mothership.coord.x > 100 and self.my_mothership.coord.y > 100:
            self.start_destination = Point(
                self.my_mothership.coord.x -
                self.destinations[self.my_number]['x'],
                self.my_mothership.coord.y -
                self.destinations[self.my_number]['y'])

        if self.my_number <= 2:
            self.job = Worker(self)
        else:
            self.job = Fighter(self)

        self.job.after_born()
예제 #11
0
 def intercept_asteroid(self):
     """
     Попытка перехватить цель у другого дрона,
     если этот дрон находится ближе к цели.
     """
     distances = {}
     for asteroid in self.unit.__class__.unavailable_asteroids:
         distance = self.unit.distance_to(asteroid)
         for drone in self.unit.teammates:
             if drone.target == asteroid and drone.distance_to(
                     asteroid) > distance:
                 distances[asteroid] = [drone, distance]
     for asteroid, drone_distance_pair in distances.items():
         closest_drone = min(distances.values(), key=lambda x: x[1])
         if drone_distance_pair == closest_drone:
             self.unit.previous_target = Point(self.unit.x, self.unit.y)
             self.unit.__class__.unavailable_asteroids.remove(asteroid)
             self.move_to_the_closest_asteroid()
             coords = Point(drone_distance_pair[0].x,
                            drone_distance_pair[0].y)
             drone_distance_pair[0].previous_target = coords
             drone_distance_pair[0].role.move_to_the_closest_asteroid()
             break
     else:
         raise CantInterceptException
예제 #12
0
    def make_a_step(self,
                    start: Point,
                    destination: Point,
                    ratio: float = 2 / 8) -> Point:
        """
            Возвращает точку в направлении от start до destination
        :param start: Начальная точка
        :param destination: Точка назначения
        :param ratio: Отпределяет в каком отношении точка делит отрезок.
        :return: Точку на отрезке start - destination
        """

        x = (start.x + ratio * destination.x) / (1 + ratio)
        y = (start.y + ratio * destination.y) / (1 + ratio)

        distance = 5 * self.radius

        teammates = [
            teammate for teammate in self.teammates
            if self.point_in_circle(Point(x, y), teammate.coord)
        ]

        if not teammates:
            return Point(x, y)
        else:
            points = self.commander.get_attack_points(center=Point(x, y),
                                                      radius=36,
                                                      size=distance)
            if (points):
                return points[0]
            return Point(x, y)
예제 #13
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
예제 #14
0
 def test_move_at_point(self):
     obj = GameObject(coord=Point(x=10, y=10), direction=180)
     obj.on_stop_at_target = mock.MagicMock()
     obj.move_at(target=Point(x=10, y=20), speed=2)
     for i in range(6):  # TODO почему 6 шагов? проверить и понять
         self.scene.game_step()
     self.assertEqual(obj.y, 20)
     self.scene.game_step()  # событие происходит на след шаге игры
     self.assertEqual(obj.on_stop_at_target.call_count, 1)
예제 #15
0
 def _get_team_pos(self, team_number):
     radius = MotherShip.radius
     if team_number == 0:
         return Point(radius, radius)
     elif team_number == 1:
         return Point(theme.FIELD_WIDTH - radius, radius)
     elif team_number == 2:
         return Point(radius, theme.FIELD_HEIGHT - radius)
     else:
         return Point(theme.FIELD_WIDTH - radius, theme.FIELD_HEIGHT - radius)
예제 #16
0
 def _get_mothership_anchor(self):
     left_anchor = Point(self.formation_size // 2, theme.FIELD_HEIGHT // 2)
     right_anchor = Point(theme.FIELD_WIDTH - self.formation_size // 2,
                          theme.FIELD_HEIGHT // 2)
     if self._get_distance(self.drone.mothership.coord, left_anchor) < \
             self._get_distance(self.drone.mothership.coord, right_anchor):
         central = left_anchor
     else:
         central = right_anchor
     self.anchors[self.drone.id][f'mothership_central'] = central
     self.set_default_formation_anchors(central, 'mothership')
 def get_point_from_self(self, target_to, distance, rotate=0):
     """Создание точки рядом с собой, относительно врага, с определенной дистанции и поворотом"""
     vec = Vector.from_points(self.coord, target_to.coord)
     koef_reduced = self.distance_to(target_to) / distance / 8
     vec.rotate(rotate)
     point = Point(self.coord.x + vec.x / koef_reduced,
                   self.coord.y + vec.y / koef_reduced)
     while self.distance_to(point) < distance:
         point = Point(point.x + vec.x / koef_reduced,
                       point.y + vec.y / koef_reduced)
     return point
예제 #18
0
 def setUp(self):
     self.scene = SpaceField(theme_mod_path='tests.themes.for_cargo_box')
     self.initial_cargo = 50
     self.maximum_cargo = 100
     self.half_load_speed = theme.CARGO_TRANSITION_SPEED // 2
     self.unit1 = CargoBoxVehicle(coord=Point(0, 0),
                                  payload=self.initial_cargo,
                                  max_payload=self.maximum_cargo)
     self.unit2 = CargoBoxVehicle(coord=Point(0, 0),
                                  payload=self.initial_cargo,
                                  max_payload=self.maximum_cargo)
예제 #19
0
 def create_defense_positions(self):
     point = Point(
         self.my_mothership.x +
         (150 * self.mothership_position_coefficients[0]),
         self.my_mothership.y +
         (50 * self.mothership_position_coefficients[1]))
     self.defense_positions.append(point)
     point = Point(
         self.my_mothership.x +
         (50 * self.mothership_position_coefficients[0]),
         self.my_mothership.y +
         (150 * self.mothership_position_coefficients[1]))
     self.defense_positions.append(point)
예제 #20
0
 def get_position_of_angle(self, drone):
     """
     :return: точку возле базы для защиты, в зависимости от угла расположения
     """
     position = Point(
         drone.my_mothership.coord.x + MOTHERSHIP_HEALING_DISTANCE - 1,
         drone.my_mothership.coord.y)
     vec = Vector.from_points(drone.my_mothership.coord, position)
     if drone.angle >= 0:
         vec.rotate(drone.angle)
     position = Point(drone.my_mothership.coord.x + vec.x,
                      drone.my_mothership.coord.y + vec.y)
     return position
예제 #21
0
 def check_shoot(self, target_coord, vec):
     self.update_all_data()
     the_bullet_will_reach = Point(x=int(self.coord.x + vec.x),
                                   y=int(self.coord.y + vec.y))
     for teammate in self.teammates:
         """Генерируем новые координаты где нет союзников"""
         coord_1 = [[60, -60], [-60, 60], [20, -100], [-20, 100], [50, 100],
                    [-50, -100]]
         coord_2 = [[70, -70], [-70, 50], [-70, 100], [50, 100], [-50, 100],
                    [50, -100]]
         new_coord = [
             Point(x=round(int(teammate.coord.x + coord[0])),
                   y=round(int(teammate.coord.y + coord[1])))
             for coord in coord_1
         ]
         new_coord.extend([
             Point(x=round(int(self.coord.x + coord[0])),
                   y=round(int(self.coord.y + coord[1])))
             for coord in coord_2
         ])
         if self.distance_to(target_coord) <= self.distance_to(
                 the_bullet_will_reach):
             """Расчитываем траекторию пули, и проверяем что на ней нет союзников"""
             step_x = (abs(target_coord.x) - abs(self.coord.x)) / 10
             step_y = (abs(target_coord.y) - abs(self.coord.y)) / 10
             coord_trajectory_bullet = [(self.coord.x + step_x * i,
                                         self.coord.y + step_y * i)
                                        for i in range(1, 11)]
             check_traject = any([
                 abs(round(teammate.coord.x - x)) <= 50
                 and abs(round(teammate.coord.y - y)) <= 50
                 and self.distance_to(teammate) >= 50
                 for x, y in coord_trajectory_bullet
             ])
             near_check = (self.distance_to(teammate) -
                           self.radius * 2) < -25 and not teammate.is_moving
             """Смена локации, если стоим близко к союзнику или попадем в союзника пулей"""
             if check_traject or near_check and not self.shot_count:
                 shuffle(new_coord)
                 for coord in new_coord:
                     if all([
                             mate.distance_to(coord) - self.radius * 2 > -25
                             for mate in self.teammates
                     ]):
                         if 0 < coord.x < self.map_field[
                                 0] and 0 < coord.y < self.map_field[1]:
                             self.task = (self.change_locate, coord)
                             return False
                 self.task = (self.change_locate, choice(self.near_aster))
                 return False
     return True
예제 #22
0
 def create_defense_positions(self):
     """создание позиций для обороны"""
     point = Point(
         self.my_mothership.x +
         (150 * self.mothership_position_coefficients[0]),
         self.my_mothership.y +
         (50 * self.mothership_position_coefficients[1]))
     self.defense_positions.append(point)
     point = Point(
         self.my_mothership.x +
         (50 * self.mothership_position_coefficients[0]),
         self.my_mothership.y +
         (150 * self.mothership_position_coefficients[1]))
     self.defense_positions.append(point)
 def locating_shot_gun(self):
     """Метод определяющий место выстрела, что бы стрелять на опережение"""
     new_location_enemy = Point(self.my_target_attack.x,
                                self.my_target_attack.y)
     if self.last_location_enemy:
         vec = Vector.from_points(self.last_location_enemy,
                                  new_location_enemy)
         koef = 0.5
         self.place_shot_gun = Point(self.my_target_attack.x + vec.x * koef,
                                     self.my_target_attack.y + vec.y * koef)
         self.last_location_enemy = new_location_enemy
     else:
         self.last_location_enemy = new_location_enemy
         self.place_shot_gun = self.last_location_enemy
예제 #24
0
    def get_place_for_attack(self,
                             target,
                             params_for_crew=None,
                             dist_to_target=500,
                             dist_to_walls=None):
        if params_for_crew is None:
            params_for_crew = ATTACKER_PARAMS

        for offset in range(5):
            if offset not in [
                    teammate.offset for teammate in self.drone.teammates
                    if teammate.offset is not None and teammate.is_alive
            ]:
                self.drone.offset = offset
                break
        angle_my_mothership_target = self.drone.vector.from_points(
            self.drone.my_mothership.coord, target).direction
        dist_in_crew, angle_in_crew = params_for_crew[self.drone.offset]
        head_drone_x, head_drone_y = Strategy.head_drone[
            'coord'].x, Strategy.head_drone['coord'].y
        if ((head_drone_x, head_drone_y) == (0, 0)
                or self.drone.distance_to(target) >
                DISTATION_FOR_NEW_HEAD_DRONE_PLACE):
            angle = radians(angle_my_mothership_target)
            x = self.drone.my_mothership.coord.x + \
                (self.drone.my_mothership.distance_to(target) - dist_to_target) * cos(angle)
            y = self.drone.my_mothership.coord.y + \
                (self.drone.my_mothership.distance_to(target) - dist_to_target) * sin(angle)

            Strategy.head_drone['coord'] = Point(
                self.check_coord_near_walls(x, theme.FIELD_WIDTH,
                                            dist_to_walls),
                self.check_coord_near_walls(y, theme.FIELD_HEIGHT,
                                            dist_to_walls))
        else:
            x = 0
            y = 0

        if angle_in_crew != 0:
            angle_offset = radians(angle_my_mothership_target + angle_in_crew)
            x = Strategy.head_drone['coord'].x + dist_in_crew * cos(
                angle_offset)
            y = Strategy.head_drone['coord'].y + dist_in_crew * sin(
                angle_offset)

        if self.drone.offset == 0:
            return Strategy.head_drone['coord']
        else:
            return Point(x, y)
예제 #25
0
 def _drunk_shooter(self, enemy):
     """Стреляет не очевидным способом по главному кораблю"""
     enemy_position = get_bases_position(enemy)
     if self.base_position[0] != enemy_position[0]:
         correction_y = SivkovDrone.position_handler.correction_y
         if self.serial_number == 1:
             self.turn_to(Point(enemy.coord.x, enemy.coord.y - correction_y))
         elif self.serial_number == 4:
             self.turn_to(Point(enemy.coord.x, enemy.coord.y + correction_y))
     else:
         correction_x = SivkovDrone.position_handler.correction_x
         if self.serial_number == 2:
             self.turn_to(Point(enemy.coord.x + correction_x, enemy.coord.y))
         elif self.serial_number == 5:
             self.turn_to(Point(enemy.coord.x - correction_x, enemy.coord.y))
예제 #26
0
    def get_turret_points(self):
        """
        Метод создает стартовые точки расстановки дронов

        :return: None

        """
        vec = Vector.from_points(self.my_mothership.coord, self.hq.center_field)
        dir = vec.direction
        angles_set = [dir - 70, dir + 40, dir + 10, dir - 10, dir - 40]

        for angle in angles_set:
            vec_turret = Vector.from_direction(direction=angle, module=MOTHERSHIP_HEALING_DISTANCE * 0.9)
            point_turret = Point(self.my_mothership.coord.x + vec_turret.x, self.my_mothership.coord.y + vec_turret.y)
            self.hq.TURRET_POINTS.append(Point(x=point_turret.x, y=point_turret.y))
예제 #27
0
 def checking_die_enemy_with_elerium(self):
     for drone in self.scene.drones:
         if not drone.is_empty and not drone.is_alive:
             if any([
                     my_drone.current_target == Point(
                         drone.coord.x, drone.coord.y)
                     for my_drone in self.drones
             ]):
                 return False
             else:
                 self.enemy = drone
                 self.current_target = Point(drone.coord.x, drone.coord.y)
                 self.move_to(self.current_target)
             return True
     return False
예제 #28
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
예제 #29
0
    def get_start_point(self):
        step_angle = 15  # начальный угол отклонения для начального разлёта
        game_field_half_x_size = theme.FIELD_WIDTH * 0.5
        game_field_half_y_size = theme.FIELD_HEIGHT * 0.5
        # в зависисости от положения базы, выбираем угол от которого будем разлетаться в полукруг вокруг базы
        if self.mothership.x < game_field_half_x_size and self.mothership.y < game_field_half_y_size:
            start_angle = 0
            start_x = 0
            start_y = 0
        elif self.mothership.x < game_field_half_x_size and self.mothership.y > game_field_half_y_size:
            start_angle = 270
            start_x = 0
            start_y = theme.FIELD_HEIGHT
        elif self.mothership.x > game_field_half_x_size and self.mothership.y < game_field_half_y_size:
            start_angle = 90
            start_x = theme.FIELD_WIDTH
            start_y = 0
        elif self.mothership.x > game_field_half_x_size and self.mothership.y > game_field_half_y_size:
            start_angle = 180
            start_x = theme.FIELD_WIDTH
            start_y = theme.FIELD_HEIGHT

        start_radius = MOTHERSHIP_HEALING_DISTANCE * 1.4
        current_angle_radians = math.radians(self.priority * step_angle +
                                             start_angle)
        x = start_x + math.cos(current_angle_radians) * start_radius
        y = start_y + math.sin(current_angle_radians) * start_radius
        return Point(x, y)
예제 #30
0
 def get_place_near_mothership(self, soldier, vec, koef=0.99):
     dist = vec.module
     _koef = 1 / dist
     norm_vec = Vector(vec.x * _koef, vec.y * _koef)
     vec_position = norm_vec * int(MOTHERSHIP_HEALING_DISTANCE * koef)
     return Point(soldier.coord.x + vec_position.x,
                  soldier.coord.y + vec_position.y)