Esempio n. 1
0
class Bot:
    # Constants
    ARENA = 0
    RUMBLE = 1

    def __init__(self):
        self.config = Configuration()
        self.api = GameApi(self.config)

        self.my_hand = None
        self.enemy_hand = None
        self.field = []
        self.style = self.ARENA

    def initializeGame(self, style=0):
        resp = self.api.updateAndGetInitFile()
        # prioritize drunk and craze
        # choose item over character
        # go two wide when opponent opens with precombo
        # resp['active_battle_data']['attack_commander']        #returns 3003 for Tina
        # resp['active_battle_data']['attack_commander_level']  #returns level for hero
        # resp['active_battle_data']['defend_commander']        #returns 3003 for Tina
        # resp['active_battle_data']['defend_commander_level']  #returns level for hero
        # Update my hand and enemy's first card

        self.my_hand = Deck()
        self.my_hand.updateAsMyDeck()
        self.enemy_hand = Deck()
        self.enemy_hand.updateAsEnemyDeck()

    def getSuggestion(self):
        print("NOT IMPLEMENTED")
Esempio n. 2
0
class Deck(object):
    def __init__(self):
        config = Configuration()
        self.cache = Cache()
        self.cards = []
        self.name = ""
        self.combos = []
        self.api = GameApi(self.config)
        self.savePath = config.paths.savePath

    def updateAsMyDeck(self, context):
        if context.update:
            json = self.api.updateAndGetInitFile(context)
        else:
            json = self.api.getInit(context)

        if not ('active_battle_data' in json):
            return 0

        if str(json['active_battle_data']
               ['host_is_attacker']).lower() == 'true':
            # indices will be below 100
            lower_indice = 1
            upper_indice = 35
        else:
            # indices will be above 100
            lower_indice = 101
            upper_indice = 135

        card_map = json['active_battle_data']['card_map']
        # order = []

        self.name = json['user_data']['name']
        self.getDeckFromCardMap(card_map, lower_indice, upper_indice)
        self.updateDeckFromXML()
        return 1

    def getDeckFromCardMap(self, cardMap, lower, upper):
        self.cards = []
        order = []

        # Get index values of array
        for card in cardMap:
            card_index = int(card)
            if lower <= card_index <= upper:
                order.append(card_index)

        order.sort()

        for index in range(len(order)):
            for card in cardMap:
                if int(card) == order[index]:
                    card_to_add = Card()
                    card_to_add.id = int(cardMap[card]['unit_id'])
                    card_to_add.level = int(cardMap[card]['level'])
                    self.cards.append(card_to_add)

    def updateCardWithXML(self, card, xml):
        found = 0

        for unit in xml.findall('unit'):
            if int(unit.find('id').text) == card.id:
                found = 1
                card.updateWithXML(unit)
                break

        return found

    def updateDeckFromXML(self):
        cards = self.api.getCards()
        mythics = self.api.getMythics()
        pc = self.api.getPC()

        for card in self.cards:
            if self.updateCardWithXML(card, cards):
                continue
            elif self.updateCardWithXML(card, mythics):
                continue
            elif self.updateCardWithXML(card, pc):
                continue

    def updateCombosFromXML(self):
        cards = self.api.getCards()

        for card in self.combos:
            if self.updateCardWithXML(card, cards):
                continue
            else:
                print("{0} not found. Should be an error".format(card.id))

    def getPrintableDeckArray(self):
        rows = [[]]

        for card in self.cards:
            rows.append([
                card.name, card.level, card.attack, card.health,
                card.interpretType(),
                card.getSkillString()
            ])

        return rows

    def printDeck(self, context):
        if context.sort:
            self.cards.sort(key=lambda x: (x.type, x.name, -x.level))

        if context.title == "":
            title = self.name

        rows = [[]]
        deck_size = 0

        rows = self.getPrintableDeckArray()
        deck_size = len(rows) - 1

        tab = Texttable()

        if context.amount:
            del rows[context.amount:]

        header = ['Name', 'Level', 'Attack', 'Health', 'Type', 'Skills']

        tab.add_rows(rows)
        tab.set_cols_align(['r', 'r', 'r', 'r', 'r', 'l'])
        tab.set_cols_width([30, 5, 6, 6, 6, 50])
        tab.header(header)

        deck_output = "{0}\n".format(title)
        deck_output += "Deck Size: {0}\n".format(deck_size)
        deck_output += tab.draw()

        # TODO: Should convert deck response to JSON instead of printable table, no longer command line app

        # write to file
        writeToCsvFile(context.userId, header, rows)

        return deck_output

    def updateAsInventory(self, context):
        self.cards = []

        if context.update:
            json = self.api.updateAndGetInitFile(context)
        else:
            json = self.api.getInit(context)

        card_map = json['user_units']
        self.name = json['user_data']['name'] + "_inventory"

        # print('[Deck] inventory for ', self.name)

        for card in card_map:
            card_to_add = Card()
            card_to_add.id = int(card_map[card]['unit_id'])
            card_to_add.level = int(card_map[card]['level'])
            print('[Deck] Adding card - id: {0}, level: {1}'.format(
                card_to_add.id, card_to_add.level))
            self.cards.append(card_to_add)

        self.updateDeckFromXML()

        print('[Deck] update as inventory - returning')
        return self.cards

    def getCardIndex(self, card_id):
        index = None

        for index in range(len(self.cards)):
            if self.cards[index].id == card_id:
                index = index
                break

        return index

    def addCard(self, card_id=0, level=0, name=""):
        card = Card()
        card.id, card.level, card.name = card_id, level, name
        self.cards.append(card)

    def trimCombos(self):
        self.combos.sort(key=lambda x: (-x.rarity, x.name, -x.combo_power))

        index = 1
        while index < len(self.combos):
            if self.combos[index].name == self.combos[index - 1].name:
                del self.combos[index]
            else:
                index += 1

    def drawAllCards(self, cards):
        for index in range(0, len(cards)):
            # print('Creating images... {0}%'.format(float(int(float(index) / float(len(cards)) * 10000)) / 100))
            cache = self.cache.getCardFromCache(cards[index])

            # if cards[index].frame is None or cards[index].frame == '':
            #     print("Card {0} at index {1} has no frame. Removing cards from set".format(cards[index].id, index))
            #     del cards[index]
            #     continue

            if cache is None:
                cards[index].createCardImage()
                self.cache.saveCardToCache(cards[index])
            else:
                cards[index].setImage(cache)

    def createLargeComboImage(self, name="", width=10, quality=100):
        return self.__createDeckImage(self.combos, name, "_combos", width,
                                      quality)

    def createLargeDeckImage(self, name="", width=5, quality=100):
        return self.__createDeckImage(self.cards, name, "", width, quality)

    def compileImages(self, cards, width=5):
        count = len(cards)
        rows = 0
        cols = 0

        if count <= 0:
            return

        img_width, img_height = cards[0].image.size

        if count > width:
            cols = width
        else:
            cols = count
        while count > 0:
            count -= width
            rows += 1

        master = Image.new('RGBA', (img_width * cols, img_height * rows),
                           "white")

        r_count = 0
        c_count = 0

        for index in range(len(cards)):
            # print('Compiling images... {0}%'.format(float(int(float(index) / float(len(cards)) * 10000)) / 100))
            master.paste(cards[index].image,
                         (img_width * c_count, img_height * r_count))
            c_count += 1

            if c_count >= width:
                c_count = 0
                r_count += 1

        return master

    def filterTrait(self, trait):
        index = 0

        while index < len(self.cards):
            success = 0
            for j in range(len(self.cards[index].trait)):
                if self.cards[index].trait[j] == trait:
                    success = 1
                    break

            if not success:
                del self.cards[index]
            else:
                index += 1

        self.name += "_" + trait

    def filterShow(self, show):
        index = 0

        while index < len(self.cards):

            if not self.cards[index].show == show:
                del self.cards[index]
            else:
                index += 1

        self.name += "_" + constants.CARD_SHOW[show]

    def filterChar(self):
        index = 0

        while index < len(self.cards):

            if not (self.cards[index].type == constants.CHAR
                    or self.cards[index].type == constants.MYTHIC):
                del self.cards[index]
            else:
                index += 1

        self.name += "_" + "Characters"

    def filterItem(self):
        index = 0

        while index < len(self.cards):

            if self.cards[index].type != constants.ITEM:
                del self.cards[index]
            else:
                index += 1

        self.name += "_" + "Items"

    def filterPC(self):
        index = 0

        while index < len(self.cards):

            if self.cards[index].type != constants.PC:
                del self.cards[index]
            else:
                index += 1

        self.name += "_" + "PC"

    def __createDeckImage(self,
                          cardset,
                          name,
                          suffix="",
                          width=5,
                          quality=100):
        filename = None

        if name == "":
            name = self.name + suffix

        self.cards.sort(key=lambda x: (-x.rarity, x.type, x.name, -x.level))
        start_time = time.time()

        self.drawAllCards(cardset)
        end_time = time.time()
        print('Created images in {0}'.format(end_time - start_time))

        master = self.compileImages(cardset, width)

        if master is not None:
            print("Saving image...")
            filename = getFullPath(self.config.paths.savePath,
                                   "{0}.png".format(name))
            master.save(filename, quality=quality)

        return filename

    def findCombos(self):
        chars = []
        items = []
        combo_xml = self.api.getCombos()

        for i in range(len(self.cards)):
            if self.cards[i].type == Card.CHAR or self.cards[
                    i].type == Card.MYTHIC:
                chars.append(self.cards[i])
            elif self.cards[i].type == Card.ITEM:
                items.append(self.cards[i])

        chars.sort(key=lambda x: x.name)
        items.sort(key=lambda x: x.name)

        # Search combo xml for all available combos
        for c in combo_xml:
            for k in range(len(chars)):
                if k - 1 >= 0 and chars[k - 1].id == chars[k].id:
                    continue

                for i in range(len(items)):
                    if i - 1 >= 0 and items[i - 1].id == items[i].id:
                        continue

                    cmb = c.find('cards')

                    if cmb.get('card1') == '' or cmb.get('card2') == '':
                        continue

                    if int(cmb.get('card1')) == chars[k].id and int(
                            cmb.get('card2')) == items[i].id:
                        combo_id = int(c.find('card_id').text)
                        new_combo = Combo(chars[k], items[i], combo_id)
                        self.combos.append(new_combo)

        self.combos.sort(key=lambda x: x.char.name)
        self.updateCombosFromXML()

    def updateAsEnemyDeck(self, context):
        if (context.update):
            json = self.api.updateAndGetInitFile(context)
        else:
            json = self.api.getInit(context)

        if not ('active_battle_data' in json):
            return 0

        if str(json['active_battle_data']
               ['host_is_attacker']).lower() == 'true':
            # indices will be below 100
            lower = 101
            upper = 135
        else:
            # indices will be above 100
            lower = 1
            upper = 35

        resp = json['active_battle_data']['card_map']

        self.name = json['active_battle_data']['enemy_name']
        self.getDeckFromCardMap(resp, lower, upper)
        self.updateDeckFromXML()

        return 1
