def steer_reactive(P, tp, a, t, sx, infleA, str8ness):
    if abs(a) > .6:
        return steer_centeralign(P, tp, a)
    maxsen = max(t)
    if maxsen > 0 and abs(tp) < .99:
        MaxSensorPos = t.index(maxsen)
        MaxSensorAng = sangsrad[MaxSensorPos]
        sensangF = -.9
        aadj = MaxSensorAng * sensangF
        if maxsen < 40:
            ttp = MaxSensorAng * - P['s2sen'] / maxsen
        else:
            if str8ness < P['str8thresh'] and abs(infleA) > P['ignoreinfleA']:
                ttp = -abs(infleA) / infleA
                aadj = 0
            else:
                ttp = 0
        senslimF = .031
        ttp = snakeoil.clip(ttp, tp - senslimF, tp + senslimF)
    else:
        aadj = a
        if tp:
            ttp = .94 * abs(tp) / tp
        else:
            ttp = 0
    sto = steer_centeralign(P, tp, aadj, ttp)
    return speed_appropriate_steer(P, sto, sx)
def speed_appropriate_steer(P, sto, sx):
    if sx > 0:
        stmax = max(P['sxappropriatest1'] / math.sqrt(sx) - P['sxappropriatest2'],
                    P['safeatanyspeed'])
    else:
        stmax = 1
    return snakeoil.clip(sto, -stmax, stmax)
def traffic_speed_adjustment(os, sx, ts, tsen):
    global opHistory
    if not opHistory:
        opHistory = os
        return 0
    tsa = 0
    mpn = 0
    sn = min(os[17], os[18])
    if sn > tsen[9] and tsen[9] > 0:
        return 0
    if sn < 15:
        sn = min(sn, os[16], os[19])
    if sn < 8:
        sn = min(sn, os[15], os[20])
    sn -= 5
    if sn < 3:
        opHistory = os
        return -ts
    opn = mpn + sn
    mpp = mpn - sx / 180
    sp = min(opHistory[17], opHistory[18])
    if sp < 15:
        sp = min(sp, os[16], os[19])
    if sp < 8:
        sp = min(sn, os[15], os[20])
    sp -= 5
    opHistory = os
    opp = mpp + sp
    osx = (opn - opp) * 180
    osx = snakeoil.clip(osx, 0, 300)
    if osx - sx > 0: return 0
    max_tsa = osx - ts
    max_worry = 80
    full_serious = 20
    if sn > max_worry:
        seriousness = 0
    elif sn < full_serious:
        seriousness = 1
    else:
        seriousness = (max_worry - sn) / (max_worry - full_serious)
    tsa = max_tsa * seriousness
    tsa = snakeoil.clip(tsa, -ts, 0)
    return tsa
def throttle_control(P, ts, sx, sl, sy, ang, steer):
    if ts < 0:
        tooslow = sx - ts
    else:
        okmaxspeed4steer = P['stst'] * (steer ** 2) - P['st'] * steer + P['stC']
        if steer > P['fullstis']:
            ts = P['fullstmaxsx']
        else:
            ts = min(ts, okmaxspeed4steer)
        tooslow = ts - sx
    ao = 2 / (1 + math.exp(-tooslow)) - 1
    ao -= abs(sl) * P['slipdec']
    spincut = P['spincutint'] - P['spincutslp'] * abs(sy)
    spincut = snakeoil.clip(spincut, P['spincutclip'], 1)
    ao *= spincut
    ww = abs(ang) / P['wwlim']
    wwcut = min(ww, .1)
    if ts > 0 and sx > 5:
        ao -= wwcut
    if ao > .8: ao = 1
    return ao
