Exemple #1
0
    def reset(self) -> GameState:
        """Reinitialise this scenario when called. Is called upon initialization and when the reset conditions are met.

        :return: The freshly initialized game state for this scenario
        :rtype: GameState, optional
        """
        self.timer = 0.0

        left_or_right = (random.random() > 0.5) * 2 - 1
        x_location = random.uniform(
            *Constants.line_x_side_range
        ) + left_or_right * Constants.line_x_side_offset

        car_pos = Vec3(x_location, random.uniform(*Constants.line_y_range),
                       Constants.car_height)
        ball_pos = Vec3(car_pos.x, car_pos.y + Constants.ball_loc_y_offset,
                        Constants.ball_radius)

        car_state = CarState(physics=Physics(location=car_pos,
                                             velocity=Vector3(0, -100, 0),
                                             rotation=Constants.car_rotation,
                                             angular_velocity=Vector3(0, 0,
                                                                      0)),
                             boost_amount=100)

        ball_state = BallState(
            physics=Physics(location=ball_pos,
                            velocity=Vector3(0, 0, 1),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        return GameState(cars={0: car_state}, ball=ball_state)
Exemple #2
0
    def reset(self) -> GameState:
        """Reinitialise this scenario when called. Is called upon initialization and when the reset conditions are met.

        :return: The freshly initialized game state for this scenario
        :rtype: GameState, optional
        """
        self.timer = 0.0

        car_state = CarState(physics=Physics(
            location=Constants.goal_location.flatten(),
            velocity=Vec3(0, -100, 0),
            rotation=Constants.car_rotation,
            angular_velocity=Vector3(0, 0, 0)),
                             boost_amount=100)

        # Normalize the direction we want the ball to go to, so we can manually define the speed
        ball_state = BallState(
            physics=Physics(location=Vec3(uniform(*Constants.ball_loc_x_range),
                                          uniform(*Constants.ball_loc_y_range),
                                          uniform(
                                              *Constants.ball_loc_z_range)),
                            velocity=Vec3(uniform(*Constants.ball_vel_x_range),
                                          uniform(*Constants.ball_vel_y_range),
                                          uniform(
                                              *Constants.ball_vel_z_range)),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vec3(0, 0, 0)))

        return GameState(cars={0: car_state}, ball=ball_state)
    def _calculate_attack_score(self) -> float:
        # Determine if we are closer to the ball or the opponent
        dist_us = 1.0 * (10**10)
        dist_opp = 1.0 * (10**10)
        ball_pos = Vec3.from_other_vec(self.world.ball.physics.location)
        for car in self.world.teams[self.opp_team].cars:
            vec_to_ball = ball_pos - Vec3.from_other_vec(car.physics.location)
            dist_opp = min(vec_to_ball.magnitude(), dist_opp)
        for car in self.world.teams[self.team].cars:
            vec_to_ball = ball_pos - Vec3.from_other_vec(car.physics.location)
            dist_us = min(vec_to_ball.magnitude(), dist_us)
        enemy_closer = dist_opp < dist_us

        if enemy_closer:
            closer_score = -1
        else:
            closer_score = 1

        # Calculate the ball speed towards the enemy goal and the position of the ball and turn them into a point value
        v_ball_score = -self.world.ball.physics.velocity.y * self.side / InGameConstants.MAX_BALL_VELOCITY
        ball_pos_score = -self.world.ball.physics.location.y * self.side / InGameConstants.MAX_BALL_POSITION

        # Calculate the total score by assigning a specific weight to each of the score values.
        total_score = (closer_score * self.weight_closest +
                       v_ball_score * self.weight_velocity +
                       ball_pos_score * self.weight_position) / (
                           self.weight_closest + self.weight_velocity +
                           self.weight_position)
        return total_score
    def reset(self) -> GameState:
        """Reinitialise this scenario when called. Is called upon initialization and when the reset conditions are met.ç

        :return: The freshly initialized game state for this scenario
        :rtype: GameState, optional
        """
        self.timer = 0.0

        car_pos = Vec3(random.uniform(*Constants.car_loc_x_range),
                       random.uniform(*Constants.car_loc_y_range),
                       Constants.car_loc_z)

        # Creates a vec between the goal location and the car location, to init the ball
        random_range = Constants.goal_car_vec_to_ball_start_location_scale_range
        length_fraction = (
            random_range[0] +
            (random_range[1] - random_range[0]) * random.random())
        ball_pos = (car_pos - Constants.goal_location
                    ) * length_fraction + Constants.goal_location

        car_state = CarState(physics=Physics(location=car_pos,
                                             velocity=Vector3(0, -100, 0),
                                             rotation=Constants.car_rotation,
                                             angular_velocity=Vector3(0, 0,
                                                                      0)),
                             boost_amount=100)

        ball_state = BallState(
            physics=Physics(location=ball_pos + Vec3(0, 0, 40),
                            velocity=Vector3(0, 0, 5),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        return GameState(cars={0: car_state}, ball=ball_state)
Exemple #5
0
    def __init__(self):
        # print("Captain Defense: Started")
        self.team = self.drones[0].team
        self.own_goal_location = Vec3(
            0, self.LENGTH_MAP_ONE_SIDE * side(self.team), 0)

        # Clear the stacks
        for drone in self.drones:
            drone.flush_actions()

        # Closest car to the goal becomes the keeper
        goal_dist = {(Vec3.from_other_vec(car.physics.location) -
                      self.own_goal_location).magnitude(): drone
                     for car, drone in zip(self.world.teams[self.team].cars,
                                           self.drones)}
        self.keeper_drone = goal_dist[min(goal_dist.keys())]
        self.keeper_state = KeeperState.SHADOWING
        self.keeper_drone.assign(Shadowing())

        # Other drones become interceptors
        self.interceptor_drones = [
            drone for drone in self.drones if (drone != self.keeper_drone)
        ]
        self.interceptor_states = {
            drone: InterceptorState.COVER
            for drone in self.interceptor_drones
        }
        [
            drone.assign(Cover(distance_ratio=self.INTERCEPTOR_COVER_RATIO))
            for drone in self.interceptor_drones
        ]
Exemple #6
0
    def _get_target(self, agent: GoslingAgent) -> Optional[Slice]:
        """"Retrieves the interception target"""
        # For predicting the location of the ball for the coming 6 seconds.
        ball_prediction = Ball.get_ball_prediction()
        min_t, max_t = 0, ball_prediction.num_slices / 60  # By default (0, 6) - From RLBOT

        for i in range(min_t,
                       round(max_t * self.GRID_SEARCH_INTERVAL)):  # Grid
            time = i / self.GRID_SEARCH_INTERVAL
            target = ball_prediction.slices[self._time_to_idx(time)]

            # Skip if the target is too high or low!
            if target.physics.location.z > self.MAX_Z_INTERCEPT:
                continue

            offset_angle = Vec3.from_other_vec(
                self._calc_local_diff(agent, Vector3(
                    target.physics.location))).angle_2d(Vec3(x=0, y=1, z=0))
            if degrees(offset_angle) < self.SLICE_ANGLE:
                ball_distance = (agent.me.location -
                                 Vector3(target.physics.location)).magnitude()

                if self._in_range(time, ball_distance,
                                  agent.me.velocity.magnitude()):
                    return target
        return None
Exemple #7
0
    def __init__(self):
        self.team = self.drones[0].team
        self.own_goal_location = Vec3(
            0, self.LENGTH_MAP_ONE_SIDE * side(self.team), 0)
        self.other_goal_location = Vec3(
            0,
            self.LENGTH_MAP_ONE_SIDE * side(self.team) * -1, 0)

        # Clear the stacks
        for drone in self.drones:
            drone.flush_actions()

        drone_closest_to_ball = self._get_teammate_closest_to_ball(
            prefer_friendly_side=True)
        self.attacker_drones = [drone_closest_to_ball]
        self.attacker_states = {drone_closest_to_ball: AttackerState.PREPARE}
        drone_closest_to_ball.assign(Prepare())

        # Select keeper from remaining drones
        remaining_drones = [
            drone for drone in self.drones if (drone != drone_closest_to_ball)
        ]
        if len(remaining_drones) > 0:
            goal_dist = {(Vec3.from_other_vec(drone.car.physics.location) -
                          self.own_goal_location).magnitude(): drone
                         for drone in remaining_drones}
            self.defender_drone = goal_dist[min(goal_dist.keys())]
            self.defender_state = DefenderState.COVER
            self.defender_drone.assign(
                Cover(distance_ratio=self.DEFENDER_COVER_DIST_RATIO))
        else:
            self.defender_drone = None
            self.defender_state = DefenderState.INACTIVE

        # All other drones
        remaining_drones = [
            drone for drone in remaining_drones
            if (drone != self.defender_drone)
        ]
        for idx, drone in enumerate(remaining_drones):
            self.attacker_states[drone] = AttackerState.COVER
            self.attacker_drones.append(drone)
            drone.assign(Cover(distance_ratio=self.ATTACKER_COVER_DIST_RATIO))

        offsets = np.linspace(*self.ATTACKER_PREPARE_OFFSETS,
                              num=len(self.attacker_drones))
        self.attacker_offsets = {
            drone: offset
            for drone, offset in zip(self.attacker_drones, offsets)
        }
Exemple #8
0
    def _detect_bad_shot(self, drone: Drone) -> bool:
        """"Check if our shot is bad"""
        # Can only be False when we are close to the ball
        if (Vec3.from_other_vec(self.world.ball.physics.location) -
                Vec3.from_other_vec(drone.car.physics.location)
            ).magnitude() < self.ATTACKER_CANCEL_CHECK_RANGE:

            # Cancel if we expect to fire to our own goal
            if (self.world.ball.physics.location.y -
                    drone.car.physics.location.y) * side(self.team) > 0:
                # print(f"Bad shot detected. Ball: {self.world.ball.physics.location.y} "
                #       f"Drone: {drone.car.physics.location.y}")
                return True

        return False
    def __init__(self):
        self.state = Status.RUNNING
        self.goal_target = Vec3(0, 5250, 350)

        # Initial role assignment!
        for drone in self.drones:
            drone.assign(Dribble(self.goal_target))
Exemple #10
0
    def _future_intercept_location(self, ball_slice_in_goal: Slice) -> Slice:
        time_of_goal = ball_slice_in_goal.game_seconds
        time_until_goal = time_of_goal - self.agent.time

        # Scaling linear based on ball velocity, 0 = 0.80, 3000 = 0.95
        vel_ball = Vec3.from_other_vec(
            Ball.predict_future_goal().physics.velocity).magnitude()
        factor = (vel_ball - 0) / (3000 - 0) * (
            0.95 - 0.8) + 0.8  # TODO: Imre - Explain please :p
        time_we_intercept = self.agent.time + time_until_goal * factor
        return Ball.find_slice_at_time(time_we_intercept)
class Constants:
    timeout = 4.0  # Time after which the scenario resets
    radia_ball = 92.75  # Radius of the ball
    y_limit_before_reset = 5000

    # Angle at which the ball will be shot to the center of the field
    ball_min_angle = -0.5 * pi * 0.8  # 20 percent to the right of down
    ball_max_angle = (1.0 + 0.5 * 0.8) * pi  # 20 percent to the left of down

    # Ball initialization distance from center of the field
    ball_min_distance = 2000
    ball_max_distance = 4000

    # Ball speed
    ball_min_speed = 500
    ball_max_speed = 2000

    # Car initialization
    location_car = Vec3(0, -2000, 0)
    velocity_car = Vec3(0, -100, 0)
    rotation_car = Rotator(0, 1.57, 0)  # Half pi rad
class Constants:
    timeout = 8.0
    goal_location = Vec3(0, 5250, 600)
    y_limit_before_reset = 5000

    car_rotation = Rotator(0, 1.57, 0)
    car_loc_x_range = [-2000, 2000]
    car_loc_y_range = [-2100, -300]
    car_loc_z = 17.02

    # Fraction between car and goal location to place the ball on
    goal_car_vec_to_ball_start_location_scale_range = [0.75, 0.95]
Exemple #13
0
    def _detect_bad_shot(self, drone: Drone) -> bool:
        """"Check if our shot is bad"""

        # Can only be False when we are close to the ball
        if self.world.calc_dist_to_ball(
                drone.car) < self.INTERCEPTOR_CANCEL_CHECK_RANGE:

            drone_to_ball = (
                Vec3.from_other_vec(self.world.ball.physics.location) -
                Vec3.from_other_vec(drone.car.physics.location)).normalize()

            drone_to_goal = (
                Vec3.from_other_vec(self.own_goal_location) -
                Vec3.from_other_vec(drone.car.physics.location)).normalize()

            # Cancel if we expect to fire to our own goal
            if drone_to_ball * drone_to_goal > self.MINIMUM_DIRECTION_RATIO:
                # print(f"Bad shot detected for drone {drone.index}")
                # print(f"Bad shot detected. Ball: {self.world.ball.physics.location.y} "
                #       f"Drone: {drone.car.physics.location.y}")
                return True

        return False
Exemple #14
0
class Constants:
    timeout = 4.0
    goal_location = Vec3(0, -5250, 600)

    ball_loc_x_range = [-1500, 1500]
    ball_loc_y_range = [-2000, 0]
    ball_loc_z_range = [100, 500]

    ball_vel_x_range = [-500, 500]
    ball_vel_y_range = [-1500, -2500]
    ball_vel_z_range = [-500, -500]

    car_rotation = Rotator(0, 1.57, 0)
    y_limit_before_reset = -5000
Exemple #15
0
    def _keeper_start_check(self) -> bool:
        """"Checks the conditions for the keeper to start"""
        ball_goal_dist = (
            Vec3.from_other_vec(self.world.ball.physics.location) -
            self.own_goal_location).magnitude()

        future_goal_predicted = self._future_goal_is_imminent()
        in_goal_circle = ball_goal_dist < self.START_KEEPER_CIRCLE_RANGE
        on_opposite_corner = self.keeper_drone.car.physics.location.x * self.world.ball.physics.location.x < 1 and \
                             0 < abs(self.world.ball.physics.location.x) < self.START_KEEPER_SIDE_RANGE and \
                             abs(self.own_goal_location.y - self.world.ball.physics.location.y) < \
                             self.START_KEEPER_CIRCLE_RANGE and self.world.ball.physics.location.z < self.JUMP_THRESHOLD

        return future_goal_predicted or in_goal_circle or on_opposite_corner
    def reset(self) -> GameState:
        """Reinitialise this scenario when called. Is called upon initialization and when the reset conditions are met.

        :return: The freshly initialized game state for this scenario
        :rtype: GameState, optional
        """
        self.timer = 0.0

        # Ball random angle from center, with velocity towards center
        angle_ball = uniform(Constants.ball_min_angle,
                             Constants.ball_max_angle)
        distance = uniform(Constants.ball_min_distance,
                           Constants.ball_max_distance)
        speed_ball = uniform(Constants.ball_min_speed,
                             Constants.ball_max_speed)
        # print(f'distance: {distance}, Angle: {angle_ball}, Speed: {speed_ball}')

        # Determine x and y position and velocity from generated random angle
        x_ball, y_ball = distance * cos(angle_ball), distance * sin(angle_ball)
        x_vel_ball, y_vel_ball = speed_ball * -cos(
            angle_ball), speed_ball * -sin(angle_ball)

        ball_state = BallState(physics=Physics(
            location=Vec3(x_ball, y_ball,
                          Constants.radia_ball),  # Always on the ground
            velocity=Vec3(x_vel_ball, y_vel_ball, 0),
            rotation=Rotator(0, 0, 0),
            angular_velocity=Vec3(0, 0, 0)))

        car_state = CarState(physics=Physics(location=Constants.location_car,
                                             velocity=Constants.velocity_car,
                                             rotation=Constants.rotation_car,
                                             angular_velocity=Vector3(0, 0,
                                                                      0)),
                             boost_amount=100)

        return GameState(cars={0: car_state}, ball=ball_state)
class Constants:
    timeout = 5.0
    y_limit_before_reset = -5000
    goal_location = Vec3(0, -5250, 600)

    ball_velocity = 2500
    shot_target_x_range = [-850, 850]
    shot_target_z_range = [1000, 2500]

    car_location = Vector3(0, goal_location.y, 17.02)
    car_rotation = Rotator(0, 1.57, 0)

    ball_loc_x_range = [-2500, 2500]
    ball_loc_y = 0
    ball_loc_z = 500
Exemple #18
0
 def calc_dist_to_ball(self, physics_object):
     return (Vec3.from_other_vec(physics_object.physics.location) - Vec3.from_other_vec(
         self.ball.physics.location)).magnitude()