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)
Exemple #4
0
    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)