예제 #1
0
def does_turn_shift_work(test_document):
    pre_gamestate = Gamestate.from_document(test_document["pre_gamestate"])
    post_gamestate = Gamestate.from_document(test_document["post_gamestate"])
    pre_gamestate.shift_turn()
    pre_gamestate.flip_all_units()

    actual = pre_gamestate.to_document()
    expected = post_gamestate.to_document()
    return give_output(actual, expected)
예제 #2
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)
예제 #3
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
예제 #4
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)
예제 #5
0
def does_upgrade_exist(test_document):
    gamestate1 = Gamestate.from_document(test_document["pre_gamestate"])
    gamestate2 = Gamestate.from_document(test_document["pre_gamestate"])
    expected_gamestate = Gamestate.from_document(test_document["post_gamestate"])

    for position, unit in gamestate1.player_units.items():
        if unit.should_be_upgraded():
            gamestate1.player_units[position] = unit.get_upgraded_unit_from_choice(0)
            gamestate2.player_units[position] = unit.get_upgraded_unit_from_choice(1)

    if (expected_gamestate in [gamestate1, gamestate2]) == test_document["result"]:
        return True
    else:
        print("g1", gamestate1.to_document())
        print("g2", gamestate2.to_document())
        print("ex", expected_gamestate.to_document())
        return False
예제 #6
0
def one_action_forward(gamestate_document, action, outcome=None):
    """
    :param gamestate_document: A dictionary containing the gamestate
    :param action: An action
    :param outcome: An outcome of the action if applicable
    :return: The resulting gamestate after performing action. (Including new bonus tiles.)
    """
    gamestate = Gamestate.from_document(gamestate_document)
    action = update_references(action, gamestate)
    gamestate.bonus_tiles = action_getter.get_bonus_tiles(gamestate)
    gamestate.do_action(action, outcome)
    return gamestate
예제 #7
0
def test_action_getter():
    path = "./../Version_1.0/Tests/General/Action_1.json"
    document = json.loads(open(path).read())
    gamestate = Gamestate.from_document(document["gamestate"])

    nloops = 100
    total_time = 0
    for _ in range(nloops):
        t = time()
        action_getter.get_actions(gamestate)
        total_time += time() - t

    print("Time used to find all actions", str(nloops), "times:",
          str(round(total_time, 3)))
예제 #8
0
def upgrade(test_document):
    gamestate = Gamestate.from_document(test_document["pre_gamestate"])

    expected_gamestate = Gamestate.from_document(test_document["post_gamestate"])

    if type(test_document["upgrade"]) is str:
        upgrade_choice = enum_from_string["upgrade"]
    else:
        upgrade_choice = {}
        for key, value in test_document["upgrade"].items():
            attribute_name = key
            number = value

            attribute, attributes = get_attribute_from_document(attribute_name, number)
            upgrade_choice[attribute] = attributes

    for position, unit in gamestate.player_units.items():
        if unit.should_be_upgraded():
            gamestate.player_units[position] = unit.get_upgraded_unit_from_upgrade(upgrade_choice)

    expected = expected_gamestate.to_document()
    actual = gamestate.to_document()
    return give_output(actual, expected)
예제 #9
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
예제 #10
0
    def new_game(cls, green_intelligence, red_intelligence):
        if not os.path.exists("./replay"):
            os.makedirs("./replay")

        controller = Controller(View(), Sound())
        players = [
            Player("Green", green_intelligence),
            Player("Red", red_intelligence)
        ]
        player1_units, player2_units = setup.get_start_units()
        gamestate = Gamestate(player1_units, player2_units, 1)
        controller.game = Game(players, gamestate)
        controller.game.gamestate.initialize_turn()
        controller.game.gamestate.actions_remaining = 1
        controller.clear_move()

        if play_fanfare:
            controller.sound.play_fanfare()

        return controller
예제 #11
0
def new_game(player1, player2):
    games = get_collection("games")
    players = [
        Player("Green", "Human", player1),
        Player("Red", "Human", player2)
    ]

    player1_units, player2_units = setup.get_start_units()

    gamestate = Gamestate(player1_units, player2_units, 1, False,
                          datetime.utcnow())

    game = Game(players, gamestate)
    game_id = games.insert(game.to_document())

    return {
        "Status": "OK",
        "ID": str(game_id),
        "ServerTime": time(),
        "Message": "New game created"
    }
