Exemplo n.º 1
0
def shooting(agent):
    """"Method that gives the output for the shooting strategy"""
    ball = agent.info.ball
    car = agent.info.my_car
    target = shooting_target(agent)
    agent.drive.target = target
    distance = distance_2d(car.position, target)
    vf = velocity_forward(car)
    dodge_overshoot = distance < (abs(vf) + 500) * 1.5
    agent.drive.speed = get_speed(agent, target)
    agent.drive.step(agent.info.time_delta)
    agent.controls = agent.drive.controls
    if agent.defending:
        agent.step = Step.Defending
    elif should_dodge(agent):
        agent.step = Step.Dodge
        agent.dodge = Dodge(car)
        agent.dodge.duration = 0.1
        agent.dodge.target = ball.position
    elif agent.ball_bouncing and not (abs(ball.velocity[2]) < 100
              and sign(agent.team) * ball.velocity[1] < 0) and get_bounce(agent) is not None:
        agent.step = Step.Catching
        agent.drive.target = ball.position
        agent.drive.speed = 1399
    elif vf < -900 and (not dodge_overshoot or distance < 600):
        agent.step = Step.HalfFlip
        agent.halfflip = HalfFlip(car)
    elif not dodge_overshoot and car.position[2] < 80 and \
            (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and car.boost <= 25):
        # Dodge towards the target for speed
        agent.step = Step.Dodge
        agent.dodge = Dodge(car)
        agent.dodge.duration = 0.1
        agent.dodge.target = target
Exemplo n.º 2
0
    def step(self, dt):
        car = self.car
        target = ground(self.target)

        car_speed = norm(car.velocity)
        time_left = (ground_distance(car, target) -
                     self.finish_distance) / max(car_speed + 500, 1400)
        forward_speed = dot(car.forward(), car.velocity)

        if self.driving and car.on_ground:
            self.action.target_pos = target
            self._time_on_ground += dt

            # check if it's a good idea to dodge, wavedash or halfflip
            if (self._time_on_ground > 0.2 and car.position[2] < 200
                    and angle_to(car, target, forward_speed < 0) < 0.1):
                # if going forward, use a dodge or a wavedash
                if forward_speed > 0:
                    use_boost_instead = self.waste_boost and car.boost > 20

                    if car_speed > 1200 and not use_boost_instead:
                        if time_left > self.DODGE_DURATION:
                            dodge = Dodge(car)
                            dodge.duration = 0.05
                            dodge.direction = vec2(direction(car, target))
                            self.action = dodge
                            self.driving = False

                        elif time_left > self.WAVEDASH_DURATION:
                            wavedash = Wavedash(car)
                            wavedash.direction = vec2(direction(car, target))
                            self.action = wavedash
                            self.driving = False

                # if going backwards, use a halfflip
                elif time_left > self.HALFFLIP_DURATION and car_speed > 800:
                    self.action = HalfFlip(car, self.waste_boost
                                           and time_left > 3)
                    self.driving = False

        self.action.step(dt)
        self.controls = self.action.controls

        # make sure we're not boosting airborne
        if self.driving and not car.on_ground:
            self.controls.boost = False

        # make sure we're not stuck turtling
        if not car.on_ground:
            self.controls.throttle = 1

        if self.action.finished and not self.driving:
            self.driving = True
            self._time_on_ground = 0
            self.action = self.drive
            self.drive.backwards = False

        if ground_distance(car,
                           target) < self.finish_distance and self.driving:
            self.finished = True
Exemplo n.º 3
0
def defending(agent):
    """"Method that gives output for the defending strategy"""
    target = defending_target(agent)
    agent.drive.target = target
    distance = distance_2d(agent.info.my_car.position, target)
    vf = velocity_forward(agent.info.my_car)
    dodge_overshoot = distance < (abs(vf) + 500) * 1.5
    agent.drive.speed = get_speed(agent, target)
    agent.drive.step(agent.info.time_delta)
    agent.controls = agent.drive.controls
    t = time.time()
    can_dodge, simulated_duration, simulated_target = agent.simulate()
    # print(time.time() - t)
    if can_dodge:
        agent.dodge = Dodge(agent.info.my_car)
        agent.turn = AerialTurn(agent.info.my_car)
        agent.dodge.duration = simulated_duration - 0.1
        agent.dodge.target = simulated_target

        agent.dodge.preorientation = look_at(simulated_target, vec3(0, 0, 1))
        agent.timer = 0
        agent.step = Step.Dodge
    if not agent.should_defend():
        agent.step = Step.Shooting
    elif vf < -900 and (not dodge_overshoot or distance < 600):
        agent.step = Step.HalfFlip
        agent.halfflip = HalfFlip(agent.info.my_car)
    elif not dodge_overshoot and agent.info.my_car.position[2] < 80 and \
            (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and agent.info.my_car.boost <= 25):
        # Dodge towards the target for speed
        agent.step = Step.Dodge
        agent.dodge = Dodge(agent.info.my_car)
        agent.dodge.duration = 0.1
        agent.dodge.target = target
Exemplo n.º 4
0
    def step(self, dt):
        if self.phase == 0:
            self.controls.throttle = 1
            self.controls.boost = 1
            if ground_distance(self.car, self.info.ball) < 2950:
                print("entering phase 1")
                self.phase = 1

        if self.phase == 1:
            self.dodge.step(dt)
            self.controls = self.dodge.controls
            if self.dodge.finished and self.car.on_ground:
                print("entering phase 2")
                self.phase = 2
                self.dodge = Dodge(self.car)
                self.dodge.duration = 0.18
                self.dodge.direction = direction(self.car.position,
                                                 self.info.ball.position)

        if self.phase == 2:
            self.drive.step(dt)
            self.controls = self.drive.controls
            if distance(self.car, self.info.ball) < 850:
                print("entering phase 3")
                self.phase = 3

        if self.phase == 3:
            self.dodge.step(dt)
            self.controls = self.dodge.controls

        self.finished = self.info.ball.position[0] != 0 and self.dodge.finished
Exemplo n.º 5
0
def defending(agent):
    """"Method that gives output for the defending strategy"""
    target = defending_target(agent)
    agent.drive.target = target
    distance = distance_2d(agent.info.my_car.location, target)
    vf = velocity_forward(agent.info.my_car)
    dodge_overshoot = distance < (abs(vf) + 500) * 1.5
    agent.drive.speed = get_speed(agent, target)
    agent.drive.step(agent.info.time_delta)
    agent.controls = agent.drive.controls
    if can_dodge(agent, target):
        agent.step = Step.Dodge
        agent.dodge = Dodge(agent.info.my_car)
        agent.dodge.duration = 0.1
        agent.dodge.target = target
    if not agent.defending:
        agent.step = (Step.Catching if agent.ball_bouncing else Step.Shooting)
    elif vf < -900 and (not dodge_overshoot or distance < 600):
        agent.step = Step.HalfFlip
        agent.halfflip = HalfFlip(agent.info.my_car)
    elif not dodge_overshoot and agent.info.my_car.location[2] < 80 and\
            (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and agent.info.my_car.boost <= 25):
        # Dodge towards the target for speed
        agent.step = Step.Dodge
        agent.dodge = Dodge(agent.info.my_car)
        agent.dodge.duration = 0.1
        agent.dodge.target = target
Exemplo n.º 6
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        if self.state == State.RESET:

            self.timer = 0.0

            # put the car in the middle of the field
            car_state = CarState(
                physics=Physics(location=Vector3(0, 0, 18),
                                velocity=Vector3(0, 0, 0),
                                rotation=Rotator(0, 0, 0),
                                angular_velocity=Vector3(0, 0, 0)))

            theta = random.uniform(0, 6.28)
            pos = Vector3(sin(theta) * 1000.0, cos(theta) * 1000.0, 100.0)

            # put the ball somewhere out of the way
            ball_state = BallState(
                physics=Physics(location=pos,
                                velocity=Vector3(0, 0, 0),
                                rotation=Rotator(0, 0, 0),
                                angular_velocity=Vector3(0, 0, 0)))

            self.set_game_state(
                GameState(ball=ball_state, cars={self.game.id: car_state}))

            next_state = State.WAIT

        if self.state == State.WAIT:

            if self.timer > 0.2:
                next_state = State.INITIALIZE

        if self.state == State.INITIALIZE:

            self.action = Dodge(self.game.my_car)
            self.action.duration = 0.1
            self.action.direction = vec2(self.game.ball.location)

            next_state = State.RUNNING

        if self.state == State.RUNNING:

            self.action.step(self.game.time_delta)
            self.controls = self.action.controls

            if self.timer > self.timeout:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls
Exemplo n.º 7
0
class CarryAndFlick(Maneuver):
    """
    Carry the ball on roof, and flick it if an opponent is close or
    if fast enough and facing the target.
    """
    def __init__(self, car: Car, info: GameInfo, target: vec3):
        super().__init__(car)

        self.target = target
        self.info = info

        self.carry = Carry(car, info.ball, target)
        self.flick = Dodge(car)
        self.flick.duration = 0.15
        self.flick.target = target
        self.flicking = False

    def interruptible(self) -> bool:
        return not self.flicking

    def step(self, dt):
        if not self.flicking:
            self.carry.step(dt)
            self.controls = self.carry.controls
            self.finished = self.carry.finished
            car = self.car
            ball = self.info.ball
            
            # check if it's a good idea to flick
            dir_to_target = ground_direction(car, self.target)
            if (
                distance(car, ball) < 150
                and ground_distance(car, ball) < 100
                and dot(car.forward(), dir_to_target) > 0.7
                and norm(car.velocity) > clamp(distance(car, self.target) / 3, 1000, 1700)
                and dot(dir_to_target, ground_direction(car, ball)) > 0.9
            ):
                self.flicking = True
            
            # flick if opponent is close
            for opponent in self.info.get_opponents():
                if (
                    distance(opponent.position + opponent.velocity, car) < max(300.0, norm(opponent.velocity) * 0.5)
                    and dot(opponent.velocity, direction(opponent, self.info.ball)) > 0.5
                ):
                    if distance(car.position, self.info.ball.position) < 200:
                        self.flicking = True
                    else:
                        self.finished = True
        else:
            self.flick.step(dt)
            self.controls = self.flick.controls
            self.finished = self.flick.finished

    def render(self, draw: DrawingTool):
        if not self.flicking:
            self.carry.render(draw)
