def test_returns_only_options_from_one_item_dictionary(self):
        score_lookup = {("a", "b"): 100}

        safest = pick_safest(score_lookup)
        expected_result = (("a", "b"), 100)

        self.assertEqual(expected_result, safest)
Example #2
0
def pick_move_in_equilibrium_from_multiple_score_lookups(score_lookups):
    # This is the WRONG way to find a Nash Equilibrium from different potential games
    # ... but it is a simple way that works (with crappy results)
    #
    # The games should be modelled properly based on incomplete information (see Harsanyi Transform),
    # however that would require the bot to keep track of what it has revealed to the opponent
    try:
        weighted_choices = get_weighted_choices_from_multiple_score_lookups(
            score_lookups)
    except CouldNotFindEquilibriumError as e:
        logger.warning("Problem finding equilibria: {}".format(e))
        return random.choice([
            pick_safest(sl, remove_guaranteed=True)[0][0]
            for sl in score_lookups
        ])

    s = sum([wc[1] for wc in weighted_choices])
    bot_choices = [wc[0] for wc in weighted_choices]
    bot_percentages = [wc[1] / s for wc in weighted_choices]

    choice = random.choices(bot_choices, weights=bot_percentages)[0]

    logger.debug("Choices: {}".format([w for w in weighted_choices if w[1]]))
    logger.debug("Choice: {}".format(choice))

    return choice
    def test_returns_better_option_for_two_different_moves(self):
        score_lookup = {("a", "b"): 100, ("c", "b"): 200}

        safest = pick_safest(score_lookup)
        expected_result = (("c", "b"), 200)

        self.assertEqual(expected_result, safest)
Example #4
0
def pick_safest_move_using_dynamic_search_depth(battles):
    """
    Dynamically decides how far to look into the game.

    This requires a strong computer to be able to search 3/4 turns ahead.
    Using a pypy interpreter will also result in better performance.

    """
    all_scores = dict()
    num_battles = len(battles)

    if num_battles > 1:
        search_depth = 2

        for i, b in enumerate(battles):
            state = b.create_state()
            mutator = StateMutator(state)
            user_options, opponent_options = b.get_all_options()
            logger.debug("Searching through the state: {}".format(mutator.state))
            scores = get_payoff_matrix(mutator, user_options, opponent_options, depth=search_depth, prune=True)
            prefixed_scores = prefix_opponent_move(scores, str(i))
            all_scores = {**all_scores, **prefixed_scores}

    elif num_battles == 1:
        search_depth = 3

        b = battles[0]
        state = b.create_state()
        mutator = StateMutator(state)
        user_options, opponent_options = b.get_all_options()

        num_user_options = len(user_options)
        num_opponent_options = len(opponent_options)
        options_product = num_user_options * num_opponent_options
        if options_product < 20 and num_user_options > 1 and num_opponent_options > 1:
            logger.debug("Low options product, looking an additional depth")
            search_depth += 1

        logger.debug("Searching through the state: {}".format(mutator.state))
        logger.debug("Options Product: {}".format(options_product))
        logger.debug("My Options: {}".format(user_options))
        logger.debug("Opponent Options: {}".format(opponent_options))
        logger.debug("Search depth: {}".format(search_depth))
        all_scores = get_payoff_matrix(mutator, user_options, opponent_options, depth=search_depth, prune=True)

    else:
        raise ValueError("less than 1 battle?: {}".format(battles))

    decision, payoff = pick_safest(all_scores, remove_guaranteed=True)
    bot_choice = decision[0]
    logger.debug("Safest: {}, {}".format(bot_choice, payoff))
    logger.debug("Depth: {}".format(search_depth))
    return bot_choice
    def test_returns_option_with_the_lowest_minimum_in_2_by_2(self):
        score_lookup = {
            ("a", "x"): 100,
            ("a", "y"): -100,
            ("c", "x"): 200,
            ("c", "y"): -200,
        }

        safest = pick_safest(score_lookup)
        expected_result = (("a", "y"), -100)

        self.assertEqual(expected_result, safest)
Example #6
0
def pick_safest_move_from_battles(battles):
    all_scores = dict()
    for i, b in enumerate(battles):
        state = b.create_state()
        mutator = StateMutator(state)
        user_options, opponent_options = b.get_all_options()
        logger.debug("Searching through the state: {}".format(mutator.state))
        scores = get_payoff_matrix(mutator, user_options, opponent_options, depth=config.search_depth, prune=True)

        prefixed_scores = prefix_opponent_move(scores, str(i))
        all_scores = {**all_scores, **prefixed_scores}

    decision, payoff = pick_safest(all_scores, remove_guaranteed=True)
    bot_choice = decision[0]
    logger.debug("Safest: {}, {}".format(bot_choice, payoff))
    return bot_choice
Example #7
0
def pick_safest_move_from_battles(battles):
    all_scores = dict()
    for i, b in enumerate(battles):
        state = b.create_state()
        mutator = StateMutator(state)
        user_options, opponent_options = b.get_all_options()
        logger.debug("Attempting to find best move from: {}".format(
            mutator.state))
        scores = get_payoff_matrix(mutator,
                                   user_options,
                                   opponent_options,
                                   prune=True)
        prefixed_scores = prefix_opponent_move(scores, str(i))
        all_scores = {**all_scores, **prefixed_scores}

    decision, payoff = pick_safest(all_scores)
    bot_choice = decision[0]
    logger.debug("Safest: {}, {}".format(bot_choice, payoff))
    return bot_choice