Exemplo n.º 1
0
    def __init__(self, **kwargs):
        # You'd pass in a dict containing information on the 'mon here.
        # {'species': 'vaporeon', 'level': 100, 'moves': ['Surf', 'Ice Beam']} ... etc

        # Initialising. They'll be overwritten if they exist
        self.level = 100
        self.ivs = [0] * 6
        self.evs = [0] * 6
        self.nature = 'Hardy'

        for arg in kwargs:
            setattr(self, arg, kwargs.get(arg))

        dex = POKEDEX.get(utils.condense(self.species))
        base_stats = dex.get('baseStats')

        self.types = dex.get('types')

        self.maxhp = statcalc_hp(base_stats['hp'], self.ivs[0], self.evs[0], self.level)
        self.hp = self.maxhp

        self.attack = statcalc('atk', base_stats['atk'], self.ivs[1], self.evs[1], self.level, self.nature)
        self.defense = statcalc('def', base_stats['def'], self.ivs[2], self.evs[2], self.level, self.nature)
        self.spattack = statcalc('spa', base_stats['spa'], self.ivs[3], self.evs[3], self.level, self.nature)
        self.spdefense = statcalc('spd', base_stats['spd'], self.ivs[4], self.evs[4], self.level, self.nature)
        self.speed = statcalc('spe', base_stats['spe'], self.ivs[5], self.evs[5], self.level, self.nature)

        # Volatiles

        self.volatiles = {'boosts': {}, 'volatile_status': None}
        self.status = None
Exemplo n.º 2
0
Arquivo: battle.py Projeto: xfix/pyMon
    def best_switch(self, active, sidedata, target):
        print 'call to switch'
        highest_score = 0
        alive_mon_indexes = self.pick_alive_mons(sidedata)
        side_mon_info = sidedata.get('pokemon')

        # Loops through all mons, finds which has the highest score, and switches

        print alive_mon_indexes
        best_mon_index = alive_mon_indexes[0]

        for i in alive_mon_indexes:

            mon = side_mon_info[i - 1]
            mon_info = mon.get('details').split(', ')

            mon_species = utils.condense(mon_info[0])
            mon_level = mon_info[1][1:]
            try:
                mon_types = battleutils.POKEDEX.get(mon_species).get('types')
            except Exception as e:
                print e
                mon_types = ['Normal']

            movelist = mon.get('moves')

            scores = [battleutils.calculate_move_score(active, mon_types, target, x) for x in movelist]
            print movelist
            print scores
            best_score = max(scores)

            if best_score > highest_score:
                print 'best score %s is higher than highest score %s!' % (best_score, highest_score)
                highest_score = best_score
                best_move = movelist[scores.index(best_score)]
                print 'best move is %s!' % best_move
                best_mon = mon_species
                best_mon_index = i

        result = '/switch ' + str(best_mon_index)
        print result
        return result
Exemplo n.º 3
0
    def received_message(self, m):
        # PS sometimes sends multiple messages split by newlines...
        messages = str(m).split('\n')

        if messages[0][0] == '>':
            room = messages.pop(0)
        else:
            room = '>lobby'

        for rawmessage in messages:
            is_battle = False
            rawmessage = "%s\n%s" % (room, rawmessage)

            print rawmessage

            msg = rawmessage.split("|")

            battle_regex = re.compile('>battle-')

            if battle_regex.match(msg[0]):
                # print 'handling battle message', msg
                self.bh.handle(msg)

            if len(msg) < 2:
                continue

            downmsg = msg[1].lower()

            # print msg, ' - ', is_battle, ' - ', downmsg

            if downmsg == 'challstr':
                print '%s: Attempting to login...' % self.user
                assertion = utils.old_login(self.user, 
                                            self.config.get('Chatbot', 'password'), 
                                            msg[3], 
                                            msg[2])
                #assertion = utils.login(self.user, 
                #                        self.config.get('Chatbot','password'), 
                #                        '|'.join(msg[2:]))

                if assertion is None:
                    raise Exception('%s: Could not login' % self.user)

                self.send('|/trn %s,0,%s' % (self.user, assertion))

            elif downmsg == 'formats':
                data = '|'.join(msg[2:])

                # this takes all of the formats data PS sends on connection 
                # and turns it into a list
                self.ch.battle_formats = map(utils.condense,
                                             (re.sub(r'\|\d\|[^|]+', '', ('|' + re.sub(r'(,[0-9a-f])', '', data)))
                                              ).split('|'))[1:]

            elif downmsg == 'updateuser':
                if utils.condense(msg[2]) == utils.condense(self.user):
                    # Bot has logged in.

                    print '%s: Logged in!' % self.user

                    self.ch.queue_worker.start()

                    for r in self.rooms:
                        print '%s: Joining room %s.' % (self.user, r)
                        self.ch.queue_message('|/join %s' % r)

            elif downmsg in ['c', 'c:', 'pm', 'j', 'n', 'l', 'users', 'raw', 
                             ':', 'init']:
                print 'match', downmsg
                print msg
                self.ch.handle(msg[1:], room)

            elif downmsg == 'tournament':
                # self.ch.handle_tournament(msg)
                print 'not implemented handle_tournament'

            elif downmsg == 'updatechallenges':
                self.bh.handle_challenge(msg)
