def main(): deck1 = random_draft(hero=MAGE) deck2 = random_draft(hero=WARRIOR) player1 = Player(name="Player1") player1.prepare_deck(deck1, MAGE) player2 = Player(name="Player2") player2.prepare_deck(deck2, WARRIOR) game = Game(players=(player1, player2)) game.start() while True: heropower = game.current_player.hero.power # always play the hero power, just for kicks if heropower.is_playable(): if heropower.has_target(): heropower.play(target=random.choice(heropower.targets)) else: heropower.play() # iterate over our hand and play whatever is playable for card in game.current_player.hand: if card.is_playable(): if card.has_target(): card.play(target=random.choice(card.targets)) else: card.play() else: print("Not playing", card) # Randomly attack with whatever can attack for character in game.current_player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) game.end_turn()
def play_full_game(): deck1 = random_draft(hero=MAGE) deck2 = random_draft(hero=WARRIOR) player1 = Player("Player1", deck1, MAGE) player2 = Player("Player2", deck2, WARRIOR) game = Game(players=(player1, player2)) game.start() for player in game.players: # print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) try: while True: player = game.current_player heropower = player.hero.power if heropower.is_usable() and random.random() < 0.1: if heropower.has_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() continue # iterate over our hand and play whatever is playable for card in player.hand: if card.is_playable() and random.random() < 0.5: target = None if card.choose_cards: card = random.choice(card.choose_cards) if card.has_target(): target = random.choice(card.targets) # print("Playing %r on %r" % (card, target)) card.play(target=target) if player.choice: choice = random.choice(player.choice.cards) # print("Choosing card %r" % (choice)) player.choice.choose(choice) continue # Randomly attack with whatever can attack for character in player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) continue game.end_turn() except GameOver: return game # print("Game completed normally in " + str(game.turn) + " turns.") return game
def play_full_game(): deck1 = random_draft(hero=MAGE) deck2 = random_draft(hero=WARRIOR) player1 = Player(name="Player1") player1.prepare_deck(deck1, MAGE) player2 = Player(name="Player2") player2.prepare_deck(deck2, WARRIOR) game = Game(players=(player1, player2)) game.start() for player in game.players: print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) while True: player = game.current_player heropower = player.hero.power if heropower.is_usable() and percent_chance(10): if heropower.has_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() continue # iterate over our hand and play whatever is playable for card in player.hand: if card.is_playable() and percent_chance(50): target = None if card.choose_cards: card = random.choice(card.choose_cards) if card.has_target(): target = random.choice(card.targets) print("Playing %r on %r" % (card, target)) card.play(target=target) continue # Randomly attack with whatever can attack for character in player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) continue if player.choice: choice = random.choice(player.choice.cards) print("Choosing card %r" % (choice)) player.choice.choose(choice) continue game.end_turn()
def play_game(hero1, hero2): deck1 = decks[hero1] player1 = Player(name="Player1") player1.prepare_deck(deck1, hero1) deck2 = decks[hero2] player2 = Player(name="Player2") player2.prepare_deck(deck2, hero2) game = Game(players=(player1, player2)) game.start() player1.choice.choose(*[]) player2.choice.choose(*[]) while game.state != State.COMPLETE: try: heropower = game.current_player.hero.power if heropower.is_usable(): if heropower.has_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() for card in game.current_player.hand: if card.is_playable(): target = None if card.choose_cards: card = random.choice(card.choose_cards) if card.has_target(): target = random.choice(card.targets) card.play(target=target) for character in game.current_player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) game.end_turn() except GameOver: pass if player1.playstate == PlayState.TIED: return None if player1.playstate == PlayState.WON: return player1 return player2
def main(): deck1 = random_draft(hero=MAGE) deck2 = random_draft(hero=WARRIOR) player1 = Player(name="Player1") player1.prepare_deck(deck1, MAGE) player2 = Player(name="Player2") player2.prepare_deck(deck2, WARRIOR) game = Game(players=(player1, player2)) game.start() for player in game.players: print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) while True: heropower = game.current_player.hero.power # always play the hero power, just for kicks if heropower.is_usable(): if heropower.has_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() # iterate over our hand and play whatever is playable for card in game.current_player.hand: if card.is_playable(): target = None choice = None if card.has_target(): target = random.choice(card.targets) if card.data.choose_cards: choice = random.choice(card.data.choose_cards) card.play(target=target, choose=choice) else: print("Not playing", card) # Randomly attack with whatever can attack for character in game.current_player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) game.end_turn()
def main(): deck1 = random_draft(hero=MAGE) deck2 = random_draft(hero=WARRIOR) player1 = Player(name="Player1") player1.prepare_deck(deck1, MAGE) player2 = Player(name="Player2") player2.prepare_deck(deck2, WARRIOR) game = Game(players=(player1, player2)) game.start() for player in game.players: print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) while True: heropower = game.current_player.hero.power # always play the hero power, just for kicks if heropower.is_usable(): if heropower.has_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() # iterate over our hand and play whatever is playable for card in game.current_player.hand: if card.is_playable(): target = None if card.choose_cards: card = random.choice(card.choose_cards) if card.has_target(): target = random.choice(card.targets) print("Playing %r on %r" % (card, target)) card.play(target=target) else: print("Not playing", card) # Randomly attack with whatever can attack for character in game.current_player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) game.end_turn()
def play_game(hero1, hero2): open(log_file, 'w').close() deck1 = random_draft(hero=hero1) deck1[0] = "EX1_160a" player1 = Player(name="Player1") player1.prepare_deck(deck1, hero1) deck2 = random_draft(hero=hero2) deck2[0] = "EX1_160a" player2 = Player(name="Player2") player2.prepare_deck(deck2, hero2) game = Game(players=(player1, player2)) game.start() player1.choice.choose(*[]) player2.choice.choose(*[]) while game.state != State.COMPLETE: try: heropower = game.current_player.hero.power if heropower.is_usable(): if heropower.has_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() for card in game.current_player.hand: if card.is_playable(): target = None if card.choose_cards: card = random.choice(card.choose_cards) if card.has_target(): target = random.choice(card.targets) card.play(target=target) for character in game.current_player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) game.end_turn() except GameOver: pass
def random_play(game: Game) -> Game: player = game.current_player while True: heropower = player.hero.power if heropower.is_usable() and random.random() < 0.1: if heropower.requires_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() continue # iterate over our hand and play whatever is playable for card in player.hand: if card.is_playable() and random.random() < 0.5: target = None if card.must_choose_one: card = random.choice(card.choose_cards) if card.requires_target(): target = random.choice(card.targets) card.play(target=target) if player.choice: choice = random.choice(player.choice.cards) player.choice.choose(choice) continue # Randomly attack with whatever can attack for character in player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) break game.end_turn() return game
class HearthState: """ A state of the game, i.e. the game board. """ def __init__(self): self.playerJustMoved = 2 # At the root pretend the player just moved is p2 - p1 has the first move random.seed(1857) # The idea of adjacent cards it to ignore minion placement if none of these cards can be found, since it doesn't # matter. #adjacent_cards = ["Dire Wolf Alpha", "Ancient Mage", "Defender of Argus", "Sunfury Protector", # "Flametongue Totem", "Explosive Shot", "Cone of Cold", "Betrayal", "Void Terror", # "Unstable Portal", "Wee Spellstopper", "Piloted Shredder", "Piloted Sky Golem", # "Recombobulator", "Foe Reaper 4000", "Nefarian"] #self.adjacent_cards = adjacent_cards self.player1 = None self.hero1 = MAGE self.deck1 = [] self.player2 = None self.hero2 = None self.deck2 = [] self.game = None # Simple Arcane Missiles lethal test #self.deck1 = ["EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277"] #self.hero1 = MAGE #self.player1 = Player("one", self.deck1, self.hero1) #self.deck2 = ["EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277"] #self.hero2 = MAGE #self.player2 = Player("two", self.deck2, self.hero2) #self.game = Game(players=(self.player1, self.player2)) #self.game.start() #for player in self.game.players: # if player.choice: # player.choice.choose() #self.game.players[0].hero.hit(24) #self.game.players[1].hero.hit(24) def Clone(self): """ Create a deep clone of this game state. """ st = HearthState() st.playerJustMoved = self.playerJustMoved st.player1 = self.player1 st.hero1 = self.hero1 st.deck1 = copy.copy(self.deck1) st.player2 = self.player2 st.hero2 = self.hero2 st.deck2 = copy.copy(self.deck2) #st.game = copy.copy(self.game) st.game = copy.deepcopy(self.game) return st def DoMove(self, move): """ Update a state by carrying out the given move. """ if self.game is not None: assert self.game.current_player.playstate == PlayState.PLAYING if self.game.current_player is not None: if self.game.current_player.name == "one": self.playerJustMoved = 1 else: self.playerJustMoved = 2 try: if move[0] == MOVE.PRE_GAME: self.player1 = Player("one", self.deck1, self.hero1) self.player2 = Player("two", self.deck2, self.hero2) self.game = Game(players=(self.player1, self.player2)) self.game.start() # TODO: Mulligan for player in self.game.players: if player.choice: player.choice.choose() elif move[0] == MOVE.PICK_CLASS: self.hero2 = move[1] elif move[0] == MOVE.PICK_CARD: if len(self.deck1) < 30: self.deck1.append(move[1].id) else: self.deck2.append(move[1].id) elif move[0] == MOVE.MULLIGAN: self.game.current_player.choice.choose(*move[1]) elif move[0] == MOVE.END_TURN: self.game.end_turn() elif move[0] == MOVE.HERO_POWER: heropower = self.game.current_player.hero.power if move[3] is None: heropower.use() else: heropower.use(target=heropower.targets[move[3]]) elif move[0] == MOVE.PLAY_CARD: card = self.game.current_player.hand[move[2]] if move[3] is None: card.play() else: card.play(target=card.targets[move[3]]) elif move[0] == MOVE.MINION_ATTACK: minion = self.game.current_player.field[move[2]] minion.attack(minion.targets[move[3]]) elif move[0] == MOVE.HERO_ATTACK: hero = self.game.current_player.hero hero.attack(hero.targets[move[3]]) elif move[0] == MOVE.CHOICE: self.game.current_player.choice.choose(move[1]) else: raise NameError("DoMove ran into unclassified card", move) except: return def GetMoves(self): """ Get all possible moves from this state. """ if self.game is not None: if self.game.current_player.playstate != PlayState.PLAYING: return [] valid_moves = [] # Move format is [enum, card, index of card in hand, target index] if self.game is None and len(self.deck1) == 30 and len(self.deck2) == 30: valid_moves.append([MOVE.PRE_GAME]) elif self.game is None and len(self.deck1) == 30 and self.hero2 is None: valid_moves.append([MOVE.PICK_CLASS, DRUID]) valid_moves.append([MOVE.PICK_CLASS, HUNTER]) valid_moves.append([MOVE.PICK_CLASS, MAGE]) valid_moves.append([MOVE.PICK_CLASS, PALADIN]) valid_moves.append([MOVE.PICK_CLASS, PRIEST]) valid_moves.append([MOVE.PICK_CLASS, ROGUE]) valid_moves.append([MOVE.PICK_CLASS, SHAMAN]) valid_moves.append([MOVE.PICK_CLASS, WARLOCK]) valid_moves.append([MOVE.PICK_CLASS, WARRIOR]) elif self.game is None and len(self.deck1) < 30 or len(self.deck2) < 30: collection = [] exclude = [] if len(self.deck1) < 30: hero = cards.db[self.hero1] deck = self.deck1 else: hero = cards.db[self.hero2] deck = self.deck2 for card in cards.db.keys(): if card in exclude: continue cls = cards.db[card] if not cls.collectible: continue if cls.type == CardType.HERO: # Heroes are collectible... continue if cls.card_class and cls.card_class != hero.card_class: continue collection.append(cls) for card in collection: if card.rarity == Rarity.LEGENDARY and card.id in deck: continue elif deck.count(card.id) < Deck.MAX_UNIQUE_CARDS: valid_moves.append([MOVE.PICK_CARD, card]) elif self.game.current_player.choice is not None: for card in self.game.current_player.choice.cards: valid_moves.append([MOVE.CHOICE, card]) else: # Play card for card in self.game.current_player.hand: dupe = False for i in range(len(valid_moves)): if valid_moves[i][1].id == card.id: dupe = True break if not dupe: if card.is_playable(): if card.has_target(): for t in range(len(card.targets)): valid_moves.append([MOVE.PLAY_CARD, card, self.game.current_player.hand.index(card), t]) else: valid_moves.append([MOVE.PLAY_CARD, card, self.game.current_player.hand.index(card), None]) # Hero Power heropower = self.game.current_player.hero.power if heropower.is_usable(): if heropower.has_target(): for t in range(len(heropower.targets)): valid_moves.append([MOVE.HERO_POWER, None, None, t]) else: valid_moves.append([MOVE.HERO_POWER, None, None, None]) # Minion Attack for minion in self.game.current_player.field: if minion.can_attack(): for t in range(len(minion.targets)): valid_moves.append([MOVE.MINION_ATTACK, minion, self.game.current_player.field.index(minion), t]) # Hero Attack hero = self.game.current_player.hero if hero.can_attack(): for t in range(len(hero.targets)): valid_moves.append([MOVE.HERO_ATTACK, hero, None, t]) valid_moves.append([MOVE.END_TURN]) return valid_moves def GetResult(self, playerjm): """ Get the game result from the viewpoint of playerjm. """ if self.game.players[0].hero.health <= 0 and self.game.players[1].hero.health <= 0: return 0.1 elif self.game.players[playerjm - 1].hero.health <= 0: # loss return 0 elif self.game.players[2 - playerjm].hero.health <= 0: # win return pow(0.99, self.game.turn) else: # Should not be possible to get here unless we terminate the game early. return 0.1 def __repr__(self): try: s = "Turn: " + str(self.game.turn) s += "\n[" + str(self.game.players[0].hero.health) + " hp ~ " + str(len(self.game.players[0].hand)) + " in hand ~ " + str(self.game.players[0].tempMana) + "/" + str(self.game.players[0].maxMana) + " mana] " #s += "\n[" + str(self.game.players[0].hero.health) + " hp ~ " + str(len(self.game.players[0].hand)) + " in hand ~ " + str(self.game.players[0].deck.left) + "/" + str(len(self.game.players[0].deck.cards)) + " in deck ~ " + str(self.game.players[0].mana) + "/" + str(self.game.players[0].max_mana) + " mana] " for minion in self.game.players[0].field: s += str(minion.atk) + "/" + str(minion.health) + ":" s += "\n[" + str(self.game.players[1].hero.health) + " hp ~ " + str(len(self.game.players[1].hand)) + " in hand ~ " + str(self.game.players[1].tempMana) + "/" + str(self.game.players[1].maxMana) + " mana] " #s += "\n[" + str(self.game.players[1].hero.health) + " hp ~ " + str(len(self.game.players[1].hand)) + " in hand ~ " + str(self.game.players[1].deck.left) + "/" + str(len(self.game.players[1].deck.cards)) + " in deck ~ " + str(self.game.players[1].mana) + "/" + str(self.game.players[1].max_mana) + " mana] " for minion in self.game.players[1].field: s += str(minion.atk) + "/" + str(minion.health) + ":" s += "\n" + "Current Player: " + str(self.game.currentPlayer) return s except: s = "Deck 1: " + ", ".join(self.deck1) s += "\nDeck 2: " + ", ".join(self.deck2) return s
def find_card_pair(onlyresult=1): card_class = CardClass.MAGE #カードクラスを設定することは必須 allCards = get_all_cards(card_class, costMax=2) vanillas = get_all_vanillas(allCards) nonVanillas = get_all_non_vanillas(allCards) spells = get_all_spells(allCards) #良いカードペアを漠然と探す旅に出る2枚は呪文カードしばり for matchNumber in range(10): count1 = 0 count2 = 0 #ヒーローパワーを消す、というのもよいかも。 nonvanillaName1 = random.choice(nonVanillas) nonvanilla1 = nonvanillaName1.id nonvanillaName2 = random.choice(spells) #この呪文によって、まえのカードが活かされるかどうか nonvanilla2 = nonvanillaName2.id print(" specific cards : %r%r" % (nonvanillaName1, nonvanillaName2)) for repeat in range(25): if onlyresult == 0: print(" GAME %d" % repeat, end=" -> ") #set decks and players deck1 = [] position = random.randint(1, 7) for i in range(position): deck1.append((random.choice(vanillas)).id) deck1.append(nonvanilla1) deck1.append(nonvanilla2) for i in range(8 - position): #デッキは10枚 deck1.append(random.choice(vanillas).id) player1 = Player("Player1", deck1, card_class.default_hero) deck2 = copy.deepcopy(deck1) random.shuffle(deck2) player2 = Player("Player2", deck2, card_class.default_hero) #set a game game = Game(players=(player1, player2)) game.start() for player in game.players: #print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) game.player1.hero.max_health = 10 game.player2.hero.max_health = 10 turnNumber = 0 if onlyresult == 0: print("Turn ", end=':') while True: turnNumber += 1 if onlyresult == 0: print(turnNumber, end=":") #StandardRandom(game)#ここはもう少し賢くする weight = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] weight[0] = weight[1] = 5 weight[26] = 10 weight[2] = weight[3] = weight[6] = weight[7] = 5 weight[10] = weight[11] = weight[12] = weight[13] = 5 StandardStep1(game, debugLog=False) if game.state != State.COMPLETE: try: game.end_turn() except GameOver: #まれにおこる pass if game.state == State.COMPLETE: if game.current_player.playstate == PlayState.WON: winner = game.current_player.name break elif game.current_player.playstate == PlayState.LOST: winner = game.current_player.opponent.name break else: winner = "DRAW" break if onlyresult == 0: print("%s won." % winner) if winner == "Player1": if onlyresult == 1: print("O", end=".") count1 += 1 elif winner == "Player2": if onlyresult == 1: print("X", end=".") count2 += 1 print("(%d : %d)" % (count1, count2), end=" ") #25戦で10点差があれば有意な差あり if count1 - count2 >= 10: print("Significant") else: print("") pass
def investigate_card_pair(onlyresult=0): card_class = CardClass.HUNTER allCards = get_all_cards(card_class) vanillas = get_all_vanillas(allCards) nonVanillas = get_all_non_vanillas(allCards) count1 = 0 count2 = 0 #ヒーローパワーを消す、というのもよいかも。 #良いカードペアを漠然と探す旅に出る? nonvanilla1 = 'EX1_045' #random.choice(nonVanillas).id#自分で指定してもよい nonvanilla2 = 'EX1_332' #random.choice(nonVanillas).id# #古代の番人:EX1_045:攻撃できない。 #沈黙:EX1_332:ミニオン1体を沈黙させる print(" specific cards : %r%r" % (nonvanilla1, nonvanilla2)) for repeat in range(50): print(" GAME %d" % repeat, end=" -> ") #set decks and players deck1 = [] position = random.randint(1, 7) for i in range(position): deck1.append((random.choice(vanillas)).id) deck1.append(nonvanilla1) deck1.append(nonvanilla2) for i in range(8 - position): #デッキは10枚 deck1.append(random.choice(vanillas).id) player1 = Player("AAAA", deck1, card_class.default_hero) deck2 = copy.deepcopy(deck1) random.shuffle(deck2) player2 = Player("BBBB", deck2, card_class.default_hero) #set a game game = Game(players=(player1, player2)) game.start() for player in game.players: #print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) game.player1.hero.max_health = 10 # ヒーローのHPは10 game.player2.hero.max_health = 10 turnNumber = 0 print("Turn ", end=':') while True: turnNumber += 1 print(turnNumber, end=":") weight = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] weight[0] = weight[1] = 5 weight[26] = 10 weight[2] = weight[3] = weight[6] = weight[7] = 5 weight[10] = weight[11] = weight[12] = weight[13] = 5 StandardStep1(game, debugLog=False) #StandardRandom(game,debugLog=True) #ここはもう少し賢い人にやってほしい if game.state != State.COMPLETE: try: game.end_turn() except GameOver: #まれにおこる pass else: if game.current_player.playstate == PlayState.WON: winner = game.current_player.name break elif game.current_player.playstate == PlayState.LOST: winner = game.current_player.opponent.name break else: winner = "DRAW" break print("%s won." % winner) if winner == "AAAA": count1 += 1 elif winner == "BBBB": count2 += 1 print("%d : %d" % (count1, count2))
class HSEnv: def __init__(self, render): cards.db.initialize() # Create a game with the standardized decks if render: self.renderer = BoardRenderer() self.reset() def start_game(self): self.game.start() # Play the game """TODO: Implement Networked version of mulligan""" for player in self.game.players: print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) def draft_mage(self): deck = [] deck.append(Card("EX1_277").id) #Arcane Missiles deck.append(Card("EX1_277").id) #Arcane Missiles deck.append(Card("NEW1_012").id) #Mana Wyrm deck.append(Card("NEW1_012").id) #Mana Wyrm deck.append(Card("CS2_027").id) #Mirror Image deck.append(Card("CS2_027").id) #Mirror Image deck.append(Card("EX1_066").id) #Acidic Swamp Ooze deck.append(Card("EX1_066").id) #Acidic Swamp Ooze deck.append(Card("CS2_025").id) #Arcane Explosion deck.append(Card("CS2_025").id) #Arcane Explosion deck.append(Card("CS2_024").id) #Frostbolt deck.append(Card("CS2_024").id) #Frostbolt deck.append(Card("CS2_142").id) #Kobold Geomancer deck.append(Card("CS2_142").id) #Kobold Geomancer deck.append(Card("EX1_608").id) #Sorcerer's Apprentice deck.append(Card("EX1_608").id) #Sorcerer's Apprentice deck.append(Card("CS2_023").id) #Arcane Intellect deck.append(Card("CS2_023").id) #Arcane Intellect deck.append(Card("CS2_029").id) #Fireball deck.append(Card("CS2_029").id) #Fireball deck.append(Card("CS2_022").id) #Polymorph deck.append(Card("CS2_022").id) #Polymorph deck.append(Card("CS2_033").id) #Water Elemental deck.append(Card("CS2_033").id) #Water Elemental deck.append(Card("CS2_155").id) #Archmage deck.append(Card("CS2_155").id) #Archmage deck.append(Card("EX1_559").id) #Archmage Antonidas deck.append(Card("CS2_032").id) #Flamestrike deck.append(Card("CS2_032").id) #Flamestrike deck.append(Card("EX1_279").id) #Pyroblast return deck def create_board_state(self): boardstate = [] # Player 1 mana boardstate.append(self.game.player1.max_mana - self.game.player1.overload_locked) # Player 2 mana boardstate.append(self.game.player2.max_mana - self.game.player2.overload_locked) # Player 1 handSize boardstate.append(self.game.player1.hand.__len__()) # Player 2 handSize boardstate.append(self.game.player2.hand.__len__()) # Player 2 hero health boardstate.append(self.game.player1.hero.health + self.game.player2.hero.armor) # Player 2 Hero Attack value if self.game.player2.weapon is not None: boardstate.append(self.game.player2.hero.atk + self.game.player2.weapon.atk) else: boardstate.append(self.game.player2.hero.atk) # Player 1 hero health boardstate.append(self.game.player1.hero.health + self.game.player2.hero.armor) # Player 1 Weapon if self.game.player1.weapon is not None: # Player 1 Weapon Health boardstate.append(self.game.player1.weapon.health_attribute) # Player 1 Weapon Attack boardstate.append(self.game.player1.weapon.atk) else: boardstate.append(0) boardstate.append(0) # Player 2 Weapon if self.game.player2.weapon is not None: # Player 2 Weapon Health boardstate.append(self.game.player2.weapon.health_attribute) # Player 2 Weapon Attack boardstate.append(self.game.player2.weapon.atk) else: boardstate.append(0) boardstate.append(0) # Player 2 HAND for index in range(10): if (self.game.player2.hand.__len__() > index): # Card ID boardstate.append( sorted(cards.db).index(self.game.player2.hand[index].id)) # Card Type boardstate.append(int(self.game.player2.hand[index].data.type)) # Mana Cost boardstate.append(self.game.player2.hand[index].data.cost) if self.game.player2.hand[index].data.type is ( CardType.MINION or CardType.WEAPON): # Card ATK boardstate.append(self.game.player2.hand[index].data.atk) # Card HEALTH boardstate.append( self.game.player2.hand[index].data.health) else: boardstate.append(0) boardstate.append(0) else: for i in range(5): boardstate.append(0) # Boardtate Player 2 Side for index in range(7): if (self.game.player2.field.__len__() > index): # Card ID boardstate.append( sorted(cards.db).index(self.game.player2.field[index].id)) # Minion ATK boardstate.append(self.game.player2.field[index].atk) # Minion Health boardstate.append(self.game.player2.field[index].health) # Minion CanAttack if self.game.player2.field[index].can_attack(): boardstate.append(1) else: boardstate.append(0) else: for i in range(4): boardstate.append(0) # Boardtate Player 1 Side for index in range(7): if (self.game.player1.field.__len__() > index): # Card ID boardstate.append( sorted(cards.db).index(self.game.player1.field[index].id)) # Minion ATK boardstate.append(self.game.player1.field[index].atk) # Minion Health boardstate.append(self.game.player1.field[index].health) else: for i in range(3): boardstate.append(0) return boardstate def play_turn_random(self): player = self.game.current_player while True: heropower = player.hero.power if heropower.is_usable() and random.random() < 0.1: if heropower.requires_target(): heropower.use(target=random.choice(heropower.targets)) else: heropower.use() continue # iterate over our hand and play whatever is playable for card in player.hand: if card.is_playable() and random.random() < 0.1: target = None if card.must_choose_one: card = random.choice(card.choose_cards) if card.requires_target(): target = random.choice(card.targets) print("Playing %r on %r" % (card, target)) card.play(target=target) if player.choice: choice = random.choice(player.choice.cards) print("Choosing card %r" % (choice)) player.choice.choose(choice) continue # Randomly attack with whatever can attack for character in player.characters: if character.can_attack(): character.attack(random.choice(character.targets)) break self.game.end_turn() return game def play_turn_untrained_network(self): while True: action = random.randrange(0, 34, 1) if action is not None: player = self.game.current_player if action is 0: self.game.end_turn() return elif action is 1: if player.hero.can_attack(): player.hero.attack( target=random.choice(player.hero.targets)) elif action is 2: heropower = player.hero.power if heropower.is_usable(): if heropower.requires_target(): heropower.use( target=random.choice(heropower.targets)) else: heropower.use() elif action is 3: # find the coin and play it for card in player.hand: if card.data.id == THE_COIN and card.is_playable(): card.play() else: to_play = self.draft_mage()[action - 4] for card in player.hand: if card.id == to_play and card.is_playable(): target = None if card.must_choose_one: card = random.choice(card.choose_cards) if card.requires_target(): target = random.choice(card.targets) print("Playing %r on %r" % (card, target)) card.play(target=target) if player.choice: choice = random.choice(player.choice.cards) print("Choosing card %r" % (choice)) player.choice.choose(choice) break for minion in player.field: if minion.id == to_play and minion.can_attack(): target = None minion.attack( target=random.choice(minion.attack_targets)) if self.check_remaining_actions(): return def check_remaining_actions(self): player = self.game.current_player # check if there are any more possible actions heropower = player.hero.power if heropower.is_usable(): return False # iterate over our hand and play whatever is playable for card in player.hand: if card.is_playable(): return False # Randomly attack with whatever can attack for character in player.characters: if character.can_attack(): return False # NO MORE ACTIONS POSSIBLE - end turn self.game.end_turn() return True def get_action_meanings(self): strings = list() strings.append("END_TURN") strings.append("HERO") strings.append("HERO_POWER") strings.append("THE_COIN") for card in self.draft_mage(): strings.append(Card(card).data.name) return strings def reset(self): from fireplace.game import Game from fireplace.player import Player deck1 = self.draft_mage() deck2 = self.draft_mage() player1 = Player("Player1", deck1, CardClass.MAGE.default_hero) player2 = Player("Player2", deck2, CardClass.MAGE.default_hero) self.game = Game(players=(player1, player2)) self.start_game() self.new_game = True return self.create_board_state() def step(self, action, targeting_agent, learn_to_play_cards): if self.game.ended: if learn_to_play_cards: return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state(), self.calculate_reward( ), self.is_game_over() if self.game.current_player is not self.game.player2: self.play_turn_untrained_network() if learn_to_play_cards: return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state(), self.calculate_reward( ), self.is_game_over() if action is not None: player = self.game.current_player if action is 0: self.game.end_turn() if learn_to_play_cards: return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state(), self.calculate_reward( ), self.is_game_over() elif action is 1: if player.hero.can_attack(): targeting_agent.run(action, self.new_game) self.new_game = False self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state(), 0, self.is_game_over( ) else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over() if learn_to_play_cards: self.game.end_turn() return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward() - 100, self.is_game_over() elif action is 2: heropower = player.hero.power if heropower.is_usable(): if heropower.requires_target(): #targeting_agent.run(action, self.new_game) heropower.play(target=random.choice(heropower.targets)) self.new_game = False self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state( ), 1, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over() else: heropower.use() self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state( ), 1, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over() if learn_to_play_cards: self.game.end_turn() return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward() - 100, self.is_game_over() elif action is 3: # find the coin and play it for card in player.hand: if card.data.id == THE_COIN and card.is_playable(): card.play() self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state( ), 1, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over() if learn_to_play_cards: self.game.end_turn() return self.create_board_state(), 0, self.is_game_over( ) else: return self.create_board_state( ), self.calculate_reward() - 100, self.is_game_over() else: to_play = self.draft_mage()[action - 4] for card in player.hand: if card.id == to_play and card.is_playable(): target = None if card.must_choose_one: card = random.choice(card.choose_cards) if card.requires_target(): #targeting_agent.run(action, self.new_game) card.play(target=random.choice(card.targets)) self.new_game = False if player.choice: choice = random.choice(player.choice.cards) print("Choosing card %r" % (choice)) player.choice.choose(choice) self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state( ), 1, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over( ) else: card.play(target=target) print("Playing %r on %r" % (card, target)) if player.choice: choice = random.choice(player.choice.cards) print("Choosing card %r" % (choice)) player.choice.choose(choice) self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state( ), 1, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over( ) for minion in player.field: if minion.id == to_play and minion.can_attack(): #targeting_agent.run(action, self.new_game) minion.attack(random.choice(minion.targets)) self.new_game = False self.check_remaining_actions() if learn_to_play_cards: return self.create_board_state( ), 1, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward(), self.is_game_over() if learn_to_play_cards: self.game.end_turn() return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state( ), self.calculate_reward() - 100, self.is_game_over() if self.game.ended: if learn_to_play_cards: self.game.end_turn() return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state(), self.calculate_reward( ), self.is_game_over() #If there are no more actions pass the turn self.check_remaining_actions() if learn_to_play_cards: self.game.end_turn() return self.create_board_state(), 0, self.is_game_over() else: return self.create_board_state(), self.calculate_reward( ), self.is_game_over() def calculate_reward(self): reward = 0 reward += self.game.player2.hero.health reward += self.game.player2.hero.armor reward += self.game.player2.hero.atk if self.game.player2.weapon is not None: reward += self.game.player2.weapon.health reward += self.game.player2.weapon.atk reward -= self.game.player1.hero.health reward -= self.game.player1.hero.armor reward -= self.game.player1.hero.atk if self.game.player1.weapon is not None: reward -= self.game.player1.weapon.health reward -= self.game.player1.weapon.atk for minion in self.game.player2.field: reward += minion.health reward += minion.atk for minion in self.game.player1.field: reward -= minion.health reward -= minion.atk return reward def is_game_over(self): return self.game.ended def render(self): """ TODO: ADD RENDERING """ self.renderer.render_board_state(game=self.game) def get_lives(self): return self.game.player1.hero.health def get_output_space(self): return 34
def play_one_game(P1: Agent, P2: Agent, deck1=[], deck2=[], HeroHPOption=30, debugLog=True): from fireplace.utils import random_draft from fireplace.player import Player import random #バグが確認されているものを当面除外する exclude = ['CFM_672', 'CFM_621', 'CFM_095', 'LOE_076', 'BT_490'] # 'LOE_076' : Sir Finley Mrrgglton # 'BT_490' : 魔力喰い、ターゲットの扱いにエラーがあるので除外。 if len(deck1) == 0: deck1 = random_draft(P1.myClass, exclude) #ランダムなデッキ if len(deck2) == 0: deck2 = random_draft(P2.myClass, exclude) #ランダムなデッキ player1 = Player(P1.name, deck1, P1.myClass.default_hero) player2 = Player(P2.name, deck2, P2.myClass.default_hero) game = Game(players=(player1, player2)) game.start() for player in game.players: #print("Can mulligan %r" % (player.choice.cards)) mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) player.choice.choose(*cards_to_mulligan) if HeroHPOption != 30: game.player1.hero.max_health = HeroHPOption game.player2.hero.max_health = HeroHPOption while True: from agent_Standard import StandardRandom, HumanInput, Original_random from agent_Maya import Maya_MCTS player = game.current_player #print("%r starts their turn."%player.name); if player.name == "Maya": Maya_MCTS(game) #マヤ氏の作品 elif player.name == "Standard": StandardRandom( game, debugLog=debugLog) #公式のランダムより、もう少しキチンとしたランダムプレーエージェント elif player.name == "Human": HumanInput(game) #人がプレーするときはこれ elif player.name == P1.name: P1.func(game, option=P1.option, debugLog=debugLog) #P1.funcには引数option, debugLogを作ってください elif player.name == P2.name: P2.func(game, option=P2.option, debugLog=debugLog) #P2.funcには引数option, debugLogを作ってください else: Original_random(game) #公式のランダム if player.choice != None: player.choice = None #論理的にはおこらないが、ときどきおこる if game.state != State.COMPLETE: try: game.end_turn() except GameOver: #まれにおこる gameover = 0 if game.state == State.COMPLETE: #ゲーム終了フラグが立っていたら if game.current_player.playstate == PlayState.WON: return game.current_player.name if game.current_player.playstate == PlayState.LOST: return game.current_player.opponent.name return 'DRAW'
class HearthState: """ A state of the game, i.e. the game board. """ def __init__(self): self.playerJustMoved = 2 # At the root pretend the player just moved is p2 - p1 has the first move random.seed(1857) # The idea of adjacent cards it to ignore minion placement if none of these cards can be found, since it doesn't # matter. #adjacent_cards = ["Dire Wolf Alpha", "Ancient Mage", "Defender of Argus", "Sunfury Protector", # "Flametongue Totem", "Explosive Shot", "Cone of Cold", "Betrayal", "Void Terror", # "Unstable Portal", "Wee Spellstopper", "Piloted Shredder", "Piloted Sky Golem", # "Recombobulator", "Foe Reaper 4000", "Nefarian"] #self.adjacent_cards = adjacent_cards self.player1 = None self.hero1 = MAGE self.deck1 = [] self.player2 = None self.hero2 = None self.deck2 = [] self.game = None # Simple Arcane Missiles lethal test #self.deck1 = ["EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277"] #self.hero1 = MAGE #self.player1 = Player("one", self.deck1, self.hero1) #self.deck2 = ["EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", "EX1_277", # "EX1_277", "EX1_277", "EX1_277"] #self.hero2 = MAGE #self.player2 = Player("two", self.deck2, self.hero2) #self.game = Game(players=(self.player1, self.player2)) #self.game.start() #for player in self.game.players: # if player.choice: # player.choice.choose() #self.game.players[0].hero.hit(24) #self.game.players[1].hero.hit(24) def Clone(self): """ Create a deep clone of this game state. """ st = HearthState() st.playerJustMoved = self.playerJustMoved st.player1 = self.player1 st.hero1 = self.hero1 st.deck1 = copy.copy(self.deck1) st.player2 = self.player2 st.hero2 = self.hero2 st.deck2 = copy.copy(self.deck2) #st.game = copy.copy(self.game) st.game = copy.deepcopy(self.game) return st def DoMove(self, move): """ Update a state by carrying out the given move. """ if self.game is not None: assert self.game.current_player.playstate == PlayState.PLAYING if self.game.current_player is not None: if self.game.current_player.name == "one": self.playerJustMoved = 1 else: self.playerJustMoved = 2 try: if move[0] == MOVE.PRE_GAME: self.player1 = Player("one", self.deck1, self.hero1) self.player2 = Player("two", self.deck2, self.hero2) self.game = Game(players=(self.player1, self.player2)) self.game.start() # TODO: Mulligan for player in self.game.players: if player.choice: player.choice.choose() elif move[0] == MOVE.PICK_CLASS: self.hero2 = move[1] elif move[0] == MOVE.PICK_CARD: if len(self.deck1) < 30: self.deck1.append(move[1].id) else: self.deck2.append(move[1].id) elif move[0] == MOVE.MULLIGAN: self.game.current_player.choice.choose(*move[1]) elif move[0] == MOVE.END_TURN: self.game.end_turn() elif move[0] == MOVE.HERO_POWER: heropower = self.game.current_player.hero.power if move[3] is None: heropower.use() else: heropower.use(target=heropower.targets[move[3]]) elif move[0] == MOVE.PLAY_CARD: card = self.game.current_player.hand[move[2]] if move[3] is None: card.play() else: card.play(target=card.targets[move[3]]) elif move[0] == MOVE.MINION_ATTACK: minion = self.game.current_player.field[move[2]] minion.attack(minion.targets[move[3]]) elif move[0] == MOVE.HERO_ATTACK: hero = self.game.current_player.hero hero.attack(hero.targets[move[3]]) elif move[0] == MOVE.CHOICE: self.game.current_player.choice.choose(move[1]) else: raise NameError("DoMove ran into unclassified card", move) except: return def GetMoves(self): """ Get all possible moves from this state. """ if self.game is not None: if self.game.current_player.playstate != PlayState.PLAYING: return [] valid_moves = [ ] # Move format is [enum, card, index of card in hand, target index] if self.game is None and len(self.deck1) == 30 and len( self.deck2) == 30: valid_moves.append([MOVE.PRE_GAME]) elif self.game is None and len( self.deck1) == 30 and self.hero2 is None: valid_moves.append([MOVE.PICK_CLASS, DRUID]) valid_moves.append([MOVE.PICK_CLASS, HUNTER]) valid_moves.append([MOVE.PICK_CLASS, MAGE]) valid_moves.append([MOVE.PICK_CLASS, PALADIN]) valid_moves.append([MOVE.PICK_CLASS, PRIEST]) valid_moves.append([MOVE.PICK_CLASS, ROGUE]) valid_moves.append([MOVE.PICK_CLASS, SHAMAN]) valid_moves.append([MOVE.PICK_CLASS, WARLOCK]) valid_moves.append([MOVE.PICK_CLASS, WARRIOR]) elif self.game is None and len(self.deck1) < 30 or len( self.deck2) < 30: collection = [] exclude = [] if len(self.deck1) < 30: hero = cards.db[self.hero1] deck = self.deck1 else: hero = cards.db[self.hero2] deck = self.deck2 for card in cards.db.keys(): if card in exclude: continue cls = cards.db[card] if not cls.collectible: continue if cls.type == CardType.HERO: # Heroes are collectible... continue if cls.card_class and cls.card_class != hero.card_class: continue collection.append(cls) for card in collection: if card.rarity == Rarity.LEGENDARY and card.id in deck: continue elif deck.count(card.id) < Deck.MAX_UNIQUE_CARDS: valid_moves.append([MOVE.PICK_CARD, card]) elif self.game.current_player.choice is not None: for card in self.game.current_player.choice.cards: valid_moves.append([MOVE.CHOICE, card]) else: # Play card for card in self.game.current_player.hand: dupe = False for i in range(len(valid_moves)): if valid_moves[i][1].id == card.id: dupe = True break if not dupe: if card.is_playable(): if card.has_target(): for t in range(len(card.targets)): valid_moves.append([ MOVE.PLAY_CARD, card, self.game.current_player.hand.index(card), t ]) else: valid_moves.append([ MOVE.PLAY_CARD, card, self.game.current_player.hand.index(card), None ]) # Hero Power heropower = self.game.current_player.hero.power if heropower.is_usable(): if heropower.has_target(): for t in range(len(heropower.targets)): valid_moves.append([MOVE.HERO_POWER, None, None, t]) else: valid_moves.append([MOVE.HERO_POWER, None, None, None]) # Minion Attack for minion in self.game.current_player.field: if minion.can_attack(): for t in range(len(minion.targets)): valid_moves.append([ MOVE.MINION_ATTACK, minion, self.game.current_player.field.index(minion), t ]) # Hero Attack hero = self.game.current_player.hero if hero.can_attack(): for t in range(len(hero.targets)): valid_moves.append([MOVE.HERO_ATTACK, hero, None, t]) valid_moves.append([MOVE.END_TURN]) return valid_moves def GetResult(self, playerjm): """ Get the game result from the viewpoint of playerjm. """ if self.game.players[0].hero.health <= 0 and self.game.players[ 1].hero.health <= 0: return 0.1 elif self.game.players[playerjm - 1].hero.health <= 0: # loss return 0 elif self.game.players[2 - playerjm].hero.health <= 0: # win return pow(0.99, self.game.turn) else: # Should not be possible to get here unless we terminate the game early. return 0.1 def __repr__(self): try: s = "Turn: " + str(self.game.turn) s += "\n[" + str( self.game.players[0].hero.health) + " hp ~ " + str( len(self.game.players[0].hand)) + " in hand ~ " + str( self.game.players[0].tempMana) + "/" + str( self.game.players[0].maxMana) + " mana] " #s += "\n[" + str(self.game.players[0].hero.health) + " hp ~ " + str(len(self.game.players[0].hand)) + " in hand ~ " + str(self.game.players[0].deck.left) + "/" + str(len(self.game.players[0].deck.cards)) + " in deck ~ " + str(self.game.players[0].mana) + "/" + str(self.game.players[0].max_mana) + " mana] " for minion in self.game.players[0].field: s += str(minion.atk) + "/" + str(minion.health) + ":" s += "\n[" + str( self.game.players[1].hero.health) + " hp ~ " + str( len(self.game.players[1].hand)) + " in hand ~ " + str( self.game.players[1].tempMana) + "/" + str( self.game.players[1].maxMana) + " mana] " #s += "\n[" + str(self.game.players[1].hero.health) + " hp ~ " + str(len(self.game.players[1].hand)) + " in hand ~ " + str(self.game.players[1].deck.left) + "/" + str(len(self.game.players[1].deck.cards)) + " in deck ~ " + str(self.game.players[1].mana) + "/" + str(self.game.players[1].max_mana) + " mana] " for minion in self.game.players[1].field: s += str(minion.atk) + "/" + str(minion.health) + ":" s += "\n" + "Current Player: " + str(self.game.currentPlayer) return s except: s = "Deck 1: " + ", ".join(self.deck1) s += "\nDeck 2: " + ", ".join(self.deck2) return s
def play_one_game(P1: Agent, P2: Agent, deck1=[], deck2=[], debugLog=True, HEROHPOPTION=30, P1MAXMANA=1, P2MAXMANA=1, P1HAND=3, P2HAND=3): """ エージェント同士で1回対戦する。 実験的に、ヒーローの体力、初期マナ数、初期ハンド枚数をコントロールできます。 play one game by P1 and P2 """ from fireplace.utils import random_draft from fireplace.player import Player import random exclude = [] # you may exclude some cards to construct a deck log.info("New game settings") if len(deck1) == 0: deck1 = random_draft(P1.myClass, exclude) #random deck wrt its class if len(deck2) == 0: deck2 = random_draft(P2.myClass, exclude) #random deck wrt its class player1 = Player(P1.name, deck1, P1.myClass.default_hero) player2 = Player(P2.name, deck2, P2.myClass.default_hero) player1.choiceStrategy = P1.choiceStrategy player2.choiceStrategy = P2.choiceStrategy game = Game(players=(player1, player2)) # Configurations player1._start_hand_size = P1HAND ## this line must be before 'start()' player2._start_hand_size = P2HAND ## player1.max_mana = int( P1MAXMANA) - 1 ## this line must be before 'start()' player2.max_mana = int(P2MAXMANA) - 1 game.start() player1.hero.max_health = int( HEROHPOPTION) ## this line must be below 'start()' player2.hero.max_health = int(HEROHPOPTION) ## #mulligan exchange # Any agent are allowed to give an algorithm to do mulligan exchange. for player in game.players: if player.name == P1.name: if P1.mulliganStrategy == None: mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) else: cards_to_mulligan = P1.mulliganStrategy( P1, player.choice.cards) elif player.name == P2.name: if P2.mulliganStrategy == None: mull_count = random.randint(0, len(player.choice.cards)) cards_to_mulligan = random.sample(player.choice.cards, mull_count) else: cards_to_mulligan = P2.mulliganStrategy( P2, player.choice.cards) player.choice.choose(*cards_to_mulligan) # includes begin_turn() #mulligan exchange end log.info("New game start") while True: #game main loop player = game.current_player start_time = time.time() if player.name == P1.name: #please make each Agent.func has arguments 'self, game, option, gameLog, debugLog' P1.func(P1, game, option=P1.option, gameLog=game.get_log(), debugLog=debugLog) elif player.name == P2.name: #please make each Agent.func has arguments 'self, game, option, gameLog, debugLog' P2.func(P2, game, option=P2.option, gameLog=game.get_log(), debugLog=debugLog) else: Original_random(game) #random player by fireplace #turn end procedure from here if player.choice != None: player.choice = None #somotimes it comes here if game.state != State.COMPLETE: try: game.end_turn() if debugLog: print(">>>>%s>>>>turn change %d[sec]>>>>%s" % (player, time.time() - start_time, player.opponent), end=' ') print("%d : %d" % (player1.hero.health + player1.hero.armor, player2.hero.health + player2.hero.armor)) if game.current_player.choice != None: postAction(game.current_player) except GameOver: #it rarely occurs gameover = 0 #ゲーム終了フラグが立っていたらゲーム終了処理を行う #if game was over if game.state == State.COMPLETE: if debugLog: print(">>>>>>>>>>game end >>>>>>>>" % (), end=' ') print("%d : %d" % (player1.hero.health, player2.hero.health)) if game.current_player.playstate == PlayState.WON: return game.current_player.name if game.current_player.playstate == PlayState.LOST: return game.current_player.opponent.name return 'DRAW' #Maybe impossible to come here.