예제 #1
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
예제 #2
0
파일: main.py 프로젝트: pmariglia/showdown
    def find_best_move(self):
        battles = self.prepare_battles()
        if len(battles) > 7:
            logger.debug(
                "Not enough is known about the opponent's active pokemon - falling back to safest decision making"
            )
            battles = self.prepare_battles(join_moves_together=True)
            decision = pick_safest_move_from_battles(battles)
        else:
            list_of_payoffs = list()
            for b in battles:
                state = b.create_state()
                mutator = StateMutator(state)
                logger.debug("Attempting to find best move from: {}".format(
                    mutator.state))
                user_options, opponent_options = b.get_all_options()
                scores = get_payoff_matrix(mutator,
                                           user_options,
                                           opponent_options,
                                           prune=False)
                list_of_payoffs.append(scores)

            decision = pick_move_in_equilibrium_from_multiple_score_lookups(
                list_of_payoffs)

        return format_decision(self, decision)
예제 #3
0
    def pick_bfs_move(self, battle):

        state = battle.create_state()
        mutator = StateMutator(state)
        user_options, opponent_options = battle.get_all_options()
        logger.debug("Attempting to find best move from: {}".format(mutator.state))

        is_winning = self.is_winning(state)

        # Builds a tree to search for opponent's moves, assume opponent picks safest
        scores = get_payoff_matrix(mutator, user_options, opponent_options, is_winning, depth=3, prune=True)

        logger.debug(f"\nScores: {scores}")

        move_string = "Aggresive"

        if is_winning:
            decision, payoff = self.pick_safest(scores)
            move_string = "Safest"
        else:
            decision, payoff = self.pick_aggresive(scores)

        bot_choice = decision[0]
        logger.debug(f"{move_string}: {bot_choice}, {payoff}")
        return bot_choice