Exemplo n.º 8
0
 def initialize_agent(self):
     """Initializing all parameters which require the field info"""
     self.my_goal = Goal(self.team, self.get_field_info())
     self.their_goal = Goal(1 - self.team, self.get_field_info())
     init_boostpads(self)
     """Setting all the mechanics to not none"""
     self.drive = Drive(self.info.my_car)
     self.dodge = Dodge(self.info.my_car)
     self.halfflip = HalfFlip(self.info.my_car)
def dodge_simulation(end_condition=None,
                     car=None,
                     hitbox_class=None,
                     dodge=None,
                     ball=None,
                     game_info=None,
                     boost=True):
    '''
    Simulates an RLU dodge until the dodge ends, or one of pass_condition or fail_condtion are met.
    pass_condition means that the dodge does what we wanted.  Returns True and the RLU car state at the end
    fail_condition returns (False, None), meaning the dodge doesn't achieve the desired result.
    '''

    #Copy everything we need and set constants
    time = 0
    dt = 1 / 60
    car_copy = RLU_Car(car)
    dodge_copy = RLU_Dodge(car_copy)
    if dodge.target != None:
        dodge_copy.target = dodge.target
    if dodge.direction != None:
        dodge_copy.direction = dodge.direction
    if dodge.preorientation != None:
        dodge_copy.preorientation = dodge.preorientation
    if dodge.duration != None:
        dodge_copy.duration = dodge.duration
    else:
        dodge_copy.duration = 0
    #Make sure there's time between the jump and the dodge so that we don't just keep holding jump
    if dodge.delay != None:
        dodge_copy.delay = dodge.delay
    else:
        dodge_copy.delay = max(dodge_copy.duration + 2 * dt, 0.05)

    #Adjust for non-octane hitboxes
    box = update_hitbox(car_copy, hitbox_class)

    #Loop until we hit end_condition or the dodge is over.
    while not end_condition(time, box, ball, game_info.team_sign):

        #Update simulations and adjust hitbox again
        time += dt
        dodge_copy.step(dt)
        controls = dodge_copy.controls
        if boost:
            controls.boost = 1
        car_copy.step(controls, dt)
        box = update_hitbox(car_copy, hitbox_class)

        if dodge_copy.finished:
            #If the dodge never triggers condition, give up and move on
            #TODO: give up sooner to save computation time
            return Simulation()

    return Simulation(ball_contact=True, car=car_copy, box=box, time=time)
Exemplo n.º 10
0
    def __init__(self, car: Car, info: GameInfo, target: vec3):
        super().__init__(car)

        self.target = target
        self.info = info

        self.carry = Carry(car, info.ball, target)
        self.flick = Dodge(car)
        self.flick.duration = 0.15
        self.flick.target = target
        self.flicking = False
Exemplo n.º 11
0
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.info = info

        self.drive = Drive(car)
        self.drive.target_speed = 2300

        self.dodge = Dodge(car)
        self.dodge.duration = 0.1
        self.dodge.direction = normalize(info.their_goal)

        self.phase = 0
Exemplo n.º 12
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        if self.state == State.RESET:
            self.timer = 0.0
            self.set_gamestate_straight_moving()
            # self.set_gamestate_angled_stationary()
            # self.set_gamestate_straight_moving_towards()
            next_state = State.WAIT

        if self.state == State.WAIT:

            if self.timer > 0.2:
                next_state = State.INITIALIZE

        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target, self.drive.speed = self.game.ball.location, 2300
            next_state = State.DRIVING

        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.location
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            can_dodge, simulated_duration, simulated_target = self.simulate()
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                print("============")
                print(simulated_duration)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target
                self.timer = 0
                next_state = State.DODGING

        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls
            if self.game.time == packet.game_ball.latest_touch.time_seconds:
                print(self.timer)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls
Exemplo n.º 13
0
class HalfFlip:
    """
    """
    def __init__(self, car: Car, use_boost=False):
        self.car = car
        self.use_boost = use_boost
        self.controls = Input()

        self.dodge = Dodge(car)
        self.dodge.jump_duration = 0.12
        self.dodge.direction = vec2(car.forward() * (-1))

        self.s = 0.95 * sgn(
            dot(self.car.angular_velocity, self.car.up()) + 0.01)

        self.timer = 0.0

        self.finished = False

    def interruptible(self) -> bool:
        return False

    def step(self, dt):

        boost_delay = 0.4
        stall_start = 0.50
        stall_end = 0.70
        timeout = 2.0

        self.dodge.step(dt)
        self.controls = self.dodge.controls

        if stall_start < self.timer < stall_end:
            self.controls.roll = 0.0
            self.controls.pitch = -1.0
            self.controls.yaw = 0.0

        if self.timer > stall_end:
            self.controls.roll = self.s
            self.controls.pitch = -1.0
            self.controls.yaw = self.s

        if self.use_boost and self.timer > boost_delay:
            self.controls.boost = 1
        else:
            self.controls.boost = 0

        self.timer += dt

        self.finished = (self.timer > timeout) or (self.car.on_ground
                                                   and self.timer > 0.5)
Exemplo n.º 14
0
    def step(self, dt):
        car = self.car
        target = ground(self.target)

        car_vel = norm(car.velocity)
        time_left = (distance(car, target) - self.finish_distance) / max(car_vel + 500, 1400)
        vf = dot(car.forward(), car.velocity)

        if self.driving and car.on_ground:
            self.action.target_pos = target
            self._time_on_ground += dt
            
            if self._time_on_ground > 0.2 and car.position[2] < 200 and angle_to(car, target, vf < 0) < 0.1:

                if vf > 0:
                    if car_vel > 1000 and (not self.waste_boost or car.boost < 10):
                        if time_left > self.dodge_duration:
                            dodge = Dodge(car)
                            dodge.duration = 0.05
                            dodge.direction = vec2(direction(car, target))
                            self.action = dodge
                            self.driving = False

                        elif time_left > self.wavedash_duration:
                            wavedash = Wavedash(car)
                            wavedash.direction = vec2(direction(car, target))
                            self.action = wavedash
                            self.driving = False

                elif time_left > self.halflip_duration and car_vel > 800:
                    self.action = HalfFlip(car, self.waste_boost and time_left > 3)
                    self.driving = False
                    

        self.action.step(dt)
        self.controls = self.action.controls

        if self.driving and not car.on_ground:
            self.controls.boost = False

        if self.action.finished and not self.driving:
            self.driving = True
            self._time_on_ground = 0
            self.action = self.drive
            self.drive.backwards = False

        if distance(car, target) < self.finish_distance and self.driving:
            self.finished = True

        if not self.waste_boost and car.boost < 70:
            self.controls.boost = 0
Exemplo n.º 15
0
 def simulate(self):
     ball_prediction = self.get_ball_prediction_struct()
     duration_estimate = math.floor(
         get_time_at_height(self.game.ball.location[2], 0.2) * 10) / 10
     for i in range(6):
         car = Car(self.game.my_car)
         ball = Ball(self.game.ball)
         batmobile = obb()
         batmobile.half_width = vec3(64.4098892211914, 42.335182189941406,
                                     14.697200775146484)
         batmobile.center = car.location + dot(car.rotation,
                                               vec3(9.01, 0, 12.09))
         batmobile.orientation = car.rotation
         dodge = Dodge(car)
         dodge.duration = duration_estimate + i / 60
         dodge.target = ball.location
         for j in range(round(60 * dodge.duration)):
             dodge.target = ball.location
             dodge.step(1 / 60)
             car.step(dodge.controls, 1 / 60)
             prediction_slice = ball_prediction.slices[j]
             physics = prediction_slice.physics
             ball_location = vec3(physics.location.x, physics.location.y,
                                  physics.location.z)
             dodge.target = ball_location
             batmobile.center = car.location + dot(car.rotation,
                                                   vec3(9.01, 0, 12.09))
             batmobile.orientation = car.rotation
             if intersect(sphere(ball_location, 93.15), batmobile) and abs(
                     ball_location[2] - car.location[2]
             ) < 25 and car.location[2] < ball_location[2]:
                 return True, j / 60, ball_location
     return False, None, None
Exemplo n.º 16
0
class DiagonalKickoff(Maneuver):
    '''Dodge forward once to get there faster.'''
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.info = info

        self.drive = Drive(car)
        self.drive.target_speed = 2300

        self.dodge = Dodge(car)
        self.dodge.duration = 0.1
        self.dodge.direction = normalize(info.their_goal)

        self.phase = 0

    def step(self, dt):
        if self.phase == 0:
            self.controls.throttle = 1
            self.controls.boost = 1
            if ground_distance(self.car, self.info.ball) < 2950:
                print("entering phase 1")
                self.phase = 1

        if self.phase == 1:
            self.dodge.step(dt)
            self.controls = self.dodge.controls
            if self.dodge.finished and self.car.on_ground:
                print("entering phase 2")
                self.phase = 2
                self.dodge = Dodge(self.car)
                self.dodge.duration = 0.18
                self.dodge.direction = direction(self.car.position,
                                                 self.info.ball.position)

        if self.phase == 2:
            self.drive.step(dt)
            self.controls = self.drive.controls
            if distance(self.car, self.info.ball) < 850:
                print("entering phase 3")
                self.phase = 3

        if self.phase == 3:
            self.dodge.step(dt)
            self.controls = self.dodge.controls

        self.finished = self.info.ball.position[0] != 0 and self.dodge.finished

    def render(self, draw: DrawingTool):
        pass
Exemplo n.º 17
0
    def __init__(self, car: Car, use_boost=False):
        self.car = car
        self.use_boost = use_boost
        self.controls = Input()

        self.dodge = Dodge(car)
        self.dodge.duration = 0.12
        self.dodge.direction = vec2(car.forward() * (-1))

        self.s = 0.95 * sgn(
            dot(self.car.angular_velocity, self.car.up()) + 0.01)

        self.timer = 0.0

        self.finished = False
Exemplo n.º 18
0
def setup_first_dodge(agent, duration, delay, target, preorientation):
    agent.dodge = Dodge(agent.info.my_car)
    agent.turn = AerialTurn(agent.info.my_car)
    agent.dodge.duration = duration
    agent.dodge.delay = delay
    agent.dodge.target = target
    agent.dodge.preorientation = preorientation
    agent.timer = 0.0
    agent.step = Step.Dodge_1
