Beispiel #1
0
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()
Beispiel #2
0
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
Beispiel #3
0
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()
Beispiel #4
0
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()
Beispiel #5
0
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
Beispiel #6
0
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()
Beispiel #7
0
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()
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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))
Beispiel #13
0
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
Beispiel #14
0
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'
Beispiel #15
0
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.