def __from_json__(cls, pd, game, agent): deck = Deck.__from__to_json__(pd["deck"], hero_from_name(pd["hero"]["name"])) player = Player("whatever", deck, agent, game) hero = Hero.__from_json__(pd["hero"], player) player.hero = hero hero.player = player if hero.weapon: hero.weapon.player = player player.mana = pd["mana"] player.max_mana = pd["max_mana"] player.name = pd['name'] player.hand = [] for card_def in pd['hand']: card = card_lookup(card_def['name']) card.__from_json__(card, **card_def) card.attach(card, player) player.hand.append(card) player.graveyard = set() for card_name in pd["graveyard"]: player.graveyard.add(card_name) player.secrets = [] for secret_name in pd["secrets"]: secret = card_lookup(secret_name) secret.player = player player.secrets.append(secret) i = 0 player.minions = [] for md in pd["minions"]: minion = Minion.__from_json__(md, player, game) minion.index = i player.minions.append(minion) i += 1 return player
def read_json(self, file): """ Read a replay in the complete json format. This format is compatible with the netplay format, and is also designed to be more future proof. For more info, see the `replay format <https://github.com/danielyule/hearthbreaker/blob/master/replay_format.md>`_ :param file: Either a string or an IO object. If a string, then it is assumed to be a filename describing where a replay file is found. If an IO object, then the IO object should be opened for reading. :type file: :class:`str` or :class:`io.TextIOBase` """ from jsonschema import validate was_filename = False if 'read' not in dir(file): was_filename = True file = open(file, 'r') jd = json.load(file) validate(jd, self.schema) self.decks = [] for deck in jd['header']['decks']: deck_size = len(deck['cards']) cards = [card_lookup(deck['cards'][index % deck_size]) for index in range(0, 30)] self.decks.append( Deck(cards, hero_from_name(deck['hero']))) self.random = jd['header']['random'] self.keeps = jd['header']['keep'] if len(self.keeps) == 0: self.keeps = [[0, 1, 2], [0, 1, 2, 3]] self._moves = [Move.from_json(**js) for js in jd['moves']] if was_filename: file.close()
def __from_json__(cls, pd, game, agent): deck = Deck.__from__to_json__(pd["deck"], hero_from_name(pd["hero"]["name"])) player = Player("whatever", deck, agent, game) hero = Hero.__from_json__(pd["hero"], player) player.hero = hero hero.player = player if pd["weapon"]: player.weapon = Weapon.__from_json__(pd["weapon"], player) player.weapon.player = player player.mana = pd["mana"] player.max_mana = pd["max_mana"] player.upcoming_overload = pd["upcoming_overload"] player.current_overload = pd["current_overload"] player.name = pd["name"] player.hand = [] for card_def in pd["hand"]: card = card_lookup(card_def["name"]) card.__from_json__(card, **card_def) card.attach(card, player) player.hand.append(card) player.graveyard = pd["graveyard"] player.secrets = [] for secret_name in pd["secrets"]: secret = card_lookup(secret_name) secret.player = player player.secrets.append(secret) i = 0 player.minions = [] for md in pd["minions"]: minion = Minion.__from_json__(md, player, game) minion.index = i player.minions.append(minion) i += 1 return player
def read_json(self, file): """ Read a replay in the complete json format. This format is compatible with the netplay format, and is also designed to be more future proof. For more info, see the `replay format <https://github.com/danielyule/hearthbreaker/blob/master/replay_format.md>`_ :param file: Either a string or an IO object. If a string, then it is assumed to be a filename describing where a replay file is found. If an IO object, then the IO object should be opened for reading. :type file: :class:`str` or :class:`io.TextIOBase` """ from jsonschema import validate was_filename = False if 'read' not in dir(file): was_filename = True file = open(file, 'r') jd = json.load(file) validate(jd, self.schema) self.decks = [] for deck in jd['header']['decks']: deck_size = len(deck['cards']) cards = [ card_lookup(deck['cards'][index % deck_size]) for index in range(0, 30) ] self.decks.append(Deck(cards, hero_from_name(deck['hero']))) self.random = jd['header']['random'] self.keeps = jd['header']['keep'] if len(self.keeps) == 0: self.keeps = [[0, 1, 2], [0, 1, 2, 3]] self._moves = [Move.from_json(**js) for js in jd['moves']] if was_filename: file.close()
def read(self, file): """ Read a replay in the compact format. This format is a series of directives, and isn't as flexible or well structured as the json format (in :meth:write_json). For more info, see the `replay format <https://github.com/danielyule/hearthbreaker/blob/master/replay_format.md>`_ :param file: Either a string or an IO object. If a string, then it is assumed to be a filename describing where a replay file is to be found. If an IO object, then the IO object should be opened for reading. :type file: :class:`str` or :class:`io.TextIOBase` """ was_filename = False if 'read' not in dir(file): was_filename = True file = open(file, 'r') line_pattern = re.compile("\s*(\w*)\s*\(([^)]*)\)\s*(;.*)?$") for line in file: (move, args) = line_pattern.match(line).group(1, 2) args = [arg.strip() for arg in args.split(",")] if move == 'play': card = args[0] if len(args) > 1: target = args[1] else: target = None self._moves.append(PlayMove(hearthbreaker.proxies.ProxyCard(card), target=target)) elif move == 'summon': card = args[0] index = int(args[1]) if len(args) > 2: target = args[2] else: target = None self._moves.append(PlayMove(hearthbreaker.proxies.ProxyCard(card), index, target)) elif move == 'attack': self._moves.append(AttackMove(args[0], args[1])) elif move == 'power': if len(args) > 0 and args[0] != '': self._moves.append(PowerMove(args[0])) else: self._moves.append(PowerMove()) elif move == 'end': self._moves.append(TurnEndMove()) elif move == 'start': self._moves.append(TurnStartMove()) elif move == 'random': if len(self._moves) == 0: if len(args[0]) > 0: for num in args: self.random.append(int(num)) else: for num in args: if num.isdigit(): self._moves[-1].random_numbers.append(int(num)) else: self._moves[-1].random_numbers.append(hearthbreaker.proxies.ProxyCharacter(num)) elif move == 'deck': if len(self.decks) > 1: raise Exception("Maximum of two decks per file") deck_size = len(args) - 1 cards = [card_lookup(args[1 + index % deck_size]) for index in range(0, 30)] self.decks.append( Deck(cards, hero_from_name(args[0]))) elif move == 'keep': if len(self.keeps) > 1: raise Exception("Maximum of two keep directives per file") self.keeps.append([int(a) for a in args]) elif move == 'concede': self._moves.append(ConcedeMove()) if was_filename: file.close() if len(self.keeps) is 0: self.keeps = [[0, 1, 2], [0, 1, 2, 3]]
def read(self, file): """ Read a replay in the compact format. This format is a series of directives, and isn't as flexible or well structured as the json format (in :meth:write_json). For more info, see the `replay format <https://github.com/danielyule/hearthbreaker/blob/master/replay_format.md>`_ :param file: Either a string or an IO object. If a string, then it is assumed to be a filename describing where a replay file is to be found. If an IO object, then the IO object should be opened for reading. :type file: :class:`str` or :class:`io.TextIOBase` """ was_filename = False if 'read' not in dir(file): was_filename = True file = open(file, 'r') line_pattern = re.compile("\s*(\w*)\s*\(([^)]*)\)\s*(;.*)?$") for line in file: (move, args) = line_pattern.match(line).group(1, 2) args = [arg.strip() for arg in args.split(",")] if move == 'play': card = args[0] if len(args) > 1: target = args[1] else: target = None self._moves.append( PlayMove(hearthbreaker.proxies.ProxyCard(card), target=target)) elif move == 'summon': card = args[0] index = int(args[1]) if len(args) > 2: target = args[2] else: target = None self._moves.append( PlayMove(hearthbreaker.proxies.ProxyCard(card), index, target)) elif move == 'attack': self._moves.append(AttackMove(args[0], args[1])) elif move == 'power': if len(args) > 0 and args[0] != '': self._moves.append(PowerMove(args[0])) else: self._moves.append(PowerMove()) elif move == 'end': self._moves.append(TurnEndMove()) elif move == 'start': self._moves.append(TurnStartMove()) elif move == 'random': if len(self._moves) == 0: if len(args[0]) > 0: for num in args: self.random.append(int(num)) else: for num in args: if num.isdigit(): self._moves[-1].random_numbers.append(int(num)) else: self._moves[-1].random_numbers.append( hearthbreaker.proxies.ProxyCharacter(num)) elif move == 'deck': if len(self.decks) > 1: raise Exception("Maximum of two decks per file") deck_size = len(args) - 1 cards = [ card_lookup(args[1 + index % deck_size]) for index in range(0, 30) ] self.decks.append(Deck(cards, hero_from_name(args[0]))) elif move == 'keep': if len(self.keeps) > 1: raise Exception("Maximum of two keep directives per file") self.keeps.append([int(a) for a in args]) elif move == 'concede': self._moves.append(ConcedeMove()) if was_filename: file.close() if len(self.keeps) is 0: self.keeps = [[0, 1, 2], [0, 1, 2, 3]]