コード例 #1
0
def is_outcome_correct_extra_action(test_document):
    gamestate = Gamestate.from_document(test_document["pre_gamestate"])
    expected_gamestate = Gamestate.from_document(test_document["post_gamestate"])

    action = Action.from_document(gamestate.all_units(), test_document["action"])
    outcome = Outcome.from_document(test_document["outcome1"]) if "outcome1" in test_document else None
    gamestate.do_action(action, outcome)

    extra_action = Action.from_document(gamestate.all_units(), test_document["extra_action"])
    outcome = Outcome.from_document(test_document["outcome2"]) if "outcome2" in test_document else None
    gamestate.do_action(extra_action, outcome)

    actual = gamestate.to_document()
    expected = expected_gamestate.to_document()
    return actual == expected
コード例 #2
0
    def select_action(self, gamestate):
        game = self.get_game()
        if not game:
            print("No new data on the server. By the way, our last update was from", self.last_modified)
            # No new data on the server
            return None, None, None
        expected_action = str(gamestate.action_count + 1)

        if game["action_count"] > gamestate.action_count + 1:
            # Several new things happened on the server
            # Handle this one now, but clear last_modified to make
            # sure we hear about the other stuff
            self.last_modified = datetime(1970, 1, 1)

        if game["action_count"] > gamestate.action_count:
            print("received action", document_to_string(game[expected_action]))
            action = Action.from_document(gamestate.all_units(), game[expected_action])
            outcome = None
            if action.is_attack:
                outcome = Outcome.from_document(game[expected_action + "_outcome"])

            upgrade = None
            if expected_action + "_options" in game:
                options = game[expected_action + "_options"]
                if "move_with_attack" in options:
                    action.move_with_attack = bool(options["move_with_attack"])
                if "upgrade" in options:
                    upgrade = get_enum_attributes(options["upgrade"])

            return action, outcome, upgrade

        return None, None, None
コード例 #3
0
def does_action_exist(test_document):
    gamestate = Gamestate.from_document(test_document["gamestate"])
    action = Action.from_document(gamestate.all_units(), test_document["action"])
    available_actions = action_getter.get_actions(gamestate)
    actual = (action in available_actions)
    expected = test_document["result"]
    return give_output(actual, expected)
コード例 #4
0
def is_outcome_correct(test_document):
    gamestate = Gamestate.from_document(test_document["pre_gamestate"])
    expected_gamestate = Gamestate.from_document(test_document["post_gamestate"])
    action = Action.from_document(gamestate.all_units(), test_document["action"])
    outcome = Outcome.from_document(test_document["outcome"]) if "outcome" in test_document else None

    gamestate.set_available_actions()
    gamestate.do_action(action, outcome)

    if not gamestate.is_extra_action():
        action.unit.remove(State.movement_remaining)

    actual = gamestate.to_document()
    expected = expected_gamestate.to_document()
    return give_output(actual, expected)
コード例 #5
0
def validate_action(gamestate, action_document):

    gamestate.set_available_actions()
    available_actions = gamestate.get_actions_including_move_with_attack_none()

    if Position.from_string(
            action_document["start_at"]) not in gamestate.player_units:
        return invalid_action(available_actions, request.json)

    action = Action.from_document(gamestate.all_units(), action_document)

    if not action:
        return invalid_action(available_actions, request.json)

    if not action in available_actions:
        return invalid_action(available_actions, str(action))

    return action
コード例 #6
0
def is_attack_and_defence_correct(test_document):
    gamestate = Gamestate.from_document(test_document["gamestate"])
    action = Action.from_document(gamestate.all_units(), test_document["action"])
    attack = test_document["attack"]
    defence = test_document["defence"]

    gamestate.set_available_actions()
    action.unit = gamestate.player_units[action.start_at]
    gamestate.move_unit(action.start_at, action.end_at)

    actual_attack = battle.get_attack(action, gamestate)
    actual_defence = battle.get_defence(action, actual_attack, gamestate)

    if attack == actual_attack and defence == actual_defence:
        return True
    else:
        print("actual and expected attack:", actual_attack, attack)
        print("actual and expected defence:", actual_defence, defence)
        return False