Exemplo n.º 4
0
    def handle(self, msg, room):
        room = room.replace('>', '')

        m_info = self.make_msg_info(msg, room, self.ws)

        if m_info['where'] == ':':
            # : messages contain an UNIX timestamp of when the room was joined
            # nvm, PS's time is usually off
            self.join_time[room] = str(int(time.time()))

        # Prevents the chatbot from responding to messages
        # sent before it entered the room
        if (m_info.get('who') and
            ((m_info.get('when') and
             int(m_info.get('when')) > int(self.join_time[room])) or
             m_info.get('where') in {'j', 'l', 'pm'})):

            for trigger in self.triggers:
                # print 'testing trigger %s' % trigger
                try:
                    if trigger.match(m_info):
                        print 'match %s' % trigger
                        future = self.thread_pool_executor.submit(self.call_trigger_response, trigger, m_info)
                        future.room = room
                        future.m_info = m_info
                        future.add_done_callback(self.future_callback)
                except Exception as e:
                    self.send_pm(self.ws.master,
                                 "Crashed in match: %s, %s, %s" %
                                 (e.message, e.args, trigger))

        # User list is currently hardcoded here. Might move this to triggers later on
        if m_info['where'] == 'j' and condense(m_info['who']) not in map(condense, self.current_users[room]):
            self.current_users[room].append(msg[1])

        elif m_info['where'] == 'l':
            for user in self.current_users[room]:
                if condense(user) == condense(msg[1]):
                    self.current_users[room].remove(user)

        elif m_info['where'] == 'n':
            # |N| messages are of the format |N|(rank)newname|oldnameid
            # Rank is a blank space if the nick is a regular user
            # i.e. |N|@Scotteh|stretcher
            newuser, olduser, userfound = msg[1], msg[2], False
            for user in self.current_users[room]:
                if condense(user) == condense(msg[2]):
                    self.current_users[room].remove(user)
                    userfound = True
            if userfound:
                self.current_users[room].append(msg[1])

        elif m_info['where'] == 'users':
            # Resets the userlist for the room if it exists, and creates a new one
            # |users| messages are only sent on room join
            self.current_users[room] = []
            for user in msg[1].split(',')[1:]:
                self.current_users[room].append(user)

        if m_info['where'] == 'raw' and int(time.time()) > int(self.join_time[room]):
            print (int(time.time()), self.join_time[room])
            # Get checker. Hardcoded.
            getmap = {2: 'dubs',
                      3: 'trips',
                      4: 'quads',
                      5: 'quints',
                      6: 'sexts',
                      7: 'septs',
                      8: 'octs',
                      9: 'nons',
                      10: 'decs'}

            if m_info['all'][1].startswith('<div class="infobox">Roll '):
                raw_msg = msg[1][21:-6]  # Strips the leading HTML

                # Don't try and understand the next line, it takes raw_msg as input and 
                # creates a list of size 2 lists splitting the raw_msg and showing the consecutive 
                # characters, and returns the amount of consecutive characters at the end
                # '11223344441122' => [['1', 2], ['2', 2], ['3', 2], ['4', 4], ['1', 2], ['2', 2]]
                get = getmap.get([[k,len(list(g))] for k, g in groupby(raw_msg)][-1][1])
                if get:
                    self.send_msg(room, 'nice ' + get)
Exemplo n.º 5
0
 def match(self, info):
     return condense(info.get('who')) == self.ch.ws.master and info.get('what').startswith('.eval ')
Exemplo n.º 6
0
 def get_rank(self, user):
     u_id = condense(user)
     for u in self.users:
         if u_id == condense(u):
             return u[0]