def drive(c, tick):
    S, R, P = c.S.d, c.R.d, c.P
    global target_speed
    global lap
    global prev_distance_from_start
    global learn_final
    global badness
    badness = S['damage'] - badness
    skid = skid_severity(P, S['wheelSpinVel'], S['speedX'])
    if skid > 1:
        badness += 15
    if car_might_be_stuck(S['speedX'], S['angle'], S['trackPos']):
        S['stucktimer'] = (S['stucktimer'] % 400) + 1
        if car_is_stuck(S['speedX'], S['stucktimer'], S['angle'],
                        S['trackPos'], S['track'][9], target_speed):
            badness += 100
            R['brake'] = 0
            if target_speed > 0:
                target_speed = -40
            else:
                target_speed = 40
    else:
        S['stucktimer'] = 0
    if S['z'] > 4:
        badness += 20
    infleX, infleA, straightness = track_sensor_analysis(S['track'], S['angle'])
    if target_speed > 0:
        if c.stage:
            if not S['stucktimer']:
                target_speed = speed_planning(P, S['track'],
                                              S['speedX'], S['speedY'], R['steer'], S['angle'],
                                              infleX, infleA)
            target_speed += jump_speed_adjustment(S['z'])
            if c.stage > 1:
                target_speed += traffic_speed_adjustment(
                    S['opponents'], S['speedX'], target_speed, S['track'])
            target_speed *= damage_speed_adjustment(S['damage'])
        else:
            if lap > 1 and T.usable_model:
                target_speed = speed_planning(P, S['track'],
                                              S['speedX'], S['speedY'], R['steer'], S['angle'],
                                              infleX, infleA)
                target_speed *= damage_speed_adjustment(S['damage'])
            else:
                target_speed = 50
    target_speed = min(target_speed, 333)
    caution = 1
    if T.usable_model:
        snow = T.section_in_now(S['distFromStart'])
        snext = T.section_ahead(S['distFromStart'])
        if snow:
            if snow.badness > 100: caution = .80
            if snow.badness > 1000: caution = .65
            if snow.badness > 10000: caution = .4
            if snext:
                if snow.end - S['distFromStart'] < 200:
                    if snext.badness > 100: caution = .90
                    if snext.badness > 1000: caution = .75
                    if snext.badness > 10000: caution = .5
    target_speed *= caution
    if T.usable_model or c.stage > 1:
        if abs(S['trackPos']) > 1:
            s = steer_centeralign(P, S['trackPos'], S['angle'])
            badness += 1
        else:
            s = steer_reactive(P, S['trackPos'], S['angle'], S['track'],
                               S['speedX'], infleA, straightness)
    else:
        s = steer_centeralign(P, S['trackPos'], S['angle'])
    R['steer'] = s
    if S['stucktimer'] and S['distRaced'] > 20:
        if target_speed < 0:
            R['steer'] = -S['angle']
    if c.stage > 1:
        if target_speed < 0:
            target_speed *= snakeoil.clip(S['opponents'][0] / 20, .1, 1)
            target_speed *= snakeoil.clip(S['opponents'][35] / 20, .1, 1)
        else:
            R['steer'] = speed_appropriate_steer(P,
                                                 traffic_navigation(S['opponents'], R['steer']),
                                                 S['speedX'] + 50)
    if not S['stucktimer']:
        target_speed = abs(target_speed)
    slip = find_slip(S['wheelSpinVel'])
    R['accel'] = throttle_control(P, target_speed, S['speedX'], slip,
                                  S['speedY'], S['angle'], R['steer'])
    if R['accel'] < .01:
        R['brake'] = brake_control(P, R['brake'], S['speedX'], S['speedY'], target_speed, skid)
    else:
        R['brake'] = 0
    R['gear'], R['clutch'] = automatic_transimission(P,
                                                     S['rpm'], S['gear'], R['clutch'], S['rpm'],
                                                     S['speedX'],
                                                     target_speed, tick)
    R['clutch'] = clutch_control(P, R['clutch'], slip, S['speedX'], S['speedY'])
    if S['distRaced'] < S['distFromStart']:
        lap = 0
    if prev_distance_from_start > S['distFromStart'] and abs(S['angle']) < .1:
        lap += 1
    prev_distance_from_start = S['distFromStart']
    if not lap:
        T.laplength = max(S['distFromStart'], T.laplength)
    elif lap == 1 and not T.usable_model:
        learn_track(R['steer'], S['angle'], S['track'], S['distFromStart'])
    elif c.stage == 3:
        pass
    else:
        if not learn_final:
            learn_track_final(T.laplength)
            T.post_process_track()
            learn_final = True
        if T.laplength:
            properlap = S['distRaced'] / T.laplength
        else:
            properlap = 0
        if c.stage == 0 and lap < 4:
            T.record_badness(badness, S['distFromStart'])
    S['targetSpeed'] = target_speed
    target_speed = 70
    badness = S['damage']
    return
def jump_speed_adjustment(z):
    offtheground = snakeoil.clip(z - .350, 0, 1000)
    jsa = offtheground * -800
    return jsa