コード例 #7
0
    def from_log_document(cls,
                          log_document,
                          player_intelligence=Intelligence.Human,
                          opponent_intelligence=Intelligence.Human,
                          player_profile=None):

        initial_gamestate_document = log_document["initial_gamestate"]
        gamestate = Gamestate.from_document(initial_gamestate_document)
        if "player1" in log_document:
            player1 = Player.from_document(log_document["player1"])
            player2 = Player.from_document(log_document["player2"])
        else:
            player1 = Player("Green", player_intelligence)
            player2 = Player("Red", opponent_intelligence)

        if player_profile:
            if player1.profile == player_profile:
                player2.intelligence = player2.ai = Intelligence.Network
            elif player2.profile == player_profile:
                player1.intelligence = player1.ai = Intelligence.Network
            else:
                print(player_profile, "is not playing this game.")
                print("The players are:", player1.profile, "and",
                      player2.profile)
                return

        if "created_at" in log_document:
            created_at = log_document["created_at"]
        else:
            created_at = None

        game = cls([player1, player2], gamestate, created_at)
        game.gamestate = gamestate

        action_count = int(log_document["action_count"])

        game.actions = {}
        game.outcomes = {}

        for action_number in range(1, action_count + 1):
            if game.is_turn_done():
                game.shift_turn()

            game.gamestate.set_available_actions()

            action_document = log_document[str(action_number)]

            action = Action.from_document(gamestate.all_units(),
                                          action_document)

            game.actions[str(action_number)] = action

            options = None
            if str(action_number) + "_options" in log_document:
                options = log_document[str(action_number) + "_options"]

            game.options[str(action_number)] = options

            outcome = None
            outcome_document = None
            if action.has_outcome:
                outcome_document = log_document[str(action_number) +
                                                "_outcome"]
                outcome = Outcome.from_document(outcome_document)
                if options and "move_with_attack" in options:
                    action.move_with_attack = bool(options["move_with_attack"])

            game.outcomes[str(action_number)] = outcome_document

            game.do_action(action, outcome)

            if options and "upgrade" in options:
                upgrade = get_enum_attributes(options["upgrade"])

                position = action.end_at
                if not position in game.gamestate.player_units:
                    position = action.target_at

                upgraded_unit = action.unit.get_upgraded_unit_from_upgrade(
                    upgrade)
                game.gamestate.player_units[position] = upgraded_unit

        if game.is_turn_done():
            game.shift_turn()

        return game
コード例 #8
0
 def get_actions_including_pass_extra(self, positions=None):
     actions = filter_actions(self.available_actions, positions)
     if self.is_extra_action():
         for position, unit in self.player_units.items():
             actions.add(Action(self.player_units, position, position))
     return actions