Esempio n. 3
0
class AutoBattle:
    def __init__(self):
        self.configuration = Configuration()
        self.api = GameApi(self.configuration)
        self.refill_five = 0
        self.refill_ten = 0
        self.energy = 0
        self.energy_cost = 99
        self.max_energy = 0
        self.mission_id = '178'
        self.curr_b_id = '0'
        self.mission_name = ""
        self.mission_number = ""
        self.mission_desc = ""
        self.nixons = 0
        self.watts = 0
        self.turds = 0
        self.message_log = []

    def setupBot(self):
        incorrect = 1
        if self.configuration.adventureIsland == "":

            while incorrect:
                print(
                    "Note: you can set up a default map in the settings at the top of assist.py file"
                )
                mission_id = input("Which map do you want to play (ie 26-3)?")

                print("Connecting to server...")
                success = self.updateMission(mission_id)

                if success:
                    print("{0} {1}: {2}, Energy Cost {3}".format(
                        self.mission_number, self.mission_name,
                        self.mission_desc, self.energy_cost))
                    inp = input("Correct (y/n)?")
                    if inp == 'Y' or inp == 'y':
                        incorrect = 0
        else:
            self.updateMission(self.configuration.adventureIsland)

        print("Connecting to server...")
        self.initializeUser()
        print("{0} {1}: {2}".format(self.mission_number, self.mission_name,
                                    self.mission_desc))
        print("Current Energy : {0}".format(self.energy))
        print("+5 Refills     : {0}".format(self.refill_five))
        print("+10 Refills    : {0}".format(self.refill_ten))

        five = self.refill_five + 1

        while five > self.refill_five:
            inp = input("How many +5 refills to use? ")
            five = int(inp)
            if five < 0:
                five = 0
                print("Using 0 +5 refills")

        self.refill_five -= five
        ten = self.refill_ten + 1

        while ten > self.refill_ten:
            inp = input("How many +10 refills to use? ")
            ten = int(inp)

            if ten < 0:
                ten = 0
                print("Using 0 +10 refills")

        self.refill_ten -= ten
        self.defaultDisplay(five, ten)
        print("Bot starting...")
        success = self.startBot(five, ten)

        return success

    def burnUpEnergy(self):
        incorrect = 1

        if self.configuration.adventureIsland == "":
            print(
                "Note: you can set up a default map in the settings at the top of assist.py file"
            )

            while incorrect:
                mission_id = input("Which map do you want to play (ie 26-3)?")

                print("Connecting to server...")
                success = self.updateMission(mission_id)

                if success:
                    print("{0} : {1} Energy Cost {2}".format(
                        self.mission_number, self.mission_name,
                        self.energy_cost))
                    inp = input("Correct (y/n)?")
                    if inp == 'Y' or inp == 'y':
                        incorrect = 0
        else:
            print("Updating mission info...")
            self.updateMission(self.configuration.adventureIsland)

        print("Updating user information...")
        self.initializeUser()
        self.defaultDisplay()
        print("Bot starting...")
        success = self.startBot()

        return success

    def startBot(self, five=0, ten=0):
        abort = 0
        self.turnOnAutoBattle()

        while not abort and (self.energy > self.energy_cost or five > 0
                             or ten > 0):
            while not abort and (self.energy < self.energy_cost):
                self.calibrateEnergy()
                full = 0

                while not full:
                    if ten > 0 and self.energy + 11 < self.max_energy:
                        success = self.useRefill(ten=1)
                        if success:
                            ten -= 1
                            self.message_log.append("Used +10 Refill")
                            self.energy += 10
                        else:
                            abort = 1
                    elif five > 0 and self.energy + 6 < self.max_energy:
                        success = self.useRefill(five=1)
                        if success:
                            five -= 1
                            self.energy += 5
                            self.message_log.append("Used +5 Refill")
                        else:
                            abort = 1
                    else:
                        full = 1
                    self.defaultDisplay(five, ten)
                    time.sleep(3)
            if not abort:
                self.defaultDisplay(five, ten)
                self.energy -= self.energy_cost
                self.fightMission()
                self.defaultDisplay(five, ten)
                time.sleep(3)

        return not abort

    def defaultDisplay(self, five=0, ten=0):
        print("{0} {1}: {2}".format(self.mission_number, self.mission_name,
                                    self.mission_desc))
        print("Current Energy : {0}".format(self.energy))
        print("+5 Refills     : {0}".format(self.refill_five))
        print("+10 Refills    : {0}".format(self.refill_ten))

        if five:
            print("Use {0} +5 refills".format(five))
        if ten:
            print("Use {0} +10 refills".format(ten))

        print('Totals: Nixons: {0}, Watts: {1}, Turds: {2}'.format(
            self.nixons, self.watts, self.turds))
        for index in range(len(self.message_log)):
            print(self.message_log[index])

    def calibrateEnergy(self):
        json = self.api.updateAndGetInitFile()
        self.energy = int(json['user_data']['energy'])
        self.refill_five = int(json['user_items']['1002']['number'])
        self.refill_ten = int(json['user_items']['1003']['number'])
        self.max_energy = int(json['user_data']['max_energy'])

    def testing(self):
        self.mission_id = '178'
        if self.fightMission():
            print("Testing finished successfully")

    def fightMission(self):
        print("starting battle vs {0}".format(self.mission_name))
        success = self.startBattle()

        if success:
            print("ending battle vs {0}".format(self.mission_name))
            success, nixons, watts, turds = self.endBattle()

        if success:
            self.nixons += nixons
            self.watts += watts
            self.turds += turds
            mess = 'you won {0} nixons, {1} watts, and {2} turds'.format(
                nixons, watts, turds)
            self.message_log.append(mess)
        else:
            success = 0

        return success

    def turnOnAutoBattle(self):
        resp = self.api.turnOnAutoBattle()
        success = 0

        if resp['result']:
            print("auto battle enabled")
            success = 1
        else:
            print("FAILURE")
            print(resp)
            success = 0

        return success

    def turnOffAutoBattle(self):
        resp = self.api.turnOffAutoBattle()
        success = 0

        if resp['result']:
            print("auto battle disabled")
            success = 1
        else:
            print("FAILURE")
            print(resp)
            success = 0

        return success

    def startBattle(self):
        response = self.api.startAdventureMission(self.mission_id)
        success = 0

        if response['result']:

            self.curr_b_id = str(response['battle_data']['battle_id'])
            success = 1
        else:
            print("FAILURE")
            print(response)
            success = 0

        return success

    def endBattle(self):
        response = self.api.finishAdventureBattle(self.curr_b_id)
        success = 0
        nixons = 0
        watts = 0
        turds = 0

        if response['result']:
            print("Battle ending...")
            nixons = response['battle_data']['rewards'][0]['gold']
            success = 1

            try:
                turds = response['battle_data']['rewards'][0]['items'][0][
                    'number']
                watts = response['battle_data']['rewards'][0]['sp']
                success = 1
            except:
                turds, watts = 0, 0
        else:
            print("FAILURE")
            print(response)
            success = 0

        return success, nixons, watts, turds

    def initializeUser(self):
        json = self.api.updateAndGetInitFile()
        self.energy = int(json['user_data']['energy'])
        self.refill_five = int(json['user_items']['1002']['number'])
        self.refill_ten = int(json['user_items']['1003']['number'])
        self.max_energy = int(json['user_data']['max_energy'])

    def updateMission(self, mission):
        counter = 0
        lst = []

        while counter < len(mission) - 1 and mission[counter] != '-':
            counter += 1
        if counter == 2:
            mission_left = 10 * int(mission[0]) + int(mission[1])
        elif counter == 1:
            mission_left = int(mission[0])
        else:
            return 0

        mission_right = int(mission[len(mission) - 1])

        if mission_left > 30:
            mission_left = 30
        if mission_left < 0:
            mission_left = 1
        if mission_right > 3:
            mission_right = 3
        if mission_right < 1:
            mission_right = 1

        self.mission_id = str(mission_left * 3 + 101 + mission_right - 4)
        self.mission_number = str(mission_left) + "-" + str(mission_right)

        missions = self.api.getMissions()

        for mission in missions.findall('mission'):
            if mission.find('id').text == self.mission_id:
                self.energy_cost = int(
                    int(mission.find('energy').text) +
                    float(mission.find('energy_per_level').text) * 12)
                self.mission_name = mission.find('name').text
                self.mission_desc = mission.find('desc').text
        return 1

    def useRefill(self, five=0, ten=0):
        while ten:
            print("Using +10 refill")
            self.api.useEnergyPlusTen()
            self.refill_ten -= 1
            ten -= 1
        while five:
            print("Using +5 refill")
            self.api.useEnergyPlusFive()
            five -= 1
            self.refill_five -= 1
        return 1

    def updateEnergy(self):
        json = self.api.updateAndGetInitFile()
        self.energy = int(json['user_data']['energy'])