예제 #1
0
파일: agent.py 프로젝트: robbai/NVDerevo
 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 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)
예제 #3
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