예제 #12
0
def server(test_document):
    gamestate = Gamestate.from_document(test_document["gamestate"])
    if "upgrade" in test_document["action"]:
        is_valid, validation_message, new_unit_string = validate_upgrade(test_document["action"], gamestate)

        new_unit = json.loads(new_unit_string)
        expected = test_document["response"]

        if is_valid == expected["Status"] and validation_message == expected["Message"] and new_unit == expected["Unit"]:
            return True

        print("act", is_valid, validation_message, new_unit)
        print("exp", expected["Status"], expected["Message"], expected["Unit"])

        return False
    elif test_document["action"]["type"] == "action":
        result = validate_action(gamestate, test_document["action"])
        if isinstance(result, Action):
            outcome = determine_outcome_if_any(result, gamestate)

            if outcome and not test_document["response"]["Action outcome"]:
                print("Did not expect an outcome")

                return False
            if not outcome and test_document["response"]["Action outcome"]:
                print("Expected an outcome")

                return False

            return True
        else:
            print("Not implemented")

            return False
    else:
        print("Not implemented")

        return False
예제 #13
0
def is_outcome_correct(test_document):
    game = Game.from_log_document(test_document)
    controller = Controller(View(), Sound())
    controller.positions = read_positions(test_document["pre_positions"])

    controller.game = game
    click_position = Position.from_string(test_document["click_position"])

    if "outcome" in test_document:
        outcome = Outcome.from_document(test_document["outcome"])
        controller.determine_outcome = partial(determine_outcome, outcome)

    if "end_at" in test_document:
        end_at = test_document["end_at"]
        controller.pick_end_at = partial(pick_end_at, end_at)

    if "upgrade_choice" in test_document:
        upgrade_choice = int(test_document["upgrade_choice"])
        controller.pick_upgrade = partial(pick_upgrade, upgrade_choice)

    if "move_with_attack" in test_document:
        controller.ask_about_move_with_attack = partial(ask_about_move_with_attack, test_document["move_with_attack"])

    controller.game.gamestate.set_available_actions()

    controller.game.save = save

    controller.add_log = add_log

    controller.left_click(click_position)

    actual_gamestate = controller.game.gamestate.to_document()
    expected_gamestate = Gamestate.from_document(test_document["post_gamestate"]).to_document()

    actual_positions = controller.positions
    expected_positions = read_positions(test_document["post_positions"])

    return give_output(actual_gamestate, expected_gamestate, actual_positions, expected_positions)
예제 #14
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
예제 #15
0
def is_the_game_over(test_document):
    gamestate = Gamestate.from_document(test_document["gamestate"])
    actual = gamestate.is_ended()
    expected = test_document["result"]
    return give_output(actual, expected)