예제 #4
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
예제 #5
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
예제 #6
0
                    'id': 'dragondance',
                    'disabled': False,
                    'current_pp': 32
                }, {
                    'id': 'earthquake',
                    'disabled': False,
                    'current_pp': 16
                }, {
                    'id': 'bounce',
                    'disabled': False,
                    'current_pp': 8
                }],
                'types': ['water', 'flying'],
                'canMegaEvo':
                False
            }
        },
        'side_conditions': {
            'toxic_count': 0
        },
        'trapped': False
    },
    'weather': None,
    'field': None,
    'trickroom': False,
    'forceSwitch': False,
    'wait': False
})
mutator = StateMutator(state)
state_instructions = get_payoff_matrix(mutator, depth=3)
예제 #7
0
                'canMegaEvo':
                False
            }
        },
        'side_conditions': {
            'toxic_count': 0
        },
        'trapped': False
    },
    'weather': None,
    'field': None,
    'trickroom': False,
    'forceSwitch': False,
    'wait': False
}
# second = {'self': {'active': {'id': 'audino', 'level': 81, 'hp': 299, 'maxhp': 299, 'ability': 'regenerator', 'baseStats': {'hp': 103, 'attack': 60, 'defense': 86, 'special-attack': 60, 'special-defense': 86, 'speed': 50}, 'attack': 144, 'defense': 186, 'special-attack': 144, 'special-defense': 186, 'speed': 128, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'healbell', 'disabled': False, 'current_pp': 8}, {'id': 'protect', 'disabled': False, 'current_pp': 16}, {'id': 'wish', 'disabled': False, 'current_pp': 16}, {'id': 'hypervoice', 'disabled': False, 'current_pp': 16}], 'types': ['normal']}, 'reserve': {'heatran': {'id': 'heatran', 'level': 75, 'hp': 0, 'maxhp': 260, 'ability': 'flashfire', 'baseStats': {'hp': 91, 'attack': 90, 'defense': 106, 'special-attack': 130, 'special-defense': 106, 'speed': 77}, 'attack': 179, 'defense': 203, 'special-attack': 239, 'special-defense': 203, 'speed': 159, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'roar', 'disabled': False, 'current_pp': 32}, {'id': 'stealthrock', 'disabled': False, 'current_pp': 32}, {'id': 'earthpower', 'disabled': False, 'current_pp': 16}, {'id': 'lavaplume', 'disabled': False, 'current_pp': 24}], 'types': ['fire', 'steel']}, 'omastar': {'id': 'omastar', 'level': 81, 'hp': 246, 'maxhp': 246, 'ability': 'swiftswim', 'baseStats': {'hp': 70, 'attack': 60, 'defense': 125, 'special-attack': 115, 'special-defense': 70, 'speed': 55}, 'attack': 144, 'defense': 249, 'special-attack': 233, 'special-defense': 160, 'speed': 136, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'scald', 'disabled': False, 'current_pp': 24}, {'id': 'shellsmash', 'disabled': False, 'current_pp': 24}, {'id': 'earthpower', 'disabled': False, 'current_pp': 16}, {'id': 'icebeam', 'disabled': False, 'current_pp': 16}], 'types': ['rock', 'water']}, 'alomomola': {'id': 'alomomola', 'level': 77, 'hp': 381, 'maxhp': 381, 'ability': 'regenerator', 'baseStats': {'hp': 165, 'attack': 75, 'defense': 80, 'special-attack': 40, 'special-defense': 45, 'speed': 65}, 'attack': 160, 'defense': 168, 'special-attack': 106, 'special-defense': 114, 'speed': 145, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'knockoff', 'disabled': False, 'current_pp': 32}, {'id': 'wish', 'disabled': False, 'current_pp': 16}, {'id': 'toxic', 'disabled': False, 'current_pp': 16}, {'id': 'scald', 'disabled': False, 'current_pp': 24}], 'types': ['water']}, 'hawlucha': {'id': 'hawlucha', 'level': 75, 'hp': 105, 'maxhp': 241, 'ability': 'unburden', 'baseStats': {'hp': 78, 'attack': 92, 'defense': 75, 'special-attack': 74, 'special-defense': 63, 'speed': 118}, 'attack': 182, 'defense': 156, 'special-attack': 155, 'special-defense': 138, 'speed': 221, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'swordsdance', 'disabled': False, 'current_pp': 32}, {'id': 'stoneedge', 'disabled': False, 'current_pp': 8}, {'id': 'roost', 'disabled': False, 'current_pp': 16}, {'id': 'highjumpkick', 'disabled': False, 'current_pp': 16}], 'types': ['fighting', 'flying']}, 'swalot': {'id': 'swalot', 'level': 83, 'hp': 129, 'maxhp': 302, 'ability': 'stickyhold', 'baseStats': {'hp': 100, 'attack': 73, 'defense': 83, 'special-attack': 73, 'special-defense': 83, 'speed': 55}, 'attack': 169, 'defense': 185, 'special-attack': 169, 'special-defense': 185, 'speed': 139, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'icebeam', 'disabled': False, 'current_pp': 16}, {'id': 'encore', 'disabled': False, 'current_pp': 8}, {'id': 'yawn', 'disabled': False, 'current_pp': 16}, {'id': 'sludgebomb', 'disabled': False, 'current_pp': 16}], 'types': ['poison']}}, 'side_conditions': {'stealthrock': 0, 'spikes': 0}, 'trapped': False}, 'opponent': {'active': {'id': 'zekrom', 'level': 73, 'hp': 202.16, 'maxhp': 266, 'ability': 'teravolt', 'baseStats': {'hp': 100, 'attack': 150, 'defense': 120, 'special-attack': 120, 'special-defense': 100, 'speed': 90}, 'attack': 261, 'defense': 218, 'special-attack': 218, 'special-defense': 188, 'speed': 174, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'boltstrike', 'disabled': False, 'current_pp': 8}, {'id': 'substitute', 'disabled': False, 'current_pp': 16}], 'types': ['dragon', 'electric']}, 'reserve': {'rotomfrost': {'id': 'rotomfrost', 'level': 83, 'hp': 199.29000000000002, 'maxhp': 219, 'ability': 'levitate', 'baseStats': {'hp': 50, 'attack': 65, 'defense': 107, 'special-attack': 105, 'special-defense': 107, 'speed': 86}, 'attack': 156, 'defense': 225, 'special-attack': 222, 'special-defense': 225, 'speed': 190, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'voltswitch', 'disabled': False, 'current_pp': 32}], 'types': ['electric', 'ice']}, 'bibarel': {'id': 'bibarel', 'level': 83, 'hp': 0, 'maxhp': 267, 'ability': None, 'baseStats': {'hp': 79, 'attack': 85, 'defense': 60, 'special-attack': 55, 'special-defense': 60, 'speed': 71}, 'attack': 189, 'defense': 147, 'special-attack': 139, 'special-defense': 147, 'speed': 166, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'return', 'disabled': False, 'current_pp': 32}], 'types': ['normal', 'water']}, 'passimian': {'id': 'passimian', 'level': 83, 'hp': 193.28, 'maxhp': 302, 'ability': None, 'baseStats': {'hp': 100, 'attack': 120, 'defense': 90, 'special-attack': 40, 'special-defense': 60, 'speed': 80}, 'attack': 247, 'defense': 197, 'special-attack': 114, 'special-defense': 147, 'speed': 180, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'uturn', 'disabled': False, 'current_pp': 32}], 'types': ['fighting']}}, 'side_conditions': {'stealthrock': 0, 'spikes': 0}, 'trapped': False}, 'weather': None, 'field': None, 'forceSwitch': False, 'wait': False}

state = State.from_dict(first)
mutator = StateMutator(state)

instruction = get_all_state_instructions(mutator, 'flareblitz', 'nastyplot')

scores = get_payoff_matrix(mutator, depth=2)

df = pd.Series(scores).unstack()
averages = df.mean(axis=1)

safest = pick_safest(scores)

