def count_boosting(player): if player.boosting: player.boost_counter -= 1 # boost ran out if player.boost_counter == 0: player.boosting = False player.speed = max_speed(player.damage)
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_max_speed(self): assert max_speed(0) == Speed.MAX_SPEED.value assert max_speed(1) == Speed.MAX_SPEED.value assert max_speed(2) == Speed.SPEED_3.value assert max_speed(3) == Speed.SPEED_2.value assert max_speed(4) == Speed.SPEED_1.value assert max_speed(5) == Speed.MIN_SPEED.value assert max_speed(6) == Speed.MIN_SPEED.value assert max_speed(10) == Speed.MIN_SPEED.value
def test_accel(self): state = setup_state() assert Cmd.ACCEL in valid_actions(state) state.player.speed = Speed.MAX_SPEED.value assert Cmd.ACCEL not in valid_actions(state) state.player.damage = 2 state.player.speed = max_speed(state.player.damage) assert Cmd.ACCEL not in valid_actions(state)
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 calc_opp_cmd(cmd, from_state, to_state): # no way to know what they were going to do if cmd == Cmd.EMP: return None cmd = ns_filter(cmd) x, y = from_state.opponent.x, from_state.opponent.y # if their boost counter was one their effective speed was actually 9 if from_state.opponent.boost_counter == 1: from_state.opponent.speed = max_speed(from_state.opponent.damage) speed = from_state.opponent.speed fx, fy = to_state.opponent.x, to_state.opponent.y fspeed = to_state.opponent.speed x_off = fx - x y_off = fy - y # go through all the valid actions that they could've taken and check if # the next state matches their actual state for opp_cmd in valid_actions(from_state.switch()): nstate = next_state(from_state, cmd, opp_cmd) if ((nstate.opponent.x, nstate.opponent.y, nstate.opponent.speed) == (fx, fy, fspeed)): return opp_cmd # above didn't work, so try figure out what they did based on some # rudimentary rules if y_off: return Cmd.LEFT if y_off < 0 else Cmd.RIGHT if x_off == y_off == 0 and fspeed == speed: return Cmd.FIX if x_off > speed: if x_off <= next_speed(speed): return Cmd.ACCEL else: return Cmd.BOOST if x_off == prev_speed(speed): return Cmd.DECEL if x_off == speed: _y = fy _speed = speed start_x = x if y_off else x + 1 for _x in range(start_x, fx + 1): block = from_state.map[_x, _y] if block == Block.MUD: _speed = prev_speed(_speed) elif block == Block.OIL_SPILL: _speed = prev_speed(_speed) elif block == Block.WALL: _speed = Speed.SPEED_1.value _speed = max(Speed.SPEED_1.value, _speed) return Cmd.LIZARD if _speed < fspeed else Cmd.NOP return None
def cap_speed(player): if not player.boosting: player.speed = min(max_speed(player.damage), player.speed)
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)