예제 #16
0
def score_actions(gamestate, scored_actions):
    """
    :param gamestate: A gamestate
    :param scored_actions: A set of actions whose scores are already evaluated.
    :return: A list of actions with attributes score and total_score.
             "score" is the value of the action itself.
             "total_score" is the value of the action plus the best subsequent action if applicable.
    """
    def find_score(result):
        """
        :param result: The result of an action. If the action has an outcome the result can be either win or loss. If
                       the action does not have an outcome, the result is noresult.

        Adds the factors for the resulting gamestate to the factors dictionary of the action, and adds the score of the
        resulting gamestate to the score_if dictionary of the action.
        """
        gamestate_factors = ai_factors.Factors(gamestate_2[action][result])
        gamestate_factors.subtract(original_factors)
        action.factors[result] = gamestate_factors
        action.score_if[result] = gamestate_factors.get_score()

    # Make a copy of the gamestate
    gamestate_1_document = gamestate.to_document()
    gamestate_1 = Gamestate.from_document(gamestate_1_document)

    # Find the available actions.
    gamestate_1.set_available_actions()
    all_actions = gamestate_1.get_actions_including_pass_extra()

    # Only recalculate scores for actions that are new or has a new bonus.
    new_actions = {
        action
        for action in all_actions if action not in scored_actions
    }
    actions_new_bonus = {
        action
        for action in all_actions
        if action.end_at in gamestate.bonus_tiles[Trait.flag_bearing]
        or action.start_at in gamestate.bonus_tiles[Trait.crusading]
    }
    actions = new_actions | actions_new_bonus
    scoredict = {action: action.score for action in scored_actions}
    factordict = {action: action.factors for action in scored_actions}
    for action in all_actions:
        if action in scoredict:
            action.score = scoredict[action]
            action.total_score = scoredict[action]
            action.factors = factordict[action]

    # If there are no actions whose scores are not already calculated, skip the remaining steps.
    if not actions:
        return all_actions

    # Contains the new gamestates after each action and each result.
    gamestate_2 = {}

    # The factors of gamestate_1. A factor is an element of the gamestate that is important.
    original_factors = ai_factors.Factors(gamestate_1)

    # Define a function that returns the resulting gamestate after performing an action on gamestate_1.
    # (Without changing gamestate_1.)
    perform_action = partial(one_action_forward, gamestate_1_document)

    # For each action, calculate the score of the action itself.
    for action in actions:
        action.factors, action.score_if = {}, {
        }  # Contains the factors and scores after each possible result.
        gamestate_2[action] = {
        }  # Contains the gamestate after each possible results.

        if action.has_outcome:
            gamestate_2[action][Result.win] = perform_action(action, success)
            gamestate_2[action][Result.loss] = perform_action(action, failure)
            action.chance_of_win = chance_of_win(gamestate_1, action)
            find_score(Result.win)
            find_score(Result.loss)
            action.score = (
                action.score_if[Result.win] * action.chance_of_win +
                action.score_if[Result.loss] * (1 - action.chance_of_win))

        else:
            gamestate_2[action][Result.noresult] = perform_action(action)
            find_score(Result.noresult)
            action.score = action.score_if[Result.noresult]

    if gamestate_1.is_extra_action(
    ) and scored_actions and gamestate_1.actions_remaining:
        for action in all_actions:
            action.total_score = action.score + max(
                [action.score for action in scored_actions])
        return all_actions

    # For each action (and each result), find the best next action and its score.
    for action in actions:
        if next(iter(gamestate_2[action].values())).actions_remaining:
            action.next_action = {
            }  # Contains the best next action after each possible result.
            if action.has_outcome:
                if action.factors[Result.win].opponent_has_winning_action():
                    next_actions_if_win = score_actions(
                        gamestate_2[action][Result.win], set())
                else:
                    next_actions_if_win = score_actions(
                        gamestate_2[action][Result.win], actions)

                if action.factors[Result.loss].opponent_has_winning_action():
                    next_actions_if_loss = score_actions(
                        gamestate_2[action][Result.loss], set())
                else:
                    next_actions_if_loss = score_actions(
                        gamestate_2[action][Result.loss], actions)

                action.next_action[Result.win] = max(next_actions_if_win,
                                                     key=attrgetter("score"))
                action.next_action[Result.loss] = max(next_actions_if_loss,
                                                      key=attrgetter("score"))

            else:
                if action.factors[
                        Result.noresult].opponent_has_winning_action():
                    next_actions = score_actions(
                        gamestate_2[action][Result.noresult], set())
                else:
                    next_actions = score_actions(
                        gamestate_2[action][Result.noresult], actions)
                action.next_action[Result.noresult] = max(
                    next_actions, key=attrgetter("score"))

    # For each action, calculate the total score. The total score is the value of the action and the expected value
    # of the best next action if applicable.
    for action in actions:
        if hasattr(action, "next_action"):
            if action.has_outcome:
                next_action_score = (
                    action.next_action[Result.win].total_score *
                    action.chance_of_win +
                    action.next_action[Result.loss].total_score *
                    (1 - action.chance_of_win))
            else:
                next_action_score = action.next_action[
                    Result.noresult].total_score
            action.total_score = action.score + next_action_score
            if next_action_score > action.score:
                action.total_score -= 0.1
        else:
            action.total_score = action.score

    return all_actions