Exemplo n.º 19
0
class Hypebot(BaseAgent):
    """Main bot class"""
    def __init__(self, name, team, index):
        """Initializing all parameters of the bot"""
        super().__init__(name, team, index)
        Game.set_mode("soccar")
        self.info = Game(index, team)
        self.team = team
        self.index = index
        self.drive = None
        self.dodge = None
        self.halfflip = None
        self.controls = SimpleControllerState()
        self.kickoff = False
        self.prev_kickoff = False
        self.in_front_off_ball = False
        self.conceding = False
        self.kickoff_Start = None
        self.step = Step.Shooting
        self.time = 0
        self.my_goal = None
        self.their_goal = None
        self.teammates = []
        self.has_to_go = False
        self.closest_to_ball = False
        self.defending = False
        self.set_state = False
        self.ball_prediction_np = []

    def initialize_agent(self):
        """Initializing all parameters which require the field info"""
        self.my_goal = Goal(self.team, self.get_field_info())
        self.their_goal = Goal(1 - self.team, self.get_field_info())
        init_boostpads(self)
        """Setting all the mechanics to not none"""
        self.drive = Drive(self.info.my_car)
        self.dodge = Dodge(self.info.my_car)
        self.halfflip = HalfFlip(self.info.my_car)

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        """The main method which receives the packets and outputs the controls"""
        self.info.read_game_information(packet, self.get_field_info())
        self.in_front_off_ball = in_front_off_ball(self.info.my_car.position,
                                                   self.info.ball.position,
                                                   self.my_goal.center)
        update_boostpads(self, packet)
        self.closest_to_ball = self.closest_to_the_ball()
        self.predict()
        self.time += self.info.time_delta
        if self.time > 5 and self.set_state:
            ball_state = BallState(Physics(location=Vector3(0, 5250, 250)))
            game_state = GameState(ball=ball_state)
            self.set_state = False
            self.set_game_state(game_state)
        dtype = [('physics', [('location', '<f4', 3),
                              ('rotation', [('pitch', '<f4'), ('yaw', '<f4'),
                                            ('roll', '<f4')]),
                              ('velocity', '<f4', 3),
                              ('angular_velocity', '<f4', 3)]),
                 ('game_seconds', '<f4')]

        self.ball_prediction_np = np.ctypeslib.as_array(
            self.get_ball_prediction_struct().slices).view(
                dtype)[:self.get_ball_prediction_struct().num_slices]
        self.teammates = []
        for i in range(self.info.num_cars):
            if self.info.cars[i].team == self.team and i != self.index:
                self.teammates.append(i)
        self.time = packet.game_info.seconds_elapsed
        # self.handle_match_comms()
        self.prev_kickoff = self.kickoff
        self.kickoff = packet.game_info.is_kickoff_pause and distance_2d(
            self.info.ball.position, vec3(0, 0, 0)) < 100
        if self.kickoff and not self.prev_kickoff:
            # if not self.close_to_kickoff_spawn():
            #     return
            if len(self.teammates) > 0:
                if self.closest_to_ball:
                    init_kickoff(self)
                    self.has_to_go = True
                else:
                    self.drive.target = get_closest_big_pad(self).location
                    self.drive.speed = 1399
            else:
                init_kickoff(self)
                self.has_to_go = True
        if (self.kickoff or self.step == "Dodge2") and self.has_to_go:
            kick_off(self)
        elif self.kickoff and not self.has_to_go:
            self.drive.step(self.info.time_delta)
            self.controls = self.drive.controls
        else:
            if self.has_to_go:
                self.has_to_go = False
            self.get_controls()
        self.render_string(self.step.name)
        # Make sure there is no variance in kickoff setups
        if not packet.game_info.is_round_active:
            self.controls.steer = 0
        return self.controls

    def predict(self):
        """Method which uses ball prediction to fill in future data"""
        self.bounces = []
        self.ball_bouncing = False
        ball_prediction = self.get_ball_prediction_struct()
        if ball_prediction is not None:
            prev_ang_velocity = normalize(self.info.ball.angular_velocity)
            for i in range(ball_prediction.num_slices):
                prediction_slice = ball_prediction.slices[i]
                physics = prediction_slice.physics
                if physics.location.y * sign(self.team) > 5120:
                    self.conceding = True
                if physics.location.z > 180:
                    self.ball_bouncing = True
                    continue
                current_ang_velocity = normalize(
                    vec3(physics.angular_velocity.x,
                         physics.angular_velocity.y,
                         physics.angular_velocity.z))
                if physics.location.z < 125 and prev_ang_velocity != current_ang_velocity:
                    self.bounces.append(
                        (vec3(physics.location.x, physics.location.y,
                              physics.location.z),
                         prediction_slice.game_seconds - self.time))
                    if len(self.bounces) > 15:
                        return
                prev_ang_velocity = current_ang_velocity

    def closest_to_the_ball(self):
        dist_to_ball = math.inf
        for i in range(len(self.teammates)):
            teammate_car = self.info.cars[self.teammates[i]]
            if distance_2d(teammate_car.position,
                           get_intersect(self, teammate_car)) < dist_to_ball:
                dist_to_ball = distance_2d(teammate_car.position,
                                           get_intersect(self, teammate_car))
        return distance_2d(self.info.my_car.position,
                           get_intersect(self,
                                         self.info.my_car)) <= dist_to_ball

    def get_controls(self):
        """Decides what strategy to uses and gives corresponding output"""
        if self.step == Step.Steer or self.step == Step.Dodge_2 or self.step == Step.Dodge_1 or self.step == Step.Drive:
            print("GETCONTROLS")
            # self.time = 0
            # self.set_state = True
            self.step = Step.Shooting
        if self.step == Step.Shooting:
            target = get_intersect(self, self.info.my_car)
            self.drive.target = target
            self.drive.step(self.info.time_delta)
            self.controls = self.drive.controls
            t = time.time()
            can_dodge, simulated_duration, simulated_target = self.simulate(
                self.their_goal.center)
            # print(time.time() - t)
            if can_dodge:
                self.dodge = Dodge(self.info.my_car)
                self.turn = AerialTurn(self.info.my_car)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.direction = vec2(self.their_goal.center -
                                            simulated_target)

                target = vec3(vec2(self.their_goal.center)) + vec3(
                    0, 0, jeroens_magic_number * simulated_target[2])
                self.dodge.preorientation = look_at(target - simulated_target,
                                                    vec3(0, 0, 1))
                self.step = Step.Dodge
            if self.should_defend():
                self.step = Step.Defending
            elif not self.closest_to_ball or self.in_front_off_ball:
                self.step = Step.Rotating
            elif should_halfflip(self, target):
                self.step = Step.HalfFlip
                self.halfflip = HalfFlip(self.info.my_car)
            elif should_dodge(self, target):
                self.step = Step.Dodge
                self.dodge = Dodge(self.info.my_car)
                self.dodge.target = target
                self.dodge.duration = 0.1
        elif self.step == Step.Rotating:
            target = 0.5 * (self.info.ball.position -
                            self.my_goal.center) + self.my_goal.center
            self.drive.target = target
            self.drive.speed = 1410
            self.drive.step(self.info.time_delta)
            self.controls = self.drive.controls
            in_position = not not_back(self.info.my_car.position,
                                       self.info.ball.position,
                                       self.my_goal.center)
            faster = self.closest_to_ball and in_position
            if len(self.teammates) == 0 and in_position:
                self.step = Step.Shooting
            elif len(self.teammates) == 1:
                teammate = self.info.cars[self.teammates[0]].position
                teammate_out_location = not_back(teammate,
                                                 self.info.ball.position,
                                                 self.my_goal.center)
                if teammate_out_location or faster:
                    self.step = Step.Shooting
            elif len(self.teammates) == 2:
                teammate1 = self.info.cars[self.teammates[0]].position
                teammate2 = self.info.cars[self.teammates[0]].position
                teammate1_out_location = not_back(teammate1,
                                                  self.info.ball.position,
                                                  self.my_goal.center)
                teammate2_out_location = not_back(teammate2,
                                                  self.info.ball.position,
                                                  self.my_goal.center)
                if teammate1_out_location and teammate2_out_location:
                    self.step = Step.Shooting
                elif (teammate1_out_location
                      or teammate2_out_location) and faster or faster:
                    self.step = Step.Shooting
            if self.should_defend():
                self.step = Step.Defending
            elif should_halfflip(self, target):
                self.step = Step.HalfFlip
                self.halfflip = HalfFlip(self.info.my_car)
            elif should_dodge(self, target):
                self.step = Step.Dodge
                self.dodge = Dodge(self.info.my_car)
                self.dodge.target = target
                self.dodge.duration = 0.1

        elif self.step == Step.Defending:
            defending(self)
        elif self.step == Step.Dodge or self.step == Step.HalfFlip:
            halfflipping = self.step == Step.HalfFlip
            if halfflipping:
                self.halfflip.step(self.info.time_delta)
            else:
                self.dodge.step(self.info.time_delta)
            if (self.halfflip.finished if halfflipping else
                    self.dodge.finished) and self.info.my_car.on_ground:
                self.step = Step.Shooting
            else:
                self.controls = (self.halfflip.controls
                                 if halfflipping else self.dodge.controls)
                if not halfflipping:
                    self.controls.boost = False
                self.controls.throttle = velocity_2d(
                    self.info.my_car.velocity) < 500

    def handle_match_comms(self):
        try:
            msg = self.matchcomms.incoming_broadcast.get_nowait()
        except Empty:
            return
        if handle_set_attributes_message(
                msg, self, allowed_keys=['kickoff', 'prev_kickoff']):
            reply_to(self.matchcomms, msg)
        else:
            self.logger.debug('Unhandled message: {msg}')

    def render_string(self, string):
        """Rendering method mainly used to show the current state"""
        self.renderer.begin_rendering('The State')
        if self.step == Step.Dodge_1:
            self.renderer.draw_line_3d(self.info.my_car.position,
                                       self.dodge.target,
                                       self.renderer.black())
        self.renderer.draw_line_3d(self.info.my_car.position,
                                   self.drive.target, self.renderer.blue())
        if self.index == 0:
            self.renderer.draw_string_2d(20, 20, 3, 3, string,
                                         self.renderer.red())
        else:
            self.renderer.draw_string_2d(20, 520, 3, 3, string,
                                         self.renderer.red())
        self.renderer.end_rendering()

    # The miraculous simulate function
    # TODO optimize heavily in case I actually need it
    # Option one: estimate the time for the current height and look at that ball prediction.
    # If its heigher use that unless it gets unreachable and else compare with the lower one.
    # If duration_estimate = 0.8 and the ball is moving up there is not sense in even simulating it.
    # Might even lower it since the higher the duration estimate the longer the simulation takes.
    def simulate(self, global_target=None):
        lol = 0
        # Initialize the ball prediction
        # Estimate the probable duration of the jump and round it down to the floor decimal
        ball_prediction = self.get_ball_prediction_struct()
        if self.info.my_car.boost < 6:
            duration_estimate = math.floor(
                get_time_at_height(self.info.ball.position[2]) * 10) / 10
        else:
            adjacent = norm(
                vec2(self.info.my_car.position - self.info.ball.position))
            opposite = (self.info.ball.position[2] -
                        self.info.my_car.position[2])
            theta = math.atan(opposite / adjacent)
            t = get_time_at_height_boost(self.info.ball.position[2], theta,
                                         self.info.my_car.boost)
            duration_estimate = (math.ceil(t * 10) / 10)
        # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s
        for i in range(6):
            # Copy the car object and reset the values for the hitbox
            car = Car(self.info.my_car)
            # Create a dodge object on the copied car object
            # Direction is from the ball to the enemy goal
            # Duration is estimated duration plus the time added by the for loop
            # preorientation is the rotation matrix from the ball to the goal
            # TODO make it work on both sides
            #  Test with preorientation. Currently it still picks a low duration at a later time meaning it
            #  wont do any of the preorientation.
            dodge = Dodge(car)
            prediction_slice = ball_prediction.slices[round(
                60 * (duration_estimate + i / 60))]
            physics = prediction_slice.physics
            ball_location = vec3(physics.location.x, physics.location.y,
                                 physics.location.z)
            # ball_location = vec3(0, ball_y, ball_z)
            dodge.duration = duration_estimate + i / 60
            if dodge.duration > 1.4:
                break

            if global_target is not None:
                dodge.direction = vec2(global_target - ball_location)
                target = vec3(vec2(global_target)) + vec3(
                    0, 0, jeroens_magic_number * ball_location[2])
                dodge.preorientation = look_at(target - ball_location,
                                               vec3(0, 0, 1))
            else:
                dodge.target = ball_location
                dodge.direction = vec2(ball_location) + vec2(ball_location -
                                                             car.position)
                dodge.preorientation = look_at(ball_location, vec3(0, 0, 1))
            # Loop from now till the end of the duration
            fps = 30
            for j in range(round(fps * dodge.duration)):
                lol = lol + 1
                # Get the ball prediction slice at this time and convert the location to RLU vec3
                prediction_slice = ball_prediction.slices[round(60 * j / fps)]
                physics = prediction_slice.physics
                ball_location = vec3(physics.location.x, physics.location.y,
                                     physics.location.z)
                dodge.step(1 / fps)

                T = dodge.duration - dodge.timer
                if T > 0:
                    if dodge.timer < 0.2:
                        dodge.controls.boost = 1
                        dodge.controls.pitch = 1
                    else:
                        xf = car.position + 0.5 * T * T * vec3(
                            0, 0, -650) + T * car.velocity

                        delta_x = ball_location - xf
                        if angle_between(vec2(car.forward()),
                                         dodge.direction) < 0.3:
                            if norm(delta_x) > 50:
                                dodge.controls.boost = 1
                                dodge.controls.throttle = 0.0
                            else:
                                dodge.controls.boost = 0
                                dodge.controls.throttle = clip(
                                    0.5 * (200 / 3) * T * T, 0.0, 1.0)
                        else:
                            dodge.controls.boost = 0
                            dodge.controls.throttle = 0.0
                else:
                    dodge.controls.boost = 0

                car.step(dodge.controls, 1 / fps)
                succesfull = self.dodge_succesfull(car, ball_location, dodge)
                if succesfull is not None:
                    if succesfull:
                        return True, j / fps, ball_location
                    else:
                        break
        return False, None, None

    def dodge_succesfull(self, car, ball_location, dodge):
        batmobile = obb()
        batmobile.half_width = vec3(64.4098892211914, 42.335182189941406,
                                    14.697200775146484)
        batmobile.center = car.position + dot(car.orientation,
                                              vec3(9.01, 0, 12.09))
        batmobile.orientation = car.orientation
        ball = sphere(ball_location, 93.15)
        b_local = dot(ball.center - batmobile.center, batmobile.orientation)

        closest_local = vec3(
            min(max(b_local[0], -batmobile.half_width[0]),
                batmobile.half_width[0]),
            min(max(b_local[1], -batmobile.half_width[1]),
                batmobile.half_width[1]),
            min(max(b_local[2], -batmobile.half_width[2]),
                batmobile.half_width[2]))

        hit_location = dot(batmobile.orientation,
                           closest_local) + batmobile.center
        if norm(hit_location - ball.center) > ball.radius:
            return None
        # if abs(ball_location[2] - hit_location[2]) < 25 and hit_location[2] < ball_location[2]:
        if abs(ball_location[2] - hit_location[2]) < 25:
            if closest_local[0] > 35 and -12 < closest_local[2] < 12:
                hit_check = True
            else:
                print("local: ", closest_local)
                hit_check = True
        else:
            hit_check = False
        # Seems to work without angle_check. No clue why though
        angle_car_simulation = angle_between(car.orientation,
                                             self.info.my_car.orientation)
        angle_simulation_target = angle_between(car.orientation,
                                                dodge.preorientation)
        angle_check = angle_simulation_target < angle_car_simulation or angle_simulation_target < 0.1
        return hit_check

    def should_defend(self):
        """Method which returns a boolean regarding whether we should defend or not"""
        ball = self.info.ball
        car = self.info.my_car
        car_to_ball = ball.position - car.position
        in_front_of_ball = self.in_front_off_ball
        backline_intersect = line_backline_intersect(self.my_goal.center[1],
                                                     vec2(car.position),
                                                     vec2(car_to_ball))
        return (in_front_of_ball
                and abs(backline_intersect) < 2000) or self.conceding

    def close_to_kickoff_spawn(self):
        blue_one = distance_2d(self.info.my_car.position, vec3(
            -2048, -2560, 18)) < 10
        blue_two = distance_2d(self.info.my_car.position, vec3(
            2048, -2560, 18)) < 10
        blue_three = distance_2d(self.info.my_car.position,
                                 vec3(-256, -3840, 18)) < 10
        blue_four = distance_2d(self.info.my_car.position, vec3(
            256, -3840, 18)) < 10
        blue_five = distance_2d(self.info.my_car.position, vec3(0, -4608,
                                                                18)) < 10
        blue = blue_one or blue_two or blue_three or blue_four or blue_five
        orange_one = distance_2d(self.info.my_car.position,
                                 vec3(-2048, 2560, 18)) < 10
        orange_two = distance_2d(self.info.my_car.position, vec3(
            2048, 2560, 18)) < 10
        orange_three = distance_2d(self.info.my_car.position,
                                   vec3(-256, 3840, 18)) < 10
        orange_four = distance_2d(self.info.my_car.position, vec3(
            256, 3840, 18)) < 10
        orange_five = distance_2d(self.info.my_car.position, vec3(0, 4608,
                                                                  18)) < 10
        orange = orange_one or orange_two or orange_three or orange_four or orange_five
        return orange or blue