Exemplo n.º 7
0
def calculate_move_score(active, types, target, move):
    move = utils.condense(move)

    # Score is zero for all of these
    blacklist = ['suckerpunch',
                 'focuspunch',
                 'fakeout',
                 'return',
                 'frustration',
                 'snore',
                 'dreameater',
                 'lastresort',
                 'explosion',
                 'selfdestruct',
                 'synchronoise',
                 'belch',
                 'trumpcard',
                 'wringout'
                 ]

    badlist = ['gigaimpact',
               'hyperbeam',
               'rockwrecker',
               'frenzyplant',
               'hydrocannon',
               'blastburn',
               'roaroftime',
               'skyattack',
               'solarbeam',
               'freezeshock',
               'iceburn',
               'doomdesire',
               'futuresight ',
               'leafstorm',
               'overheat',
               'dracometeor',
               'psychoboost',
               'superpower',
               'hammerarm'
               ]

    if not MOVES.get(move):
        return 0

    if MOVES.get(move).get('category') == 'Status' or move in blacklist:
        return 0

    res = 1.0

    for user_type in types:
        if MOVES[move]['type'] == user_type:
            res *= 1.5

    if move in badlist:
        res *= 0.5

    res *= MOVES[move]['basePower']
    if type(MOVES[move]['accuracy']) == int:
        res *= (MOVES[move]['accuracy'] / 100.0)
    res *= effectiveness(move, target)

    return res
Exemplo n.º 8
0
 async def match(self, info):
     return (utils.condense(info.get('who')) == self.cb.master
             and info.get('what').startswith('.eval'))
Exemplo n.º 9
0
Arquivo: battle.py Projeto: xfix/pyMon
    def handle(self, msg):
        # Commenting out until I decide whether to properly integrate triggers in battle rooms with regular triggers.
        # self.ch.handle(msg, self.id)

        if msg[0] == 'init':
            self.ch.send_msg(self.id, '/timer')

        elif msg[0] == 'c':

            # These are hardcoded.

            if utils.condense(msg[1]) == 'scotteh':
                if msg[2] == '!alive':
                    self.ch.send_msg(self.id, self.name_alive_mons(self.sidedata))

                elif msg[2] == '!moves':
                    if self.active is not None:
                        self.ch.send_msg(self.id, ', '.join(self.pick_move(self.active)))

                elif msg[2] == '!item':
                    self.ch.send_msg(self.id, self.sidedata['pokemon'][0]['item'])

                elif msg[2].startswith('!custom'):
                    self.ch.send_msg(self.id, msg[2][8:])

                elif msg[2].startswith('.eval'):
                    expression = msg[2][6:]
                    try:
                        response = eval(expression)
                        self.ch.send_msg(self.id, response)
                    except Exception as e:
                        self.ch.send_msg(self.id, e)

        elif msg[0] == 'player':
            # Sets p1 and p2 in a new player object

            if msg[1] == 'p1':

                if msg[2] == self.ch.user:
                    # This is me
                    self.me = 'p1'
                else:
                    self.me = 'p2'

                self.battle.p1 = battleutils.Player(id=msg[1], username=utils.condense(msg[2]))
            else:
                self.battle.p2 = battleutils.Player(id=msg[1], username=utils.condense(msg[2]))

        elif msg[0] == 'poke':
            if msg[1] == 'p1':
                self.battle.add_to_team(self.battle.p1, msg[2])
            else:
                self.battle.add_to_team(self.battle.p2, msg[2])

        elif msg[0] == 'switch' or msg[0] == 'drag':
            # New mon was sent out
            if msg[1][0:2] != self.me:
                if self.waiting:
                    self.waiting = False
                    self.ch.send_msg(self.id, '/switch %s|%s' % (random.choice(self.pick_alive_mons(self.sidedata)),
                                                                 self.rqid))

                mon_info = msg[2].split(', ')
                mon_species = utils.condense(mon_info[0])
                mon_level = int(mon_info[1][1:])

                print 'Encountered a level %s %s' % (mon_level, mon_species)
                self.active_opponent = battleutils.Pokemon(species=mon_species, level=mon_level)
            else:
                mon_info = msg[2].split(', ')
                mon_species = utils.condense(mon_info[0])
                self.types = battleutils.POKEDEX[mon_species]['types']

        elif msg[0] == 'request':
            self.canMegaEvo = False
            request = json.loads(msg[1])

            self.rqid = request.get('rqid')
            self.active = request.get('active', [None])[0]  # Note: check if active has multiple elements for doubles

            self.sidedata = request.get('side')
            self.player = self.sidedata.get('id')

            self.canMegaEvo = self.sidedata.get('pokemon')[0].get('canMegaEvo')

        elif msg[0] == 'turn':
            # move_msg = '/move %s' % random.choice(self.pick_move(self.active))
            # move_msg = '/move %s' % self.best_move(self.active, self.types, self.active_opponent)
            move_msg = self.best_move(self.active, self.types, self.active_opponent)
            print 'move_msg is %s' % move_msg
            if move_msg.startswith('/move'):
                message = (move_msg + '|' if not self.canMegaEvo else move_msg + ' mega |') + str(self.rqid)
                self.ch.send_msg(self.id, message)
            else:
                self.ch.send_msg(self.id, move_msg)

        elif msg[0] == 'teampreview':
            self.ch.send_msg(self.id, "/team %s|%s" % (random.randint(1, 6), self.rqid))

        elif msg[0] == 'faint' and msg[1][0:2] == self.player:
            if self.lastmove in {'U-turn', 'Volt Switch'}:
                # The opponent needs to send out their 'mon first
                self.waiting = True
            else:
                mon_choice = self.best_switch(self.active, self.sidedata, self.active_opponent)
                self.ch.send_msg(self.id, '%s|%s' % (mon_choice, self.rqid))

        elif self.waiting and msg[0] == 'switch' and msg[1][0:2] != self.player:
            # Opponent has sent out their 'mon
            self.waiting = False
            self.ch.send_msg(self.id, '/switch %s|%s' % (random.choice(self.pick_alive_mons(self.sidedata)), self.rqid))

        elif msg[0] == 'win':
            self.ch.send_msg(self.id, '/leave')

        elif msg[0] == 'deinit':
            del self.bh.battles[self.id]

        elif msg[0] == '-crit' and msg[1][0:2] == self.player:
            self.ch.send_msg(self.id, 'wow stop hacking anytime')

        elif msg[0] == 'move':
            self.lastmove = msg[2]
            if msg[1][0:2] == self.player:
                if msg[2] in {'U-turn', 'Volt Switch', 'Baton Pass', 'Parting Shot'}:  # Horrible hack
                    self.ch.send_msg(self.id, '/switch %s' % random.choice(self.pick_alive_mons(self.sidedata)[1:]))