コード例 #9
0
def do_action(gamestate, action, outcome):
    def settle_ability():
        ability = action.ability
        level = unit.get(action.ability)

        if ability == Ability.bribe:
            target_unit.set(Effect.bribed, duration=1)
            gamestate.change_unit_owner(target_at)

        elif ability == Ability.assassinate:
            rolls = outcome.for_position(action.target_at)
            if battle.assassin_kills_target(rolls, level):
                gamestate.delete_unit_at(target_at)

            rolls = outcome.for_position(action.start_at)
            if battle.assassin_dies(rolls):
                gamestate.delete_unit_at(start_at)

        elif ability == Ability.poison:
            target_unit.set(Effect.poisoned, level=level, duration=level)

        elif ability == Ability.sabotage:
            target_unit.set(Effect.sabotaged, level=level, duration=level)

        elif ability == Ability.improve_weapons:
            target_unit.set(Effect.improved_weapons,
                            level=level,
                            duration=level)

    def prepare_extra_actions():
        # If this is the extra action already, remove the option to do more extra actions
        if unit.has(State.extra_action):
            unit.remove(State.extra_action)
            unit.remove(State.movement_remaining)
            return

        # If the action is a move with a Hobelar, there is no reason to allow an extra action.
        if unit.has(Trait.swiftness) and not action.is_attack:
            unit.remove(State.movement_remaining)
            return

        if movement_remaining or unit.has(Trait.combat_agility):
            unit.set(State.extra_action)
        else:
            unit.remove(State.movement_remaining)

    def update_actions_remaining():

        if unit.has(State.extra_action):
            return

        gamestate.decrement_actions_remaining()

        if action.double_cost:
            gamestate.decrement_actions_remaining()

    def apply_unit_effects():
        if unit.has(Trait.attack_cooldown) and action.is_attack:
            unit.set(State.attack_frozen, value=3)

        if unit.has(Trait.attack_cooldown, 2) and action.is_attack:
            unit.set(State.attack_frozen, value=2)

    def unit_should_gain_experience():
        return action.is_attack or unit.type == Type.Cavalry or action.is_ability

    def get_subattack_targets():
        targets = []
        if unit.has(Trait.triple_attack):
            targets = action.end_at.two_forward_tiles(attack_direction) & set(
                enemy_units)
        elif unit.has(Trait.spread_attack):
            targets = list(action.target_at.adjacent_tiles() & set(all_units))
        elif unit.has(Trait.longsword):
            targets = list(
                action.end_at.four_forward_tiles(attack_direction)
                & set(enemy_units))

        return targets

    def unit_has_subattacks():
        subattack_traits = [
            Trait.triple_attack, Trait.spread_attack, Trait.longsword
        ]

        return any(unit.has(trait) for trait in subattack_traits)

    def unit_has_extra_action_trait():
        return any(
            unit.has(attribute)
            for attribute in [Trait.swiftness, Trait.combat_agility])

    # Define local variables
    start_at = action.start_at
    end_at = action.end_at
    target_at = action.target_at
    unit = action.unit
    target_unit = action.target_unit
    enemy_units = gamestate.enemy_units
    all_units = gamestate.all_units()

    apply_unit_effects()

    update_actions_remaining()

    gamestate.move_unit(start_at, end_at)
    final_position = end_at

    if unit_should_gain_experience():
        unit.gain_experience()

    if action.is_attack:
        attack_direction = action.attack_direction
        settle_attack(action, gamestate, outcome, attack_direction, False)

        if action.move_with_attack and action.target_at not in enemy_units:
            gamestate.move_unit(end_at, target_at)
            final_position = target_at

        if unit_has_subattacks():
            for target in get_subattack_targets():
                sub_attack = Action(all_units, start_at, end_at, target)
                settle_attack(sub_attack, gamestate, outcome, attack_direction,
                              True)

    elif action.is_ability:
        settle_ability()

    if unit_has_extra_action_trait():
        # Determine the movement points the unit can use on its extra action.
        movement_remaining = unit.movement - distance(start_at, final_position)

        # An attack requires a movement point even if it doesn't succeed. But not for Fencer.
        if action.is_attack and not unit.has(
                Trait.combat_agility) and target_at != final_position:
            movement_remaining -= 1
        unit.set(State.movement_remaining, value=movement_remaining)
        prepare_extra_actions()

    unit.set(State.used, value=1)
コード例 #10
0
 def make_action(self, end_at=None, target_at=None, move_with_attack=None, ability=None):
     if not end_at:
         end_at = self.start_at
     return Action(self.units, self.start_at, end_at, target_at, move_with_attack, ability)
コード例 #11
0
from gamestate import Gamestate
from gamestate.action import Action
import json
import game.ai as ai_module
import glob

paths = glob.glob("../ai_tests/*.json")

for path in paths:
    print path
    document = json.loads(open(path).read())

    gamestate = Gamestate.from_document(document["gamestate"])
    desired_action = Action.from_document(gamestate.all_units(),
                                          document["action"])

    gamestate.set_available_actions()
    ai = ai_module.AI()

    action = ai.select_action(gamestate)

    if action != desired_action:
        print action
        print desired_action
        print