Exemplo n.º 20
0
def kick_off(agent):
    ball = agent.info.ball
    car = agent.info.my_car
    t = distance_2d(ball.position, car.position) / 2200
    batmobile_resting = 18.65
    robbies_constant = (ball.position - vec3(0, 0, 92.75 - batmobile_resting) -
                        car.position - car.velocity * t) * 2 * t**-2
    robbies_boost_constant = dot(normalize(xy(
        car.forward())), normalize(
            xy(robbies_constant))) > (0.3 if car.on_ground else 0.1)
    """"Module that performs the kickoffs"""
    if agent.kickoffStart == "Diagonal":
        if agent.step is Step.Drive:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                ball_location = ball.position + vec3(
                    0, -sign(agent.team) * 500, 0)
                target = car.position + 250 * normalize(ball_location -
                                                        car.position)
                agent.drive = Drive(car)
                agent.drive.target = target
                agent.drive.speed = 2400
                agent.step = Step.Drive_1
        if agent.step is Step.Drive_1:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                target = vec3(
                    dot(
                        rotation(
                            math.radians(-sign(agent.info.team) *
                                         sign(car.position[0]) * 60)),
                        vec2(car.forward())) * 10000)
                preorientation = dot(
                    axis_to_rotation(
                        vec3(
                            0, 0,
                            math.radians(-sign(agent.info.team) *
                                         -sign(car.position[0]) * 30))),
                    car.orientation)
                setup_first_dodge(agent, 0.05, 0.3, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.info.time_delta
            if agent.timer > 0.8:
                lerp_var = lerp(
                    normalize(robbies_constant),
                    normalize(ball.position -
                              vec3(0, 0, 92.75 - batmobile_resting) -
                              car.position), 0.8)
                agent.turn.target = look_at(lerp_var, vec3(0, 0, 1))
                agent.turn.step(agent.info.time_delta)
                agent.controls = agent.turn.controls
                if car.on_ground:
                    agent.time = 0
                    agent.set_state = True
                    agent.step = Step.Shooting
            else:
                agent.dodge.step(agent.info.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
    elif agent.kickoffStart == "Center":
        if agent.step is Step.Drive:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                target = vec3(
                    dot(rotation(math.radians(-65)), vec2(car.forward())) *
                    10000)
                preorientation = dot(
                    axis_to_rotation(vec3(0, 0, math.radians(45))),
                    car.orientation)
                setup_first_dodge(agent, 0.05, 0.4, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.info.time_delta
            if agent.timer > 0.8:
                agent.turn.target = look_at(xy(ball.position - car.position),
                                            vec3(0, 0, 1))
                agent.turn.step(agent.info.time_delta)
                agent.controls = agent.turn.controls
                set_steer(agent)
            else:
                agent.dodge.step(agent.info.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
        elif agent.step is Step.Steer:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(car.position, ball.position) < 800:
                agent.step = Step.Dodge_2
                agent.dodge = Dodge(car)
                agent.dodge.duration = 0.075
                agent.dodge.target = ball.position
        elif agent.step is Step.Dodge_2:
            agent.dodge.step(agent.info.time_delta)
            agent.controls = agent.dodge.controls
            if agent.dodge.finished and car.on_ground:
                agent.time = 0
                agent.set_state = True
                agent.step = Step.Shooting
    elif agent.kickoffStart == "offCenter":
        if agent.step is Step.Drive:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(car.position, agent.drive.target) < 650:
                target = vec3(
                    dot(
                        rotation(
                            math.radians(-sign(agent.info.team) *
                                         -sign(car.position[0]) * 100)),
                        vec2(car.forward())) * 10000)
                preorientation = dot(
                    axis_to_rotation(
                        vec3(
                            0, 0,
                            math.radians(-sign(agent.info.team) *
                                         sign(car.position[0]) * 30))),
                    car.orientation)
                print("PYTHON: ", agent.info.my_car.position)
                print(
                    "PYTHON: ",
                    math.radians(-sign(agent.info.team) *
                                 -sign(car.position[0]) * 100))
                setup_first_dodge(agent, 0.05, 0.4, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.info.time_delta
            if agent.timer > 0.8:
                lerp_var = lerp(
                    normalize(robbies_constant),
                    normalize(ball.position -
                              vec3(0, 0, 92.75 - batmobile_resting) -
                              car.position), 0.25)
                agent.turn.target = look_at(lerp_var, vec3(0, 0, 1))
                agent.turn.step(agent.info.time_delta)
                agent.controls = agent.turn.controls
                set_steer(agent)
            else:
                agent.dodge.step(agent.info.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
        elif agent.step is Step.Steer:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(ball.position, car.position) < 800:
                agent.step = Step.Dodge_2
                agent.dodge = Dodge(car)
                agent.dodge.duration = 0.075
                agent.dodge.target = ball.position
        elif agent.step is Step.Dodge_2:
            agent.dodge.step(agent.info.time_delta)
            agent.controls = agent.dodge.controls
            if agent.dodge.finished and car.on_ground:
                agent.time = 0
                agent.set_state = True
                agent.step = Step.Shooting
Exemplo n.º 21
0
    def get_controls(self):
        """Decides what strategy to uses and gives corresponding output"""
        if self.step == Step.Steer or self.step == Step.Dodge_2 or self.step == Step.Dodge_1 or self.step == Step.Drive:
            print("GETCONTROLS")
            # self.time = 0
            # self.set_state = True
            self.step = Step.Shooting
        if self.step == Step.Shooting:
            target = get_intersect(self, self.info.my_car)
            self.drive.target = target
            self.drive.step(self.info.time_delta)
            self.controls = self.drive.controls
            t = time.time()
            can_dodge, simulated_duration, simulated_target = self.simulate(
                self.their_goal.center)
            # print(time.time() - t)
            if can_dodge:
                self.dodge = Dodge(self.info.my_car)
                self.turn = AerialTurn(self.info.my_car)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.direction = vec2(self.their_goal.center -
                                            simulated_target)

                target = vec3(vec2(self.their_goal.center)) + vec3(
                    0, 0, jeroens_magic_number * simulated_target[2])
                self.dodge.preorientation = look_at(target - simulated_target,
                                                    vec3(0, 0, 1))
                self.step = Step.Dodge
            if self.should_defend():
                self.step = Step.Defending
            elif not self.closest_to_ball or self.in_front_off_ball:
                self.step = Step.Rotating
            elif should_halfflip(self, target):
                self.step = Step.HalfFlip
                self.halfflip = HalfFlip(self.info.my_car)
            elif should_dodge(self, target):
                self.step = Step.Dodge
                self.dodge = Dodge(self.info.my_car)
                self.dodge.target = target
                self.dodge.duration = 0.1
        elif self.step == Step.Rotating:
            target = 0.5 * (self.info.ball.position -
                            self.my_goal.center) + self.my_goal.center
            self.drive.target = target
            self.drive.speed = 1410
            self.drive.step(self.info.time_delta)
            self.controls = self.drive.controls
            in_position = not not_back(self.info.my_car.position,
                                       self.info.ball.position,
                                       self.my_goal.center)
            faster = self.closest_to_ball and in_position
            if len(self.teammates) == 0 and in_position:
                self.step = Step.Shooting
            elif len(self.teammates) == 1:
                teammate = self.info.cars[self.teammates[0]].position
                teammate_out_location = not_back(teammate,
                                                 self.info.ball.position,
                                                 self.my_goal.center)
                if teammate_out_location or faster:
                    self.step = Step.Shooting
            elif len(self.teammates) == 2:
                teammate1 = self.info.cars[self.teammates[0]].position
                teammate2 = self.info.cars[self.teammates[0]].position
                teammate1_out_location = not_back(teammate1,
                                                  self.info.ball.position,
                                                  self.my_goal.center)
                teammate2_out_location = not_back(teammate2,
                                                  self.info.ball.position,
                                                  self.my_goal.center)
                if teammate1_out_location and teammate2_out_location:
                    self.step = Step.Shooting
                elif (teammate1_out_location
                      or teammate2_out_location) and faster or faster:
                    self.step = Step.Shooting
            if self.should_defend():
                self.step = Step.Defending
            elif should_halfflip(self, target):
                self.step = Step.HalfFlip
                self.halfflip = HalfFlip(self.info.my_car)
            elif should_dodge(self, target):
                self.step = Step.Dodge
                self.dodge = Dodge(self.info.my_car)
                self.dodge.target = target
                self.dodge.duration = 0.1

        elif self.step == Step.Defending:
            defending(self)
        elif self.step == Step.Dodge or self.step == Step.HalfFlip:
            halfflipping = self.step == Step.HalfFlip
            if halfflipping:
                self.halfflip.step(self.info.time_delta)
            else:
                self.dodge.step(self.info.time_delta)
            if (self.halfflip.finished if halfflipping else
                    self.dodge.finished) and self.info.my_car.on_ground:
                self.step = Step.Shooting
            else:
                self.controls = (self.halfflip.controls
                                 if halfflipping else self.dodge.controls)
                if not halfflipping:
                    self.controls.boost = False
                self.controls.throttle = velocity_2d(
                    self.info.my_car.velocity) < 500
Exemplo n.º 22
0
class MyAgent(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        self.game = Game(index, team)
        self.name = name
        self.controls = SimpleControllerState()

        self.timer = 0.0

        self.drive = Drive(self.game.my_car)
        self.navigator = None
        self.dodge = None
        self.turn = None
        self.state = State.RESET

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        if self.state == State.RESET:
            self.timer = 0.0
            self.set_gamestate_straight_moving()
            # self.set_gamestate_angled_stationary()
            # self.set_gamestate_straight_moving_towards()
            next_state = State.WAIT

        if self.state == State.WAIT:

            if self.timer > 0.2:
                next_state = State.INITIALIZE

        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target, self.drive.speed = self.game.ball.location, 2300
            next_state = State.DRIVING

        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.location
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            can_dodge, simulated_duration, simulated_target = self.simulate()
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                print("============")
                print(simulated_duration)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target
                self.timer = 0
                next_state = State.DODGING

        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls
            if self.game.time == packet.game_ball.latest_touch.time_seconds:
                print(self.timer)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls

    def simulate(self):
        ball_prediction = self.get_ball_prediction_struct()
        duration_estimate = math.floor(
            get_time_at_height(self.game.ball.location[2], 0.2) * 10) / 10
        for i in range(6):
            car = Car(self.game.my_car)
            ball = Ball(self.game.ball)
            batmobile = obb()
            batmobile.half_width = vec3(64.4098892211914, 42.335182189941406,
                                        14.697200775146484)
            batmobile.center = car.location + dot(car.rotation,
                                                  vec3(9.01, 0, 12.09))
            batmobile.orientation = car.rotation
            dodge = Dodge(car)
            dodge.duration = duration_estimate + i / 60
            dodge.target = ball.location
            for j in range(round(60 * dodge.duration)):
                dodge.target = ball.location
                dodge.step(1 / 60)
                car.step(dodge.controls, 1 / 60)
                prediction_slice = ball_prediction.slices[j]
                physics = prediction_slice.physics
                ball_location = vec3(physics.location.x, physics.location.y,
                                     physics.location.z)
                dodge.target = ball_location
                batmobile.center = car.location + dot(car.rotation,
                                                      vec3(9.01, 0, 12.09))
                batmobile.orientation = car.rotation
                if intersect(sphere(ball_location, 93.15), batmobile) and abs(
                        ball_location[2] - car.location[2]
                ) < 25 and car.location[2] < ball_location[2]:
                    return True, j / 60, ball_location
        return False, None, None

    def set_gamestate_straight_moving(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(0, -1000, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 2, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

        ball_state = BallState(
            physics=Physics(location=Vector3(0, 1500, 93),
                            velocity=Vector3(0, random.randint(-250, 800),
                                             random.randint(700, 800)),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_straight_moving_towards(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, 0, 18),
            velocity=Vector3(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        # put the ball in the middle of the field

        ball_state = BallState(physics=Physics(
            location=Vector3(0, 2500, 93),
            velocity=Vector3(0, -250, 700),
            rotation=Rotator(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_angled_stationary(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(-1000, -1500, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 8, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

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

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))
Exemplo n.º 23
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        # Update the game values and set the state
        self.game.read_game_information(packet, self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        # Reset everything
        if self.state == State.RESET:
            self.timer = 0.0
            # self.set_gamestate_straight_moving()
            # self.set_gamestate_straight_moving_towards()
            self.set_state_stationary_angled()
            # self.set_gamestate_angled_stationary()
            # self.set_state_stationary()
            next_state = State.WAIT

        # Wait so everything can settle in, mainly for ball prediction
        if self.state == State.WAIT:
            if self.timer > 0.2:
                next_state = State.INITIALIZE

        # Initialize the drive mechanic
        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target = self.game.ball.position
            self.drive.speed = 1400
            next_state = State.DRIVING

        # Start driving towards the target and check whether a dodge is possible, if so initialize the dodge
        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.position
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            a = time.time()
            target = self.game.my_car.position + 1000000 * (
                self.game.ball.position - self.game.my_car.position)
            can_dodge, simulated_duration, simulated_target = self.simulate()
            print(time.time() - a)
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target

                self.dodge.preorientation = look_at(simulated_target,
                                                    vec3(0, 0, 1))
                self.timer = 0
                next_state = State.DODGING

        # Perform the dodge
        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls

            T = self.dodge.duration - self.dodge.timer
            if T > 0:
                if self.dodge.timer < 0.2:
                    self.controls.boost = 1
                    # self.controls.pitch = 1
                else:
                    xf = self.game.my_car.position + 0.5 * T * T * vec3(
                        0, 0, -650) + T * self.game.my_car.velocity

                    delta_x = self.game.ball.position - xf
                    if angle_between(vec2(self.game.my_car.forward()),
                                     self.dodge.direction) < 0.3:
                        if norm(delta_x) > 50:
                            self.controls.boost = 1
                            self.controls.throttle = 0.0
                        else:
                            self.controls.boost = 0
                            self.controls.throttle = clip(
                                0.5 * (200 / 3) * T * T, 0.0, 1.0)
                    else:
                        self.controls.boost = 0
                        self.controls.throttle = 0.0
            else:
                self.controls.boost = 0

            # Great line
            # if self.game.time == packet.game_ball.latest_touch.time_seconds:
            #     print(self.game.my_car.position)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls
Exemplo n.º 24
0
 def get_controls(self):
     """Decides what strategy to uses and gives corresponding output"""
     self.drive.power_turn = False
     if self.step is Step.Steer or self.step is Step.Drive:
         self.step = Step.Catching
     if self.step is Step.Catching:
         # Enable power turning for catching, since we don't halfflip
         self.drive.power_turn = True
         target = get_bounce(self)
         if target is None:
             self.step = Step.Shooting
         else:
             self.catching.target = target[0]
             self.catching.speed = (distance_2d(self.info.my_car.location,
                                                target[0]) + 50) / target[1]
             self.catching.step(self.info.time_delta)
             self.controls = self.catching.controls
             ball = self.info.ball
             car = self.info.my_car
             if distance_2d(ball.location, car.location) < 150 and 65 < abs(
                     ball.location[2] - car.location[2]) < 127:
                 self.step = Step.Dribbling
                 self.dribble = Dribbling(self.info.my_car, self.info.ball,
                                          self.their_goal)
             if self.defending:
                 self.step = Step.Defending
             ball = self.info.ball
             if abs(ball.velocity[2]) < 100 and sign(self.team) * ball.velocity[1] < 0 and sign(self.team) * \
                     ball.location[1] < 0:
                 self.step = Step.Shooting
     elif self.step is Step.Dribbling:
         self.dribble.step()
         self.controls = self.dribble.controls
         ball = self.info.ball
         car = self.info.my_car
         bot_to_opponent = self.info.cars[
             1 - self.index].location - self.info.my_car.location
         local_bot_to_target = dot(bot_to_opponent,
                                   self.info.my_car.rotation)
         angle_front_to_target = math.atan2(local_bot_to_target[1],
                                            local_bot_to_target[0])
         opponent_is_near = norm(vec2(bot_to_opponent)) < 2000
         opponent_is_in_the_way = math.radians(
             -10) < angle_front_to_target < math.radians(10)
         if not (distance_2d(ball.location, car.location) < 150
                 and 65 < abs(ball.location[2] - car.location[2]) < 127):
             self.step = Step.Catching
         if self.defending:
             self.step = Step.Defending
         if opponent_is_near and opponent_is_in_the_way:
             self.step = Step.Dodge
             self.dodge = Dodge(self.info.my_car)
             self.dodge.duration = 0.25
             self.dodge.target = self.their_goal.center
     elif self.step is Step.Defending:
         defending(self)
     elif self.step in [
             Step.Dodge, Step.Dodge_1, Step.Dodge_2, Step.HalfFlip
     ]:
         halfflipping = self.step is Step.HalfFlip
         if halfflipping:
             self.halfflip.step(self.info.time_delta)
         else:
             self.dodge.step(self.info.time_delta)
         if self.halfflip.finished if halfflipping else self.dodge.finished:
             self.step = Step.Catching
         else:
             self.controls = (self.halfflip.controls
                              if halfflipping else self.dodge.controls)
     elif self.step is Step.Shooting:
         shooting(self)
Exemplo n.º 25
0
    def simulate(self, global_target=None):
        lol = 0
        # Initialize the ball prediction
        # Estimate the probable duration of the jump and round it down to the floor decimal
        ball_prediction = self.get_ball_prediction_struct()
        if self.info.my_car.boost < 6:
            duration_estimate = math.floor(
                get_time_at_height(self.info.ball.position[2]) * 10) / 10
        else:
            adjacent = norm(
                vec2(self.info.my_car.position - self.info.ball.position))
            opposite = (self.info.ball.position[2] -
                        self.info.my_car.position[2])
            theta = math.atan(opposite / adjacent)
            t = get_time_at_height_boost(self.info.ball.position[2], theta,
                                         self.info.my_car.boost)
            duration_estimate = (math.ceil(t * 10) / 10)
        # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s
        for i in range(6):
            # Copy the car object and reset the values for the hitbox
            car = Car(self.info.my_car)
            # Create a dodge object on the copied car object
            # Direction is from the ball to the enemy goal
            # Duration is estimated duration plus the time added by the for loop
            # preorientation is the rotation matrix from the ball to the goal
            # TODO make it work on both sides
            #  Test with preorientation. Currently it still picks a low duration at a later time meaning it
            #  wont do any of the preorientation.
            dodge = Dodge(car)
            prediction_slice = ball_prediction.slices[round(
                60 * (duration_estimate + i / 60))]
            physics = prediction_slice.physics
            ball_location = vec3(physics.location.x, physics.location.y,
                                 physics.location.z)
            # ball_location = vec3(0, ball_y, ball_z)
            dodge.duration = duration_estimate + i / 60
            if dodge.duration > 1.4:
                break

            if global_target is not None:
                dodge.direction = vec2(global_target - ball_location)
                target = vec3(vec2(global_target)) + vec3(
                    0, 0, jeroens_magic_number * ball_location[2])
                dodge.preorientation = look_at(target - ball_location,
                                               vec3(0, 0, 1))
            else:
                dodge.target = ball_location
                dodge.direction = vec2(ball_location) + vec2(ball_location -
                                                             car.position)
                dodge.preorientation = look_at(ball_location, vec3(0, 0, 1))
            # Loop from now till the end of the duration
            fps = 30
            for j in range(round(fps * dodge.duration)):
                lol = lol + 1
                # Get the ball prediction slice at this time and convert the location to RLU vec3
                prediction_slice = ball_prediction.slices[round(60 * j / fps)]
                physics = prediction_slice.physics
                ball_location = vec3(physics.location.x, physics.location.y,
                                     physics.location.z)
                dodge.step(1 / fps)

                T = dodge.duration - dodge.timer
                if T > 0:
                    if dodge.timer < 0.2:
                        dodge.controls.boost = 1
                        dodge.controls.pitch = 1
                    else:
                        xf = car.position + 0.5 * T * T * vec3(
                            0, 0, -650) + T * car.velocity

                        delta_x = ball_location - xf
                        if angle_between(vec2(car.forward()),
                                         dodge.direction) < 0.3:
                            if norm(delta_x) > 50:
                                dodge.controls.boost = 1
                                dodge.controls.throttle = 0.0
                            else:
                                dodge.controls.boost = 0
                                dodge.controls.throttle = clip(
                                    0.5 * (200 / 3) * T * T, 0.0, 1.0)
                        else:
                            dodge.controls.boost = 0
                            dodge.controls.throttle = 0.0
                else:
                    dodge.controls.boost = 0

                car.step(dodge.controls, 1 / fps)
                succesfull = self.dodge_succesfull(car, ball_location, dodge)
                if succesfull is not None:
                    if succesfull:
                        return True, j / fps, ball_location
                    else:
                        break
        return False, None, None
Exemplo n.º 26
0
class Hypebot(BaseAgent):
    """Main bot class"""
    def __init__(self, name, team, index):
        """Initializing all parameters of the bot"""
        super().__init__(name, team, index)
        Game.set_mode("soccar")
        self.info = Game(index, team)
        self.team = team
        self.index = index
        self.defending = False
        self.conceding = False
        self.bounces = []
        self.drive = None
        self.catching = None
        self.dodge = None
        self.halfflip = None
        self.dribble = None
        self.controls = SimpleControllerState()
        self.kickoff = False
        self.prev_kickoff = False
        self.in_front_off_the_ball = False
        self.kickoff_Start = None
        self.step = Step.Catching
        self.time = 0
        self.my_goal = None
        self.their_goal = None
        self.ball_bouncing = False

    def initialize_agent(self):
        """Initializing all parameters which require the field info"""
        self.my_goal = Goal(self.team, self.get_field_info())
        self.their_goal = Goal(1 - self.team, self.get_field_info())
        init_boostpads(self)
        """Setting all the mechanics to not none"""
        self.drive = Drive(self.info.my_car)
        self.catching = Drive(self.info.my_car)
        self.dodge = Dodge(self.info.my_car)
        self.dribble = Dribbling(self.info.my_car, self.info.ball,
                                 self.their_goal)

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        """The main method which receives the packets and outputs the controls"""
        self.time = packet.game_info.seconds_elapsed
        self.info.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        update_boostpads(self, packet)
        self.predict()
        # self.handle_match_comms()
        self.prev_kickoff = self.kickoff
        self.kickoff = packet.game_info.is_kickoff_pause and distance_2d(
            self.info.ball.location, vec3(0, 0, 0)) < 100
        self.defending = self.should_defending()
        if self.kickoff and not self.prev_kickoff:
            # if not self.close_to_kickoff_spawn():
            #     return
            init_kickoff(self)
            self.prev_kickoff = True
            self.drive.kickoff = True
        elif self.kickoff or self.step is Step.Dodge_2:
            kick_off(self)
            self.drive.kickoff = True
        else:
            self.drive.kickoff = False
            self.get_controls()
        self.render_string(self.step.name)
        # Make sure there is no variance in kickoff setups
        if not packet.game_info.is_round_active:
            self.controls.steer = 0
        return self.controls

    def predict(self):
        """Method which uses ball prediction to fill in future data"""
        self.bounces = []
        self.ball_bouncing = False
        ball_prediction = self.get_ball_prediction_struct()
        if ball_prediction is not None:
            prev_ang_velocity = normalize(self.info.ball.angular_velocity)
            for i in range(ball_prediction.num_slices):
                prediction_slice = ball_prediction.slices[i]
                physics = prediction_slice.physics
                if physics.location.y * sign(self.team) > 5120:
                    self.conceding = True
                if physics.location.z > 180:
                    self.ball_bouncing = True
                    continue
                current_ang_velocity = normalize(
                    vec3(physics.angular_velocity.x,
                         physics.angular_velocity.y,
                         physics.angular_velocity.z))
                if physics.location.z < 125 and prev_ang_velocity != current_ang_velocity:
                    self.bounces.append(
                        (vec3(physics.location.x, physics.location.y,
                              physics.location.z),
                         prediction_slice.game_seconds - self.time))
                    if len(self.bounces) > 15: return
                prev_ang_velocity = current_ang_velocity

    def get_controls(self):
        """Decides what strategy to uses and gives corresponding output"""
        self.drive.power_turn = False
        if self.step is Step.Steer or self.step is Step.Drive:
            self.step = Step.Catching
        if self.step is Step.Catching:
            # Enable power turning for catching, since we don't halfflip
            self.drive.power_turn = True
            target = get_bounce(self)
            if target is None:
                self.step = Step.Shooting
            else:
                self.catching.target = target[0]
                self.catching.speed = (distance_2d(self.info.my_car.location,
                                                   target[0]) + 50) / target[1]
                self.catching.step(self.info.time_delta)
                self.controls = self.catching.controls
                ball = self.info.ball
                car = self.info.my_car
                if distance_2d(ball.location, car.location) < 150 and 65 < abs(
                        ball.location[2] - car.location[2]) < 127:
                    self.step = Step.Dribbling
                    self.dribble = Dribbling(self.info.my_car, self.info.ball,
                                             self.their_goal)
                if self.defending:
                    self.step = Step.Defending
                ball = self.info.ball
                if abs(ball.velocity[2]) < 100 and sign(self.team) * ball.velocity[1] < 0 and sign(self.team) * \
                        ball.location[1] < 0:
                    self.step = Step.Shooting
        elif self.step is Step.Dribbling:
            self.dribble.step()
            self.controls = self.dribble.controls
            ball = self.info.ball
            car = self.info.my_car
            bot_to_opponent = self.info.cars[
                1 - self.index].location - self.info.my_car.location
            local_bot_to_target = dot(bot_to_opponent,
                                      self.info.my_car.rotation)
            angle_front_to_target = math.atan2(local_bot_to_target[1],
                                               local_bot_to_target[0])
            opponent_is_near = norm(vec2(bot_to_opponent)) < 2000
            opponent_is_in_the_way = math.radians(
                -10) < angle_front_to_target < math.radians(10)
            if not (distance_2d(ball.location, car.location) < 150
                    and 65 < abs(ball.location[2] - car.location[2]) < 127):
                self.step = Step.Catching
            if self.defending:
                self.step = Step.Defending
            if opponent_is_near and opponent_is_in_the_way:
                self.step = Step.Dodge
                self.dodge = Dodge(self.info.my_car)
                self.dodge.duration = 0.25
                self.dodge.target = self.their_goal.center
        elif self.step is Step.Defending:
            defending(self)
        elif self.step in [
                Step.Dodge, Step.Dodge_1, Step.Dodge_2, Step.HalfFlip
        ]:
            halfflipping = self.step is Step.HalfFlip
            if halfflipping:
                self.halfflip.step(self.info.time_delta)
            else:
                self.dodge.step(self.info.time_delta)
            if self.halfflip.finished if halfflipping else self.dodge.finished:
                self.step = Step.Catching
            else:
                self.controls = (self.halfflip.controls
                                 if halfflipping else self.dodge.controls)
        elif self.step is Step.Shooting:
            shooting(self)

    def handle_match_comms(self):
        try:
            msg = self.matchcomms.incoming_broadcast.get_nowait()
        except Empty:
            return
        if handle_set_attributes_message(
                msg, self, allowed_keys=['kickoff', 'prev_kickoff']):
            reply_to(self.matchcomms, msg)
        else:
            self.logger.debug('Unhandled message: {msg}')

    def render_string(self, string):
        """Rendering method mainly used to show the current state"""
        self.renderer.begin_rendering('The State')
        if self.step is Step.Dodge_1:
            self.renderer.draw_line_3d(self.info.my_car.location,
                                       self.dodge.target,
                                       self.renderer.black())
        self.renderer.draw_line_3d(self.info.my_car.location,
                                   self.drive.target, self.renderer.blue())
        if self.kickoff_Start is None:
            self.renderer.draw_string_2d(20, 20, 3, 3, string,
                                         self.renderer.red())
        else:
            self.renderer.draw_string_2d(20, 20, 3, 3,
                                         string + " " + self.kickoff_Start,
                                         self.renderer.red())
        self.renderer.end_rendering()

    def should_defending(self):
        return False  # Don't.
        """Method which returns a boolean regarding whether we should defend or not"""
        ball = self.info.ball
        car = self.info.my_car
        our_goal = self.my_goal.center
        car_to_ball = ball.location - car.location
        in_front_of_ball = distance_2d(ball.location, our_goal) < distance_2d(
            car.location, our_goal)
        backline_intersect = line_backline_intersect(self.my_goal.center[1],
                                                     vec2(car.location),
                                                     vec2(car_to_ball))
        return (in_front_of_ball
                and abs(backline_intersect) < 2000) or self.conceding

    def close_to_kickoff_spawn(self):
        blue_one = distance_2d(self.info.my_car.location, vec3(
            -2048, -2560, 18)) < 10
        blue_two = distance_2d(self.info.my_car.location, vec3(
            2048, -2560, 18)) < 10
        blue_three = distance_2d(self.info.my_car.location,
                                 vec3(-256, -3840, 18)) < 10
        blue_four = distance_2d(self.info.my_car.location, vec3(
            256, -3840, 18)) < 10
        blue_five = distance_2d(self.info.my_car.location, vec3(0, -4608,
                                                                18)) < 10
        blue = blue_one or blue_two or blue_three or blue_four or blue_five
        orange_one = distance_2d(self.info.my_car.location,
                                 vec3(-2048, 2560, 18)) < 10
        orange_two = distance_2d(self.info.my_car.location, vec3(
            2048, 2560, 18)) < 10
        orange_three = distance_2d(self.info.my_car.location,
                                   vec3(-256, 3840, 18)) < 10
        orange_four = distance_2d(self.info.my_car.location, vec3(
            256, 3840, 18)) < 10
        orange_five = distance_2d(self.info.my_car.location, vec3(0, 4608,
                                                                  18)) < 10
        orange = orange_one or orange_two or orange_three or orange_four or orange_five
        return orange or blue
Exemplo n.º 27
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        if self.state == State.RESET:

            self.timer = 0.0

            # put the car in the middle of the field
            car_state = CarState(physics=Physics(
                location=Vector3(-2000, 0, 18),
                velocity=Vector3(0, 0, 0),
                rotation=Rotator(0, 0, 0),
                angular_velocity=Vector3(0, 0, 0)),
                                 jumped=False,
                                 double_jumped=False)

            # put the ball somewhere out of the way
            ball_state = BallState(
                physics=Physics(location=Vector3(0, 5000, 0),
                                velocity=Vector3(0, 0, 0),
                                rotation=Rotator(0, 0, 0),
                                angular_velocity=Vector3(0, 0, 0)))

            self.set_game_state(
                GameState(ball=ball_state, cars={self.game.id: car_state}))

            next_state = State.WAIT

        if self.state == State.WAIT:

            if self.timer > 0.2:
                next_state = State.INITIALIZE

        if self.state == State.INITIALIZE:

            self.dodge = Dodge(self.game.my_car)
            self.turn = AerialTurn(self.game.my_car)

            f = self.game.my_car.forward()
            l = self.game.my_car.left()
            u = self.game.my_car.up()

            # musty flick
            if self.counter % 3 == 0:
                self.name = "Musty Flick"
                self.dodge.duration = 0.2
                self.dodge.delay = 0.8
                self.dodge.direction = vec2(f)
                self.dodge.preorientation = look_at(-0.1 * f - u, -1.0 * u)

            # diagonal forward dodge
            if self.counter % 3 == 1:
                self.name = "Fast Forward Dodge"
                self.dodge.duration = 0.15
                self.dodge.delay = 0.4
                self.dodge.direction = vec2(1.0, 0.0)
                self.dodge.preorientation = dot(
                    axis_to_rotation(vec3(0, 0, 3)), self.game.my_car.rotation)

            # diagonal twist
            if self.counter % 3 == 2:
                self.name = "Air-Roll Dodge hit"
                self.dodge.duration = 0.15
                self.dodge.delay = 0.5
                self.dodge.direction = vec2(f - 0.3 * l)
                self.dodge.preorientation = dot(
                    self.game.my_car.rotation,
                    axis_to_rotation(vec3(-0.8, -0.4, 0)))

            self.counter += 1

            next_state = State.RUNNING

        if self.state == State.RUNNING:

            if self.timer > 1.2:
                self.turn.target = look_at(xy(self.game.my_car.velocity),
                                           vec3(0, 0, 1))
                self.turn.step(self.game.time_delta)
                self.controls = self.turn.controls

            else:
                self.dodge.step(self.game.time_delta)
                self.controls = self.dodge.controls

            if self.timer > self.timeout:
                next_state = State.RESET

        self.game.my_car.last_input.roll = self.controls.roll
        self.game.my_car.last_input.pitch = self.controls.pitch
        self.game.my_car.last_input.yaw = self.controls.yaw

        self.timer += self.game.time_delta
        self.state = next_state

        if self.name:
            self.renderer.begin_rendering()
            self.renderer.draw_string_2d(50, 50, 6, 6, self.name,
                                         self.renderer.red())
            self.renderer.end_rendering()

        return self.controls
Exemplo n.º 28
0
class MyAgent(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        Game.set_mode("soccar")
        self.game = Game(index, team)
        self.name = name
        self.controls = SimpleControllerState()
        self.timer = 0.0

        self.drive = Drive(self.game.my_car)
        self.dodge = None
        self.turn = None
        self.state = State.RESET

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        # Update the game values and set the state
        self.game.read_game_information(packet, self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        # Reset everything
        if self.state == State.RESET:
            self.timer = 0.0
            # self.set_gamestate_straight_moving()
            # self.set_gamestate_straight_moving_towards()
            self.set_state_stationary_angled()
            # self.set_gamestate_angled_stationary()
            # self.set_state_stationary()
            next_state = State.WAIT

        # Wait so everything can settle in, mainly for ball prediction
        if self.state == State.WAIT:
            if self.timer > 0.2:
                next_state = State.INITIALIZE

        # Initialize the drive mechanic
        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target = self.game.ball.position
            self.drive.speed = 1400
            next_state = State.DRIVING

        # Start driving towards the target and check whether a dodge is possible, if so initialize the dodge
        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.position
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            a = time.time()
            target = self.game.my_car.position + 1000000 * (
                self.game.ball.position - self.game.my_car.position)
            can_dodge, simulated_duration, simulated_target = self.simulate()
            print(time.time() - a)
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target

                self.dodge.preorientation = look_at(simulated_target,
                                                    vec3(0, 0, 1))
                self.timer = 0
                next_state = State.DODGING

        # Perform the dodge
        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls

            T = self.dodge.duration - self.dodge.timer
            if T > 0:
                if self.dodge.timer < 0.2:
                    self.controls.boost = 1
                    # self.controls.pitch = 1
                else:
                    xf = self.game.my_car.position + 0.5 * T * T * vec3(
                        0, 0, -650) + T * self.game.my_car.velocity

                    delta_x = self.game.ball.position - xf
                    if angle_between(vec2(self.game.my_car.forward()),
                                     self.dodge.direction) < 0.3:
                        if norm(delta_x) > 50:
                            self.controls.boost = 1
                            self.controls.throttle = 0.0
                        else:
                            self.controls.boost = 0
                            self.controls.throttle = clip(
                                0.5 * (200 / 3) * T * T, 0.0, 1.0)
                    else:
                        self.controls.boost = 0
                        self.controls.throttle = 0.0
            else:
                self.controls.boost = 0

            # Great line
            # if self.game.time == packet.game_ball.latest_touch.time_seconds:
            #     print(self.game.my_car.position)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls

    # The miraculous simulate function
    # TODO optimize heavily in case I actually need it
    # Option one: estimate the time for the current height and look at that ball prediction.
    # If its heigher use that unless it gets unreachable and else compare with the lower one.
    # If duration_estimate = 0.8 and the ball is moving up there is not sense in even simulating it.
    # Might even lower it since the higher the duration estimate the longer the simulation takes.
    def simulate(self, global_target=None):
        lol = 0
        # Initialize the ball prediction
        # Estimate the probable duration of the jump and round it down to the floor decimal
        ball_prediction = self.get_ball_prediction_struct()
        if self.game.my_car.boost < 6:
            duration_estimate = math.floor(
                get_time_at_height(self.game.ball.position[2]) * 10) / 10
        else:
            adjacent = norm(
                vec2(self.game.my_car.position - self.game.ball.position))
            opposite = (self.game.ball.position[2] -
                        self.game.my_car.position[2])
            theta = math.atan(opposite / adjacent)
            t = get_time_at_height_boost(self.game.ball.position[2], theta,
                                         self.game.my_car.boost)
            duration_estimate = (math.ceil(t * 10) / 10)
        # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s
        for i in range(6):
            # Copy the car object and reset the values for the hitbox
            car = Car(self.game.my_car)
            # Create a dodge object on the copied car object
            # Direction is from the ball to the enemy goal
            # Duration is estimated duration plus the time added by the for loop
            # preorientation is the rotation matrix from the ball to the goal
            # TODO make it work on both sides
            #  Test with preorientation. Currently it still picks a low duration at a later time meaning it
            #  wont do any of the preorientation.
            dodge = Dodge(car)
            prediction_slice = ball_prediction.slices[round(
                60 * (duration_estimate + i / 60))]
            physics = prediction_slice.physics
            ball_location = vec3(physics.location.x, physics.location.y,
                                 physics.location.z)
            # ball_location = vec3(0, ball_y, ball_z)
            dodge.duration = duration_estimate + i / 60
            if dodge.duration > 1.4:
                break

            if global_target is not None:
                dodge.direction = vec2(global_target - ball_location)
                target = vec3(vec2(global_target)) + vec3(
                    0, 0, jeroens_magic_number * ball_location[2])
                dodge.preorientation = look_at(target - ball_location,
                                               vec3(0, 0, 1))
            else:
                dodge.target = ball_location
                dodge.direction = vec2(ball_location) + vec2(ball_location -
                                                             car.position)
                dodge.preorientation = look_at(ball_location, vec3(0, 0, 1))
            # Loop from now till the end of the duration
            fps = 30
            for j in range(round(fps * dodge.duration)):
                lol = lol + 1
                # Get the ball prediction slice at this time and convert the location to RLU vec3
                prediction_slice = ball_prediction.slices[round(60 * j / fps)]
                physics = prediction_slice.physics
                ball_location = vec3(physics.location.x, physics.location.y,
                                     physics.location.z)
                dodge.step(1 / fps)

                T = dodge.duration - dodge.timer
                if T > 0:
                    if dodge.timer < 0.2:
                        dodge.controls.boost = 1
                        dodge.controls.pitch = 1
                    else:
                        xf = car.position + 0.5 * T * T * vec3(
                            0, 0, -650) + T * car.velocity

                        delta_x = ball_location - xf
                        if angle_between(vec2(car.forward()),
                                         dodge.direction) < 0.3:
                            if norm(delta_x) > 50:
                                dodge.controls.boost = 1
                                dodge.controls.throttle = 0.0
                            else:
                                dodge.controls.boost = 0
                                dodge.controls.throttle = clip(
                                    0.5 * (200 / 3) * T * T, 0.0, 1.0)
                        else:
                            dodge.controls.boost = 0
                            dodge.controls.throttle = 0.0
                else:
                    dodge.controls.boost = 0

                car.step(dodge.controls, 1 / fps)
                succesfull = self.dodge_succesfull(car, ball_location, dodge)
                if succesfull is not None:
                    if succesfull:
                        return True, j / fps, ball_location
                    else:
                        break
        return False, None, None

    def dodge_succesfull(self, car, ball_location, dodge):
        batmobile = obb()
        batmobile.half_width = vec3(64.4098892211914, 42.335182189941406,
                                    14.697200775146484)
        batmobile.center = car.position + dot(car.orientation,
                                              vec3(9.01, 0, 12.09))
        batmobile.orientation = car.orientation
        ball = sphere(ball_location, 93.15)
        b_local = dot(ball.center - batmobile.center, batmobile.orientation)

        closest_local = vec3(
            min(max(b_local[0], -batmobile.half_width[0]),
                batmobile.half_width[0]),
            min(max(b_local[1], -batmobile.half_width[1]),
                batmobile.half_width[1]),
            min(max(b_local[2], -batmobile.half_width[2]),
                batmobile.half_width[2]))

        hit_location = dot(batmobile.orientation,
                           closest_local) + batmobile.center
        if norm(hit_location - ball.center) > ball.radius:
            return None
        # if abs(ball_location[2] - hit_location[2]) < 25 and hit_location[2] < ball_location[2]:
        if abs(ball_location[2] - hit_location[2]) < 25:
            if closest_local[0] > 35 and -12 < closest_local[2] < 12:
                hit_check = True
            else:
                print("local: ", closest_local)
                hit_check = True
        else:
            hit_check = False
        # Seems to work without angle_check. No clue why though
        angle_car_simulation = angle_between(car.orientation,
                                             self.game.my_car.orientation)
        angle_simulation_target = angle_between(car.orientation,
                                                dodge.preorientation)
        angle_check = angle_simulation_target < angle_car_simulation or angle_simulation_target < 0.1
        return hit_check

    """" State setting methods for various situations"""

    def set_gamestate_straight_moving(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(0, -1000, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 2, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

        ball_state = BallState(
            physics=Physics(location=Vector3(0, 1500, 93),
                            velocity=Vector3(200, 650, 750),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_straight_moving_towards(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, 0, 18),
            velocity=Vector3(0, 0, 0),
            rotation=Rotator(0, math.pi / 2, 0),
            angular_velocity=Vector3(0, 0, 0),
        ),
                             boost_amount=50)

        # put the ball in the middle of the field

        ball_state = BallState(physics=Physics(
            location=Vector3(0, 2500, 93),
            velocity=Vector3(0, -250, 500),
            rotation=Rotator(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_angled_stationary(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(-1000, -2000, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 8, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

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

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_state_stationary(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, -2500, 18),
            velocity=Vector3(0, 0, 0),
            rotation=Rotator(0, math.pi / 2, 0),
            angular_velocity=Vector3(0, 0, 0),
        ),
                             boost_amount=100)

        # put the ball in the middle of the field
        ball_state = BallState(physics=Physics(
            location=Vector3(0, ball_y, ball_z),
            velocity=Vector3(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_state_stationary_angled(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, -2500, 18),
            velocity=Vector3(0, 0, 0),
            rotation=Rotator(0, math.pi / 2, 0),
            angular_velocity=Vector3(0, 0, 0),
        ),
                             boost_amount=100)

        # put the ball in the middle of the field
        ball_state = BallState(physics=Physics(
            location=Vector3(1500, 0, 93),
            velocity=Vector3(0, 0, 750),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))
Exemplo n.º 29
0
 def initialize_agent(self):
     """Initializing all parameters which require the field info"""
     init_boostpads(self)
     self.drive = Drive(self.game.my_car)
     self.dodge = Dodge(self.game.my_car)
Exemplo n.º 30
0
c.time = 0.0
c.location = vec3(1509.38, -686.19, 17.01)
c.velocity = vec3(-183.501, 1398., 8.321)
c.angular_velocity = vec3(0, 0, 0)
c.rotation = mat3(-0.130158, -0.991493, -0.00117062, 0.991447, -0.130163,
                  0.00948812, -0.00955977, 0.0000743404, 0.999954)
c.dodge_rotation = mat2(-0.130163, -0.991493, 0.991493, -0.130163)

c.on_ground = True
c.jumped = False
c.double_jumped = False
c.jump_timer = -1.0
c.dodge_timer = -1.0

dodge = Dodge(c)
dodge.direction = vec2(-230.03, 463.42)
dodge.duration = 0.1333
dodge.delay = 0.35

f = open("dodge_simulation.csv", "w")
for i in range(300):
    dodge.step(0.008333)
    print(c.time, dodge.controls.jump, dodge.controls.pitch,
          dodge.controls.yaw)
    c.step(dodge.controls, 0.008333)
    f.write(
        f"{c.time}, {c.location[0]}, {c.location[1]}, {c.location[2]}, "
        f"{c.velocity[0]}, {c.velocity[1]}, {c.velocity[2]}, "
        f"{c.angular_velocity[0]}, {c.angular_velocity[1]}, {c.angular_velocity[2]}\n"
    )