Exemplo n.º 10
0
async def handle_msg(m, cb):
    messages = m.split('\n')

    if messages[0][0] == '>':
        room = messages.pop(0)[1:]
    else:
        room = 'global'

    for rawmessage in messages:
        print(f'{room}{rawmessage}')
        rawmessage = f'{">" + room}\n{rawmessage}'

        msg = rawmessage.split("|")

        if len(msg) < 2:
            continue

        if room.startswith('battle-') and cb.rooms.get(room):
            await cb.rooms[room].battle.handle(msg)

        downmsg = msg[1].lower()

        if downmsg == 'challstr':
            username = cb.username
            if cb.config[cb.id].get('password'):
                assertion = await login(username, cb.config[cb.id]['password'],
                                        '|'.join(msg[2:4]))
            else:
                assertion = await unreg_login(username, '|'.join(msg[2:4]))

            if len(assertion) == 0 or assertion is None:
                raise Exception('login failed :(')

            await cb.send('', f'/trn {username},0,{assertion}')

        elif downmsg == 'updateuser':
            if condense(msg[2]) == condense(cb.username):
                print("Logged in!")
                rooms = cb.config[cb.id]['rooms']
                for room in rooms.split(','):
                    await cb.send('', f'/join {room}')

        elif downmsg == 'formats':
            data = '|'.join(msg[2:])
            cb.battle_formats = list(
                map(condense, (re.sub(
                    r'\|\d\|[^|]+', '',
                    ('|' + re.sub(r'(,[0-9a-f])', '', data)))).split('|')))[1:]

        elif downmsg == 'init':
            cb.rooms[room] = Room(room, cb)

        elif downmsg == 'deinit':
            del cb.rooms[room]

        elif downmsg == 'title':
            cb.rooms[room].title = msg[2]

        elif downmsg == 'users':
            cb.rooms[room].users = []
            for user in msg[2].split(',')[1:]:
                cb.rooms[room].users.append(user)
            print(cb.rooms[room].__dict__)

        elif downmsg == ':':
            cb.rooms[room].join_time = int(msg[2])

        elif downmsg == 'j' and condense(msg[2]) not in cb.rooms[room].users:
            cb.rooms[room].users.append(msg[2])

        elif downmsg == 'l':
            for user in cb.rooms[room].users:
                if condense(user) == condense(msg[2]):
                    cb.rooms[room].users.remove(user)

        elif downmsg == 'n':
            newuser, olduser, userfound = msg[2], msg[3], False
            for user in cb.rooms[room].users:
                if condense(user) == condense(olduser):
                    cb.rooms[room].users.remove(user)
                    userfound = True
            if userfound:
                cb.rooms[room].users.append(newuser)

        elif downmsg == 'updatechallenges':
            challs = json.loads(msg[2])
            for chall in challs['challengesFrom']:
                if challs['challengesFrom'][chall] == 'gen7doublescustomgame':
                    if cb.teams:
                        team = random.choice(cb.teams['gen7doublescustomgame'])
                        await cb.send('', f'/utm {team}')
                        await cb.send('', f'/accept {chall}')

        if downmsg in ['c', 'c:', 'pm', 'j', 'l', 'html']:
            await handle_chat(msg[1:], room, cb)
