def valid_actions(state): valid = [] if state.player.speed < max_speed(state.player.damage): valid.append(Cmd.ACCEL) if state.player.speed > 0: valid.append(Cmd.NOP) valid.append(Cmd.DECEL) if state.player.y > state.map.min_y: valid.append(Cmd.LEFT) if state.player.y < state.map.max_y: valid.append(Cmd.RIGHT) if state.player.lizards > 0: valid.append(Cmd.LIZARD) if state.player.damage > 0: valid.append(Cmd.FIX) if state.player.boosts > 0: if state.player.speed < boost_speed(state.player.damage): valid.append(Cmd.BOOST) if state.player.boost_counter == 1: valid.append(Cmd.BOOST) return valid
def test_boost(self): state = setup_state() state.player.boosts = 1 state.opponent.boosts = 1 cmd = Cmd.BOOST nstate = next_state(state, cmd, cmd) for prev, cur in zip([state.player, state.opponent], [nstate.player, nstate.opponent]): assert cur.y == prev.y assert cur.x - prev.x == Speed.BOOST_SPEED.value assert cur.speed == Speed.BOOST_SPEED.value assert cur.boosts - prev.boosts == -1 assert cur.boosting == True assert cur.boost_counter == 5 # test no damage for i in range(5): pstate = nstate nstate = next_state(nstate, Cmd.NOP, cmd.NOP) for prev, cur in zip([pstate.player, pstate.opponent], [nstate.player, nstate.opponent]): assert cur.boost_counter - prev.boost_counter == -1 if i < 4: assert cur.boosting == True assert cur.speed == Speed.BOOST_SPEED.value else: assert cur.boosting == False assert cur.speed == Speed.MAX_SPEED.value # test with damage state.player.speed = Speed.MIN_SPEED.value state.opponent.speed = Speed.MIN_SPEED.value state.player.damage = 2 state.opponent.damage = 2 nstate = next_state(state, cmd, cmd) for i in range(5): pstate = nstate nstate = next_state(nstate, Cmd.NOP, cmd.NOP) for prev, cur in zip([pstate.player, pstate.opponent], [nstate.player, nstate.opponent]): assert cur.boost_counter - prev.boost_counter == -1 if i < 4: assert cur.boosting == True assert cur.speed == boost_speed(cur.damage) else: assert cur.boosting == False assert cur.speed == max_speed(cur.damage)
def test_boosts(self): state = setup_state() state.player.boosts = 0 assert Cmd.BOOST not in valid_actions(state) state.player.boosts = 1 assert Cmd.BOOST in valid_actions(state) # speed capped at 9, boosting won't help anyway state.player.damage = 1 state.player.speed = Speed.MAX_SPEED.value assert not state.player.boosting assert Cmd.BOOST not in valid_actions(state) # already boosting state.player.boosting = True state.player.boost_counter = 5 state.player.speed = boost_speed(state.player.damage) assert Cmd.BOOST not in valid_actions(state) # already boosting but boost counter equals 1 state.player.boosting = True state.player.boost_counter = 1 state.player.speed = boost_speed(state.player.damage) assert Cmd.BOOST in valid_actions(state)
def process_opp_action(self, trans): # clean map of stuff that wasn't there when the opponent was here if trans.from_state.opponent.x >= trans.from_state.player.x: clean_map(trans.from_state, trans.from_state.opponent.x, trans.to_state.opponent.x) # check if we have lost track of the opponent's damage - if their x # offset or final speed is more than they should be allowed decrease # their damage until their move becomes valid x_off = trans.to_state.opponent.x - trans.from_state.opponent.x if trans.from_state.opponent.y != trans.to_state.opponent.y: x_off += 1 fspeed = trans.to_state.opponent.speed dmg = max(trans.from_state.opponent.damage, 0) while max(x_off, fspeed) > boost_speed(dmg) and dmg > 0: dmg -= 1 trans.from_state.opponent.damage = dmg # get opponent's cmd cmd = calc_opp_cmd(trans.cmd, trans.from_state, trans.to_state) if cmd is None: log.error(f'unable to calculate opponent cmd for {trans.round_num}') trans.from_state.opponent.transfer_mods(trans.to_state.opponent) return # keep track of opponent's mods calc_ns = next_state(trans.from_state, ns_filter(trans.cmd), cmd) opp = trans.to_state.opponent calc_ns.opponent.transfer_mods(opp) opp.lizards = max(opp.lizards, 0) opp.boosts = max(opp.boosts, 0) # remove crashed into cybertrucks if trans.from_state.opponent.x < trans.from_state.player.x: calc_ns.map.update_global_map()
def boost(self): self.speed = boost_speed(self.damage) self.straight()
def test_boost_speed(self): assert boost_speed(0) == Speed.BOOST_SPEED.value for i in range(1, 7): assert boost_speed(i) == max_speed(i)