pass
예제 #8
0
    def pick_move_from_battles(self, battles):
        # Only work on current battle
        # In practice the bot can play several at once, for now we simplified to one battle.
        battle = battles[0]
        root = Node("Root")

        state = battle.create_state()
        mutator = StateMutator(state)
        user_options, opponent_options = battle.get_all_options()
        logger.debug("Attempting to find best move from: {}".format(mutator.state))
        #get the scores from the "safest" algorithm provided by the starter code
        scores = get_payoff_matrix(mutator, user_options, opponent_options, depth=2, prune=False)

        # Create tree using payoff matrix from "Safest" algorithm
        checked_moves = {}
        for (myMove, opponentMove), score in scores.items():
            #checked moves keeps track of which nodes have been added to the tree, so we dont duplicate.
            if myMove not in checked_moves:
                child = Node(myMove, root)
                checked_moves[myMove] = child
            grandchild = Node(opponentMove, checked_moves[myMove])
            Node(score, grandchild)

        # a library function that prints our tree for readability.
        for pre, _, node in RenderTree(root):
            print("%s%s" % (pre, node.name))

        myTotalHP = 0.0 # max of 600, 100 points for full hp
        oppTotalHP = 0.0

        # calculate my total hp
        my_pokes = state.self
        # get active pokemon hp if it isn't dead
        if my_pokes.active.maxhp != 0:
            myTotalHP += my_pokes.active.hp / my_pokes.active.maxhp
        # get reserve pokmeons hps
        for p in my_pokes.reserve.values():
            if p.maxhp !=0:
                myTotalHP += p.hp / p.maxhp
        myTotalHP *= 100

        # calculate opp total hp
        opp_pokes = state.opponent
        # get active pokemon hp
        if opp_pokes.active.maxhp != 0:
            oppTotalHP += opp_pokes.active.hp / opp_pokes.active.maxhp
        # get reserve pokmeons hps
        for p in opp_pokes.reserve.values():
            if p.maxhp !=0:
                oppTotalHP += p.hp / p.maxhp
        
        #accounts for the pokemon of opponent that have not been revealed
        unseenPoke = 5-len(opp_pokes.reserve)
        oppTotalHP += unseenPoke
        oppTotalHP *=100

        possibleStatuses = {
            "psn" : .06,
            "frz" : .25,
            "tox" : .19,
            "par" : .16,
            "slp" : .16,
            "brn" : .20,
            None: 0,
        }

        statBuffs = {
            6 : .25,
            5 : .235,
            4 : .22,
            3 : .19,
            2 : .15,
            1 : .08,
            0 : 0,
            -1 : -.08,
            -2 : -.15,
            -3 : -.19,
            -4 : -.22,
            -5 : -.235,
            -6 : -.25,
        }

        # check how many status conditions we have
        myStatuses = 0
        # active pokemon
        myStatuses += possibleStatuses[my_pokes.active.status]
        # reserve pokemon
        for p in my_pokes.reserve.values():
            myStatuses += possibleStatuses[p.status]

        # check how many status conditions opponent has
        opponentStatuses = 0
        # active pokemon
        opponentStatuses += possibleStatuses[opp_pokes.active.status]
        # reserve pokemon
        for p in opp_pokes.reserve.values():
            opponentStatuses += possibleStatuses[p.status]

        status_aggression_multiplier = 1
        status_aggression_modifier = (opponentStatuses - myStatuses) * status_aggression_multiplier
        print(f"Status modifier:{status_aggression_modifier}")

        # Stat Buffs
        # check how many stat boosts/nerfs we have
        myBuffs = 0
        # active pokemon
        myBuffs += statBuffs[my_pokes.active.accuracy_boost]
        myBuffs += statBuffs[my_pokes.active.attack_boost]
        myBuffs += statBuffs[my_pokes.active.defense_boost]
        myBuffs += statBuffs[my_pokes.active.evasion_boost]
        myBuffs += statBuffs[my_pokes.active.special_attack_boost]
        myBuffs += statBuffs[my_pokes.active.special_defense_boost]
        myBuffs += statBuffs[my_pokes.active.speed_boost]
        
        # check how many stat boosts/nerfs opponent has
        oppBuffs = 0
        # active pokemon
        oppBuffs += statBuffs[opp_pokes.active.accuracy_boost]
        oppBuffs += statBuffs[opp_pokes.active.attack_boost]
        oppBuffs += statBuffs[opp_pokes.active.defense_boost]
        oppBuffs += statBuffs[opp_pokes.active.evasion_boost]
        oppBuffs += statBuffs[opp_pokes.active.special_attack_boost]
        oppBuffs += statBuffs[opp_pokes.active.special_defense_boost]
        oppBuffs += statBuffs[opp_pokes.active.speed_boost]

        buff_aggression_multiplier = 1
        buff_aggression_modifier = (myBuffs - oppBuffs) * buff_aggression_multiplier
        print(f"Buff modifier:{buff_aggression_modifier}")

        safety = (3 + status_aggression_modifier + buff_aggression_modifier) * myTotalHP/oppTotalHP
        if safety < 0:
            print("WARNING: safety constant is less than 0, changing to 0.1")
            safety = 0.1
        print(f"bot will play with safety constant of {safety}")
        bot_choice = self.aggressive_pick(root,safety)
        print(f"choice: {bot_choice}")
        print(f"the safest pick was {self.safest_pick(root)}")

        print("Choice: {}".format(bot_choice))
        return bot_choice