Exemplo n.º 11
0
async def handle_msg(m, cb):
    messages = m.split('\n')

    if messages[0][0] == '>':
        room = messages.pop(0)[1:]
    else:
        room = 'global'

    for rawmessage in messages:
        print(f'{room}{rawmessage}')
        rawmessage = f'{">" + room}\n{rawmessage}'

        msg = rawmessage.split("|")

        if len(msg) < 2:
            continue

        if room.startswith('battle-') and cb.rooms.get(room):
            await cb.rooms[room].battle.handle(msg)

        downmsg = msg[1].lower()

        if downmsg == 'challstr':
            username = cb.username
            if cb.config[cb.id].get('password'):
                assertion = await login(username, cb.config[cb.id]['password'],
                                        '|'.join(msg[2:4]))
            else:
                assertion = await unreg_login(username, '|'.join(msg[2:4]))

            if len(assertion) == 0 or assertion is None:
                raise Exception('login failed :(')

            await cb.send('', f'/trn {username},0,{assertion}')

        elif downmsg == 'updateuser':
            if '@' in msg[2][1:]:
                user, status = msg[2].rsplit('@', 1)
            else:
                user = msg[2]
            if condense(user) == condense(cb.username):
                print("Logged in!")
                rooms = cb.config[cb.id]['rooms']
                # join rooms
                for room in rooms.split(','):
                    await cb.send('', f'/join {room}')
                # send status to last room
                await cb.send(room, f'/status {cb.status}')

        elif downmsg == 'formats':
            formats = msg[2:]
            res = {}
            format_name = False
            cur_format = None
            for format in formats:
                if format_name:
                    res[format] = []
                    cur_format = format
                    format_name = False
                    continue
                if format[0] == ',':
                    format_name = True
                    continue
                name, type = format.split(',', 1)
                res[cur_format].append({
                    'name': name,
                    'info': get_format_info(type)
                })
            cb.battle_formats = res

        elif downmsg == 'init':
            cb.rooms[room] = Room(room, cb)

        elif downmsg == 'deinit':
            del cb.rooms[room]

        elif downmsg == 'title':
            cb.rooms[room].title = msg[2]

        elif downmsg == 'users':
            cb.rooms[room].users = []
            for user in msg[2].split(',')[1:]:
                cb.rooms[room].users.append(user)
            print(cb.rooms[room].__dict__)

        elif downmsg == ':':
            cb.rooms[room].join_time = int(msg[2])

        elif downmsg == 'j':
            if '@' in msg[2][1:]:
                user, status = msg[2].rsplit('@', 1)
            else:
                user = msg[2]
            if condense(user) not in cb.rooms[room].users:
                cb.rooms[room].users.append(user)

        elif downmsg == 'l':
            if '@' in msg[2][1:]:
                user, status = msg[2].rsplit('@', 1)
            else:
                user = msg[2]
            for existing_user in cb.rooms[room].users:
                if condense(existing_user) == condense(user):
                    cb.rooms[room].users.remove(existing_user)

        elif downmsg == 'n':
            newuser, olduser, userfound = msg[2], msg[3], False
            if '@' in newuser[1:]:
                newuser, status = newuser[1:].rsplit('@', 1)
            for user in cb.rooms[room].users:
                if condense(user) == condense(olduser):
                    cb.rooms[room].users.remove(user)
                    userfound = True
            if userfound:
                cb.rooms[room].users.append(newuser)

        elif downmsg == 'updatechallenges':
            challs = json.loads(msg[2])
            for chall in challs['challengesFrom']:
                if challs['challengesFrom'][chall] == 'gen7doublescustomgame':
                    if cb.teams:
                        team = random.choice(cb.teams['gen7doublescustomgame'])
                        await cb.send('', f'/utm {team}')
                        await cb.send('', f'/accept {chall}')

        if downmsg in ['c', 'c:', 'pm', 'j', 'l', 'html']:
            await handle_chat(msg[1:], room, cb)