Exemplo n.º 1
0
    def __init__(self):
        oneMonte_threeNaive_anon = [
            Player("AI 1  ", PlayerTypes.NaiveMinAI, self),
            Player("AI 2 ", PlayerTypes.MonteCarloAI, self),
            Player("AI 3  ", PlayerTypes.NaiveMinAI, self),
            Player("AI 4  ", PlayerTypes.NaiveMaxAI, self)
        ]
        thePlayers = oneMonte_threeNaive_anon
        #Shake up the order
        random.shuffle(thePlayers)
        self.players = thePlayers
        self.allTricks = []
        self.currentTrick = Trick()
        self.trickWinner = -1

        self.cardsPlayed = ()  #keep track of state in a tuple
        temp = dict.fromkeys(thePlayers)
        for key in temp:
            temp[key] = []
        self.cardsPlayedbyPlayer = temp
        self.shift = 0
        self.winningPlayer = None
        self.winningPlayers = None

        self.humanExists = False

        self.roundNum = 0
        self.trickNum = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        #self.passes = [1, -1, 2, 0] # left, right, across, no pass

        self.heartsBroken = False
        self.losingPlayer = None
Exemplo n.º 2
0
    def __init__(self):
        self.round_num = 0
        self.trick_num = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        self.passes = [1, -1, 2, 0]  # left, right, across, no pass
        self.currentTrick = Trick(self.trick_num)
        self.trickWinner = -1
        self.hearts_broken = False
        self.losingPlayer = None
        self.passingCards = [[], [], [], []]
        self.scoreboard = [0, 0, 0, 0]
        self.verbose = False
        '''
		Player physical locations:
		Game runs clockwise
			p3
		p2		p4
			p1
		'''
        self.players = [
            PolicyNN("Jason"),
            SimpleAI("Jack"),
            SimpleAI("Sam"),
            SimpleAI("JB")
        ]
        self.newRound()
Exemplo n.º 3
0
    def __init__(self, players):

        self.roundNum = 0
        self.trickNum = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        self.passes = [1, -1, 2, 0]  # left, right, across, no pass
        self.currentTrick = Trick()
        self.trickWinner = -1
        self.heartsBroken = False
        self.losingPlayer = None
        self.passingCards = [[], [], [], []]

        # Make four players

        self.players = players
        #self.players = [QLearningBoi("Dani"), AutoPlayer("Desmond"), AutoPlayer("Ben"), AutoPlayer("Tyler")]
        '''
		Player physical locations:
		Game runs clockwise

			p3
		p2		p4
			p1

		'''

        # Generate a full deck of cards and shuffle it
        self.newRound()
Exemplo n.º 4
0
 def evaluateTrick(self):
     self.trickWinner = self.currentTrick.winner
     p = self.players[self.trickWinner]
     p.trickWon(self.currentTrick)
     self.printCurrentTrick()
     print p.name + " won the trick."
     # print 'Making new trick'
     self.currentTrick = Trick()
     print self.currentTrick.suit
Exemplo n.º 5
0
 def evaluateTrick(self, printOut=True):
     self.trickWinner = self.currentTrick.winner
     p = self.players[self.trickWinner]
     p.trickWon(self.currentTrick)
     self.printCurrentTrick()
     if printOut:
         print(f"{p.name} won the trick.")
     # print 'Making new trick'
     self.currentTrick = Trick()
     if printOut:
         print(self.currentTrick.suit)
Exemplo n.º 6
0
	def evaluateTrick(self):
		self.trickWinner = self.currentTrick.winner
		p = self.players[self.trickWinner]
		p.trickWon(self.currentTrick)
		for p in self.players:
			if p.name == "Maddox":
				p.eval(self)
		self.printCurrentTrick()
		# print p.name + " won the trick."
		# print 'Making new trick'
		self.currentTrick = Trick()
Exemplo n.º 7
0
 def newRound(self):
     self.deck = Deck()
     self.deck.shuffle()
     self.roundNum += 1
     self.trickNum = 0
     self.trickWinner = -1
     self.heartsBroken = False
     self.dealer = (self.dealer + 1) % len(self.players)
     self.dealCards()
     self.currentTrick = Trick()
     self.passingCards = [[], [], [], []]
     for p in self.players:
         p.discardTricks()
Exemplo n.º 8
0
def play_game_trick(game_state) -> Gamestate:
    trick = Trick()

    # Whose turn it is can start the trick
    for _ in game_state.players:
        card = game_state.players[game_state.current_turn].spielt_Karte(trick)

        # When called ace is played, everyone knows the teams
        if card.farbe == game_state.called_ace and card.schlag == "Ass":
            game_state.teams['ist_spieler'].append(game_state.current_turn)
            for player in game_state.players.values():
                if player.number not in game_state.teams['ist_spieler']:
                    game_state.teams['nicht_spieler'].append(player.number)

        trick.Karte_reinlegen(card, game_state.players[game_state.current_turn])
        game_state.current_trick = trick
        next_turn(game_state=game_state)

    # Update process_data
    game_state.played_tricks[len(game_state.played_tricks)] = trick
    if trick.winner() in game_state.teams['ist_spieler']:
        game_state.points['ist_spieler'] += trick.get_punkte()
    else:
        game_state.points['nicht_spieler'] += trick.get_punkte()

    print(trick)

    # Points for the winner
    trick.winner().stiche.append(trick)

    return game_state
Exemplo n.º 9
0
def main():
    hearts = Hearts()
    hearts.verbose = True

    # play until someone loses
    while hearts.losingPlayer is None or hearts.losingPlayer.score < maxScore:
        print("====================Round " + str(hearts.round_num) +
              "====================")
        while hearts.trick_num < totalTricks:
            if hearts.trick_num == 0:
                hearts.playersPassCards()
                hearts.getFirstTrickStarter()
            hearts.playTrick(hearts.trickWinner)
            hearts.currentTrick = Trick(hearts.trick_num)

        # tally scores
        hearts.handleScoring()
        print()

        # new round if no one has lost
        if (hearts.losingPlayer.score < maxScore):
            hearts.newRound()

    print()  # spacing
    winners = hearts.getWinner()
    winnerString = ""
    for w in winners:
        winnerString += w.name + " "
    print(winnerString + "wins!")
Exemplo n.º 10
0
    def reset(self):
        self.round_num = 0
        self.trick_num = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        self.passes = [1, -1, 2, 0]  # left, right, across, no pass
        self.currentTrick = Trick(self.trick_num)
        self.trickWinner = -1
        self.hearts_broken = False
        self.losingPlayer = None
        self.passingCards = [[], [], [], []]
        self.scoreboard = [0, 0, 0, 0]

        for a_player in self.players:
            a_player.reset()

        self.newRound()
Exemplo n.º 11
0
 def start(self):
     """ Start and run the game """
     self.determine_dealer()
     self.deal()
     self.show_flip()
     #while self.score[0] < 10 and self.score[1] < 10:
     Trick(self.flip, self.dealer, self.players, self.position).start()
Exemplo n.º 12
0
	def __init__(self):
		
		self.roundNum = 0
		self.trickNum = 0 # initialization value such that first round is round 0
		self.dealer = -1 # so that first dealer is 0
		self.passes = [1, -1, 2, 0] # left, right, across, no pass
		self.currentTrick = Trick()
		self.trickWinner = -1
		self.heartsBroken = False
		self.losingPlayer = None
		self.passingCards = [[], [], [], []]


		# Make four players

		self.players = [Player("Danny"), Player("Desmond"), Player("Ben"), Player("Tyler")]
		
		'''
		Player physical locations:
		Game runs clockwise

			p3
		p2		p4
			p1

		'''

		# Generate a full deck of cards and shuffle it
		self.newRound()
Exemplo n.º 13
0
	def evaluateTrick(self):
		self.trickWinner = self.currentTrick.winner
		p = self.players[self.trickWinner]
		p.trickWon(self.currentTrick)
		self.printCurrentTrick()
		print p.name + " won the trick."
		# print 'Making new trick'
		self.currentTrick = Trick()
		print self.currentTrick.suit
Exemplo n.º 14
0
 def newSimRound(self, rollout):
     rollout.deck = Deck()
     rollout.deck.shuffle()
     rollout.roundNum += 1
     rollout.trickNum = 0
     rollout.trickWinner = -1
     rollout.heartsBroken = False
     rollout.dealer = (self.dealer + 1) % len(self.players)
     rollout.dealCards(rollout)
     rollout.currentTrick = Trick()
     for p in rollout.players:
         p.discardTricks()
Exemplo n.º 15
0
	def __init__(self, felicity, maddox):

		self.roundNum = 0
		self.trickNum = 0 # initialization value such that first round is round 0
		self.dealer = -1 # so that first dealer is 0
		self.passes = [1, -1, 2, 0] # left, right, across, no pass
		self.currentTrick = Trick()
		self.trickWinner = -1
		self.heartsBroken = False
		self.losingPlayer = None
		self.passingCards = [[], [], [], []]


		# Make four players
		self.players = [felicity, maddox, Dumb("Dumb"), Dumb("Dumber")]

		#initialize Felicity
		self.players[0].hand = Hand()
		self.players[0].score = 0
		self.players[0].roundScore = 0
		self.players[0].tricksWon = []

		#initialize Maddox
		self.players[1].hand = Hand()
		self.players[1].score = 0
		self.players[1].roundScore = 0
		self.players[1].tricksWon = []

		'''
		Player physical locations:
		Game runs clockwise

			p3
		p2		p4
			p1

		'''

		# Generate a full deck of cards and shuffle it
		self.newRound()
Exemplo n.º 16
0
	def newRound(self):
		self.deck = Deck()
		self.deck.shuffle()
		self.roundNum += 1
		self.trickNum = 0
		self.trickWinner = -1
		self.heartsBroken = False
		self.dealer = (self.dealer + 1) % len(self.players)
		self.dealCards()
		self.currentTrick = Trick()
		self.passingCards = [[], [], [], []]
		for p in self.players:
			p.discardTricks()
Exemplo n.º 17
0
 def nextTrick(self):
     currentTrick = Trick()
     if Card.trumpSuit == 4:
         print("=== NEW TRICK (!" +
               Card.VALUES[Player.players[self.boss].level] + ")===")
     else:
         print("=== NEW TRICK (" + Card.SUITS[Card.trumpSuit] +
               Card.VALUES[Player.players[self.boss].level] + ")===")
     for i in Player.players:
         print("Player " + str(i.id) + ": " + str(self.playerPoints[i.id]) +
               " points")
     for i in range(Round.NUM_PLAYERS):
         if len(self.tricks) == 0:
             playerID = (i + self.boss) % Round.NUM_PLAYERS
         else:
             playerID = (i + self.tricks[len(self.tricks) -
                                         1].getWinner()) % Round.NUM_PLAYERS
         self.updateDisplay(Player.players[playerID])
         self.playCards(Player.players[playerID], currentTrick)
     self.updatePoints(currentTrick.getWinner(), currentTrick.getPoints())
     print("Player " + str(currentTrick.getWinner()) +
           " wins trick and earns " + str(currentTrick.getPoints()) +
           " points!")
     return currentTrick
Exemplo n.º 18
0
class Hearts:
	def __init__(self, felicity, maddox):

		self.roundNum = 0
		self.trickNum = 0 # initialization value such that first round is round 0
		self.dealer = -1 # so that first dealer is 0
		self.passes = [1, -1, 2, 0] # left, right, across, no pass
		self.currentTrick = Trick()
		self.trickWinner = -1
		self.heartsBroken = False
		self.losingPlayer = None
		self.passingCards = [[], [], [], []]


		# Make four players
		self.players = [felicity, maddox, Dumb("Dumb"), Dumb("Dumber")]

		#initialize Felicity
		self.players[0].hand = Hand()
		self.players[0].score = 0
		self.players[0].roundScore = 0
		self.players[0].tricksWon = []

		#initialize Maddox
		self.players[1].hand = Hand()
		self.players[1].score = 0
		self.players[1].roundScore = 0
		self.players[1].tricksWon = []

		'''
		Player physical locations:
		Game runs clockwise

			p3
		p2		p4
			p1

		'''

		# Generate a full deck of cards and shuffle it
		self.newRound()

	def handleScoring(self):
		p, highestScore = None, 0
		# print "\nScores:\n"
		for player in self.players:
			# print(player.name + ": " + str(player.score))
			if player.score > highestScore:
				p = player
				highestScore = player.score
			self.losingPlayer = p



	def newRound(self):
		self.deck = Deck()
		self.deck.shuffle()
		self.roundNum += 1
		self.trickNum = 0
		self.trickWinner = -1
		self.heartsBroken = False
		self.dealer = (self.dealer + 1) % len(self.players)
		self.dealCards()
		self.currentTrick = Trick()
		self.passingCards = [[], [], [], []]
		for p in self.players:
			p.discardTricks()
			print(p.roundScore)

	def getFirstTrickStarter(self):
		for i,p in enumerate(self.players):
			if p.hand.contains2ofclubs:
				self.trickWinner = i

	def dealCards(self):
		i = 0
		while(self.deck.size() > 0):
			self.players[i % len(self.players)].addCard(self.deck.deal())
			i += 1


	def evaluateTrick(self):
		self.trickWinner = self.currentTrick.winner
		p = self.players[self.trickWinner]
		p.trickWon(self.currentTrick)
		for p in self.players:
			if p.name == "Maddox":
				p.eval(self)
		self.printCurrentTrick()
		# print p.name + " won the trick."
		# print 'Making new trick'
		self.currentTrick = Trick()
		# print self.currentTrick.suit

	def roundScore(self):
		for p in self.players:
			if (p.roundScore == 26):
				self.shootTheMoon(p)
			else:
				p.score += p.roundScore
			# if p.name == "Maddox":
			# 	p.eval(self)

	def shootTheMoon(self, player):
		if (auto):
			r = randint(0,1)
			if r:
				for p in self.players:
					if (p != player):
						p.add26()
			else:
				player.subtract26()
		else:
			inp = raw_input(self.name + ", do you want to add or subtract")
			if (inp == "add"):
				for p in self.players:
					if (p != player):
						p.add26()
			else:
				player.subtract26()


	def passCards(self, index):
		# print self.printPassingCards()
		passTo = self.passes[self.trickNum] # how far to pass cards
		passTo = (index + passTo) % len(self.players) # the index to which cards are passed
		while len(self.passingCards[passTo]) < cardsToPass: # pass three cards
			passCard = None
			while passCard is None: # make sure string passed is valid
				passCard = self.players[index].play(option='pass', auto=auto, state=self)
				if passCard is not None:
					# remove card from player hand and add to passed cards
					self.passingCards[passTo].append(passCard)
					self.players[index].removeCard(passCard)

	def distributePassedCards(self):
		for i,passed in enumerate(self.passingCards):
			for card in passed:
				self.players[i].addCard(card)
		self.passingCards = [[], [], [], []]


	def printPassingCards(self):
		out = "[ "
		for passed in self.passingCards:
			out += "["
			for card in passed:
				out += card.__str__() + " "
			out += "] "
		out += " ]"
		return out


	def playersPassCards(self):

		self.printPlayers()
		if not self.trickNum % 4 == 3: # don't pass every fourth hand
			for i in range(0, len(self.players)):
				# print # spacing
				self.printPlayer(i)
				self.passCards(i % len(self.players))

			self.distributePassedCards()
			self.printPlayers()

	def playTrick(self, start):
		shift = 0
		if self.trickNum == 0:
			startPlayer = self.players[start]
			addCard = startPlayer.play(option="play", c='2c', state=self)
			startPlayer.removeCard(addCard)

			self.currentTrick.addCard(addCard, start)

			shift = 1 # alert game that first player has already played

		# have each player take their turn
		for i in range(start + shift, start + len(self.players)):
			self.printCurrentTrick()
			curPlayerIndex = i % len(self.players)
			self.printPlayer(curPlayerIndex)
			curPlayer = self.players[curPlayerIndex]
			addCard = None

			while addCard is None: # wait until a valid card is passed

				addCard = curPlayer.play(auto=auto, state=self) # change auto to False to play manually


				# the rules for what cards can be played
				# card set to None if it is found to be invalid
				if addCard is not None:

					# if it is not the first trick and no cards have been played,
					# set the first card played as the trick suit if it is not a heart
					# or if hearts have been broken
					if self.trickNum != 0 and self.currentTrick.cardsInTrick == 0:
						if addCard.suit == Suit(hearts) and not self.heartsBroken:
							# if player only has hearts but hearts have not been broken,
							# player can play hearts
							if not curPlayer.hasOnlyHearts():
								# print curPlayer.hasOnlyHearts()
								# print curPlayer.hand.__str__()
								# print "Hearts have not been broken."
								addCard = None
							else:
								self.currentTrick.setTrickSuit(addCard)
						else:
							self.currentTrick.setTrickSuit(addCard)

					# player tries to play off suit but has trick suit
					if addCard is not None and addCard.suit != self.currentTrick.suit:
						if curPlayer.hasSuit(self.currentTrick.suit):
							#print "Must play the suit of the current trick."
							addCard = None
						elif addCard.suit == Suit(hearts):
							self.heartsBroken = True

					if self.trickNum == 0:
						if addCard is not None:
							if addCard.suit == Suit(hearts):
								#print "Hearts cannot be broken on the first hand."
								self.heartsBroken = False
								addCard = None
							elif addCard.suit == Suit(spades) and addCard.rank == Rank(queen):
								# print "The queen of spades cannot be played on the first hand."
								addCard = None

					if addCard is not None and self.currentTrick.suit == Suit(noSuit):
						if addCard.suit == Suit(hearts) and not self.heartsBroken:
							# print "Hearts not yet broken."
							addCard = None



					if addCard is not None:
						if addCard == Card(queen, spades):
							self.heartsBroken = True
						curPlayer.removeCard(addCard)


			self.currentTrick.addCard(addCard, curPlayerIndex)

		self.evaluateTrick()
		self.trickNum += 1

	# print player's hand
	def printPlayer(self, i):
		p = self.players[i]
		# print p.name + "'s hand: " + str(p.hand)

	# print all players' hands
	def printPlayers(self):
		pass
	# 	for p in self.players:
	# 		# print p.name + ": " + str(p.hand)

	# show cards played in current trick
	def printCurrentTrick(self):
		trickStr = '\nCurrent table:\n'
		trickStr += "Trick suit: " + self.currentTrick.suit.__str__() + "\n"
		for i, card in enumerate(self.currentTrick.trick):
			if self.currentTrick.trick[i] is not 0:
				trickStr += self.players[i].name + ": " + str(card) + "\n"
			else:
				trickStr += self.players[i].name + ": None\n"
		# print trickStr

	def getWinner(self):
		minScore = 200 # impossibly high
		winner = None
		for p in self.players:
			if p.score < minScore:
				winner = p
				minScore = p.score
		return winner
Exemplo n.º 19
0
def main():
    trainer = Hearts_env_policy()
    tot_wins = 0
    tot_loss = 0
    last200Wins = []
    last200Loss = []
    jason_wins = 0
    sam_wins = 0
    jb_wins = 0
    jason_loss = 0
    sam_loss = 0
    jb_loss = 0
    current_odds = .5
    trainer.hearts_game = Hearts()

    record_final_score = []

    for i in range(epochs):

        # play until someone loses
        while trainer.hearts_game.losingPlayer is None or trainer.hearts_game.losingPlayer.score < max_score:

            while trainer.hearts_game.trick_num < total_tricks:
                # print("Round: ", trainer.hearts_game.trick_num)
                if trainer.hearts_game.trick_num == 0:
                    trainer.hearts_game.playersPassCards()
                    trainer.hearts_game.getFirstTrickStarter()

                # print(trainer.hearts_game.players[1].hand)

                previous_scores = [
                    pl.currentScore for pl in trainer.hearts_game.players
                ]

                trainer.hearts_game.playTrick(trainer.hearts_game.trickWinner)

                # add reward to the model for this timestep
                for j, a_palyer in enumerate(trainer.hearts_game.players):

                    q_reward = trainer.get_reward(j, previous_scores)

                    a_palyer.store_reward(q_reward)

                trainer.hearts_game.currentTrick = Trick(
                    trainer.hearts_game.trick_num)

            # tally scores
            trainer.hearts_game.handleScoring()

            #Learn based off the past round
            trainer.hearts_game.players[1].play_policy.learn()

            # new round if no one has lost
            if trainer.hearts_game.losingPlayer.score < max_score:
                trainer.hearts_game.newRound()

        # Record Jack's final score
        record_final_score.append(trainer.hearts_game.players[1].score)

        winners = trainer.hearts_game.getWinner()
        winnerString = ""
        for w in winners:
            winnerString += w.name + " "
            if len(last200Wins) == 200:
                last200Wins.pop(0)

            if w.name == "Jack":
                tot_wins += 1
                last200Wins.append(1)
            else:
                last200Wins.append(0)
            if w.name == "Jason":
                jason_wins += 1
            if w.name == "Sam":
                sam_wins += 1
            if w.name == "JB":
                jb_wins += 1

        if i % 25 == 0:
            print()
            for a, player in enumerate(trainer.hearts_game.players):
                print(player.name + ": " + str(player.score))
            print(winnerString + "wins!")
            print("--------------------------------------")
            print("Jack last 200 games wins: ", np.sum(last200Wins))
            print("Jack wins: ", tot_wins)
            print("Jason wins: ", jason_wins)
            print("Sam wins: ", sam_wins)
            print("JB wins: ", jb_wins)
            print("num games: ", i)

        losers = trainer.hearts_game.getLosers()
        losersString = ""

        if len(last200Loss) == 200:
            last200Loss.pop(0)
        if 'Jack' in [l.name for l in losers]:
            last200Loss.append(1)
        else:
            last200Loss.append(0)

        for w in losers:
            losersString += w.name + " "
            if w.name == "Jack":
                tot_loss += 1

            if w.name == "Jason":
                jason_loss += 1
            if w.name == "Sam":
                sam_loss += 1
            if w.name == "JB":
                jb_loss += 1

        if i % 25 == 0:
            print("\n")
            for a, player in enumerate(trainer.hearts_game.players):
                print(player.name + ": " + str(player.score))
            print(losersString + "lose.")
            print("--------------------------------------")
            print("Jack last 200 games losses: %d  (%.2f%%)" %
                  (np.sum(last200Loss),
                   100 * np.sum(last200Loss) / len(last200Loss)))
            print("       Average final score: %.2f" %
                  (np.sum(record_final_score[-200:]) /
                   len(record_final_score[-200:])))
            print("Jack losses: ", tot_loss)
            print("Jason losses: ", jason_loss)
            print("Sam losses: ", sam_loss)
            print("JB losses: ", jb_loss)
            print("num games: ", i)

        if i % 50 == 0:
            for player in trainer.hearts_game.players:
                try:
                    player.play_policy.save_model()
                except Exception as E:
                    pass

        trainer.hearts_game.reset()

    plot_records(record_final_score, "Final score")

    jack = [pl for pl in trainer.hearts_game.players if pl.name == "Jack"][0]

    plot_records(jack.play_policy.loss_actor, "Loss Actor")
    plot_records(np.log(jack.play_policy.loss_critic), "Log-loss Critic")
Exemplo n.º 20
0
def main():
    trainer = Hearts_env_policy()
    player0_win = np.array([])
    player1_win = np.array([])
    player2_win = np.array([])
    player3_win = np.array([])
    player0_scores = np.array([])
    player1_scores = np.array([])
    player2_scores = np.array([])
    player3_scores = np.array([])
    num_hands = 0

    if play_self:
        policy1 = PolicyNN("Sam")
        models = policy1.play_policy.policy, policy1.play_policy.predict
        policy2 = PolicyNN("Jack", models=models)
        policy3 = PolicyNN("Jason", models=models)
        policy4 = PolicyNN("JB", models=models)
        trainer.hearts_game.players = [policy1, policy2, policy3, policy4]
        trainer.hearts_game.reset()

    for i in range(epochs):
        # play until someone loses
        while trainer.hearts_game.losingPlayer is None or trainer.hearts_game.losingPlayer.score < max_score:
            while trainer.hearts_game.trick_num < total_tricks:
                if trainer.hearts_game.trick_num == 0:
                    trainer.hearts_game.playersPassCards()
                    trainer.hearts_game.getFirstTrickStarter()

                trainer.hearts_game.playTrick(trainer.hearts_game.trickWinner)

                # add reward to the model for this timestep
                for j, a_player in enumerate(trainer.hearts_game.players):
                    # reward = trainer.get_reward(j)
                    # reward = trainer.get_reward_simple(j)
                    reward = trainer.get_reward_simple_v2(j)
                    a_player.store_reward(reward)

                trainer.hearts_game.currentTrick = Trick(trainer.hearts_game.trick_num)

            # tally scores
            trainer.hearts_game.handleScoring()

            # Learn based off the past round
            if train:
                num_hands += 1
                if num_hands == batch_size:
                    for j, player in enumerate(trainer.hearts_game.players):
                        if type(player) is PolicyNN:
                                player.play_policy.learn(batch_size)
                    num_hands = 0

            # new round if no one has lost
            if trainer.hearts_game.losingPlayer.score < max_score:
                trainer.hearts_game.newRound()

        if track[0]:
            player0_scores = np.append(player0_scores, trainer.hearts_game.players[0].score)
        if track[1]:
            player1_scores = np.append(player1_scores, trainer.hearts_game.players[1].score)
        if track[2]:
            player2_scores = np.append(player2_scores, trainer.hearts_game.players[2].score)
        if track[3]:
            player3_scores = np.append(player3_scores, trainer.hearts_game.players[3].score)

        winners = trainer.hearts_game.getWinner()
        winnerString = ""
        won = [False, False, False, False]
        for w in winners:
            winnerString += w.name + " "
            if w.name == trainer.hearts_game.players[0].name:
                won[0] = True
            elif w.name == trainer.hearts_game.players[1].name:
                won[1] = True
            elif w.name == trainer.hearts_game.players[2].name:
                won[2] = True
            elif w.name == trainer.hearts_game.players[3].name:
                won[3] = True

        if track[0]:
            if won[0]:
                player0_win = np.append(player0_win, 1)
            else:
                player0_win = np.append(player0_win, 0)
        if track[1]:
            if won[1]:
                player1_win = np.append(player1_win, 1)
            else:
                player1_win = np.append(player1_win, 0)
        if track[2]:
            if won[2]:
                player2_win = np.append(player2_win, 1)
            else:
                player2_win = np.append(player2_win, 0)
        if track[3]:
            if won[3]:
                player3_win = np.append(player3_win, 1)
            else:
                player3_win = np.append(player3_win, 0)

        if i % display_stats_epochs == (display_stats_epochs - 1):  # Console output
            print()
            for a, player in enumerate(trainer.hearts_game.players):
                print(player.name + ": " + str(player.score))
            print(winnerString + "wins!")
            print("--------------------------------------")
            if track[0]:
                print("Player 0 wins:", np.sum(player0_win))
                print("Player 0 avg. score:", np.mean(player0_scores))
            if track[1]:
                print("Player 1 wins:", np.sum(player1_win))
                print("Player 1 avg. score:", np.mean(player1_scores))
            if track[2]:
                print("Player 2 wins:", np.sum(player2_win))
                print("Player 2 avg. score:", np.mean(player2_scores))
            if track[3]:
                print("Player 3 wins:", np.sum(player3_win))
                print("Player 3 avg. score:", np.mean(player3_scores))
            print("num games: ", i + 1)

        if train and i % physical_save_epochs == (physical_save_epochs - 1):  # Physical save
            print("Saving model")
            for player in trainer.hearts_game.players:
                plot_records(player0_scores, "Final score", "models/policy/Scores.png")
                if type(player) is PolicyNN:
                    plot_records(player.play_policy.loss_policy, "Loss Actor", "models/policy/loss_" + player.name + ".png")

                    try:
                        player.play_policy.save_model()
                    except:
                        pass

        # Change players and reset
        if i % 10 == 9:
            for j in randomize_players:
                rand = np.random.randint(10)
                if rand == 9:
                    trainer.hearts_game.players[j] = RandomAI("rand" + str(j))
                else:
                    trainer.hearts_game.players[j] = SimpleAI("simple" + str(j))
        trainer.hearts_game.reset()

    if train:
        for i, player in enumerate(trainer.hearts_game.players):
            plot_records(player0_scores, "Final score", "models/policy/Scores.png")
            if type(player) is PolicyNN:
                plot_records(player.play_policy.loss_policy, "Loss Actor", "models/policy/loss_" + player.name + ".png")
Exemplo n.º 21
0
 def evaluateTrick(self):
     self.trickWinner = self.currentTrick.winner
     p = self.players[self.trickWinner]
     p.trickWon(self.currentTrick)
     self.allTricks.append(self.currentTrick.trick)
     self.currentTrick = Trick()
Exemplo n.º 22
0
 def evaluateTrick(self, rollout):
     rollout.trickWinner = rollout.currentTrick.winner
     p = rollout.players[rollout.trickWinner]
     p.trickWon(rollout.currentTrick)
     rollout.currentTrick = Trick()
Exemplo n.º 23
0
class Hearts:
    def __init__(self):
        oneMonte_threeNaive_anon = [
            Player("AI 1  ", PlayerTypes.NaiveMinAI, self),
            Player("AI 2 ", PlayerTypes.MonteCarloAI, self),
            Player("AI 3  ", PlayerTypes.NaiveMinAI, self),
            Player("AI 4  ", PlayerTypes.NaiveMaxAI, self)
        ]
        thePlayers = oneMonte_threeNaive_anon
        #Shake up the order
        random.shuffle(thePlayers)
        self.players = thePlayers
        self.allTricks = []
        self.currentTrick = Trick()
        self.trickWinner = -1

        self.cardsPlayed = ()  #keep track of state in a tuple
        temp = dict.fromkeys(thePlayers)
        for key in temp:
            temp[key] = []
        self.cardsPlayedbyPlayer = temp
        self.shift = 0
        self.winningPlayer = None
        self.winningPlayers = None

        self.humanExists = False

        self.roundNum = 0
        self.trickNum = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        #self.passes = [1, -1, 2, 0] # left, right, across, no pass

        self.heartsBroken = False
        self.losingPlayer = None

        # Generate a full deck of cards and shuffle it
        # # else:
        # 	self = copy.deepcopy(orig)
        #return flat array of cards
    def getLegalPlays(self, player):
        if player.type == PlayerTypes.MonteCarloAI:
            validHand = []
            for suit in range(0, 4):
                handSuit = player.hand.hand[suit]
                for card in handSuit:
                    if self.isValidCard(card, player):
                        validHand.append(card)
        else:
            monterCards = sum(self.players[0].hand.hand, [])
            playedCards = self.cardsPlayed
            d = Deck()
            validHand = [
                i for i in d.deck if i not in monterCards + list(playedCards)
            ]
        #print('player:',player.name,'vali:',validHand)
        return validHand

    def getCurrentPlayer(self):
        return self.players[self.currentTrick.getCurrentPlayer(
            self.trickWinner)]

    def step(self, card, player, monteCarlo=False):
        #add card to state
        self.cardsPlayed = self.cardsPlayed + (card, )
        self.cardsPlayedbyPlayer[player].append(card)

        player.removeCard(card)
        start = (self.trickWinner + self.shift) % len(self.players)
        self.currentTrick.addCard(card, start)
        self.shift += 1
        if self.shift == 4:
            self.evaluateTrick()
            self.trickNum += 1
            self.shift = 0
            #end game and evaluate winner if round is over
            if monteCarlo:
                if (self.trickNum >= totalTricks):
                    self.winningPlayers = self.roundWinners()
                    self.handleScoring()
                    self.winningPlayer = self.getWinner()

    def isValidCard(self, card, player):
        if card is None:
            return False

        # if it is not the first trick and no cards have been played:
        if self.trickNum != 0 and self.currentTrick.cardsInTrick == 0:
            if card.suit == Suit(hearts) and not self.heartsBroken:
                if not player.hasOnlyHearts():
                    return False
        #Can't play hearts or queen of spades on first hand
        if self.trickNum == 0:
            if card.suit == Suit(hearts):
                return False
            elif card.suit == Suit(spades) and card.rank == Rank(queen):
                return False
        return True

    def evaluateTrick(self):
        self.trickWinner = self.currentTrick.winner
        p = self.players[self.trickWinner]
        p.trickWon(self.currentTrick)
        self.allTricks.append(self.currentTrick.trick)
        self.currentTrick = Trick()

    def roundWinners(self):
        winners = []
        for player in self.players:
            if player.roundscore == 26:
                #shotMoon = True
                winners.append(player)
                return winners

        minScore = 200  # impossibly high
        winner = None
        for p in self.players:
            if p.roundscore < minScore:
                winner = p
                minScore = p.roundscore

        winners.append(winner)
        #check for a draw
        for p in self.players:
            if p != winner and p.roundscore == minScore:
                winners.append(p)
        return winners

    def handleScoring(self):
        p, highestScore = None, 0
        shotMoon = False
        for player in self.players:
            if player.roundscore == 26:
                shotMoon = True
        for player in self.players:
            if shotMoon and player.roundscore != 26:
                player.score += 26
            elif not shotMoon:
                player.score += player.roundscore
            player.roundscore = 0
            if player.score > highestScore:
                p = player
                highestScore = player.score
            self.losingPlayer = p

    def getWinner(self):
        minScore = 200  # impossibly high
        winner = None
        for p in self.players:
            if p.score < minScore:
                winner = p
                minScore = p.score
        return winner

    def getFirstTrickStarter(self):
        for i, p in enumerate(self.players):
            if p.hand.contains2ofclubs:
                self.trickWinner = i
Exemplo n.º 24
0
class Hearts:
    def __init__(self, players):

        self.roundNum = 0
        self.trickNum = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        self.passes = [1, -1, 2, 0]  # left, right, across, no pass
        self.currentTrick = Trick()
        self.trickWinner = -1
        self.heartsBroken = False
        self.losingPlayer = None
        self.passingCards = [[], [], [], []]

        # Make four players

        self.players = players
        #self.players = [QLearningBoi("Dani"), AutoPlayer("Desmond"), AutoPlayer("Ben"), AutoPlayer("Tyler")]
        '''
		Player physical locations:
		Game runs clockwise

			p3
		p2		p4
			p1

		'''

        # Generate a full deck of cards and shuffle it
        self.newRound()

    def handleScoring(self):
        p, highestScore = None, 0
        print("\nScores:\n")
        for player in self.players:
            print(player.name + ": " + str(player.score))
            if player.score > highestScore:
                p = player
                highestScore = player.score
            self.losingPlayer = p

    def newRound(self):
        self.deck = Deck()
        self.deck.shuffle()
        self.roundNum += 1
        self.trickNum = 0
        self.trickWinner = -1
        self.heartsBroken = False
        self.dealer = (self.dealer + 1) % len(self.players)
        self.dealCards()
        self.currentTrick = Trick()
        self.passingCards = [[], [], [], []]
        for p in self.players:
            p.discardTricks()

    def getFirstTrickStarter(self):
        for i, p in enumerate(self.players):
            if p.hand.contains2ofclubs:
                self.trickWinner = i

    def dealCards(self):
        i = 0
        while (self.deck.size() > 0):
            self.players[i % len(self.players)].addCard(self.deck.deal())
            i += 1

    def evaluateTrick(self, printOut=True):
        self.trickWinner = self.currentTrick.winner
        p = self.players[self.trickWinner]
        p.trickWon(self.currentTrick)
        self.printCurrentTrick()
        if printOut:
            print(f"{p.name} won the trick.")
        # print 'Making new trick'
        self.currentTrick = Trick()
        if printOut:
            print(self.currentTrick.suit)

    def passCards(self, index):
        print(self.printPassingCards())
        passTo = self.passes[self.trickNum]  # how far to pass cards
        passTo = (index + passTo) % len(
            self.players)  # the index to which cards are passed
        while len(self.passingCards[passTo]) < cardsToPass:  # pass three cards
            passCard = None
            while passCard is None:  # make sure string passed is valid
                passCard = self.players[index].play(self, option='pass')
                if passCard is not None:
                    # remove card from player hand and add to passed cards
                    self.passingCards[passTo].append(passCard)
                    self.players[index].removeCard(passCard)

    def distributePassedCards(self):
        for i, passed in enumerate(self.passingCards):
            for card in passed:
                self.players[i].addCard(card)
        self.passingCards = [[], [], [], []]

    def printPassingCards(self):
        out = "[ "
        for passed in self.passingCards:
            out += "["
            for card in passed:
                out += card.__str__() + " "
            out += "] "
        out += " ]"
        return out

    def playersPassCards(self):

        self.printPlayers()
        if not self.trickNum % 4 == 3:  # don't pass every fourth hand
            for i in range(0, len(self.players)):
                print('\n')
                self.printPlayer(i)
                self.passCards(i % len(self.players))

            self.distributePassedCards()
            self.printPlayers()

    def finishTrick(self, start, action):
        print("finishTrick start")
        if self.trickNum >= totalTricks:
            print('end game')
            return
        playersLeft = len(self.players) - self.currentTrick.cardsInTrick
        # have each player take their turn
        for i in range(start, start + playersLeft):
            # print("playerNum: ", i)
            # self.printCurrentTrick()
            curPlayerIndex = i % len(self.players)
            # self.printPlayer(curPlayerIndex)
            curPlayer = self.players[curPlayerIndex]
            addCard = None

            while addCard is None:  # wait until a valid card is passed
                if i == 0:
                    addCard = action
                else:
                    addCard = curPlayer.play(
                        self)  # change auto to False to play manually

                # the rules for what cards can be played
                # card set to None if it is found to be invalid
                if addCard is not None:

                    # if it is not the first trick and no cards have been played,
                    # set the first card played as the trick suit if it is not a heart
                    # or if hearts have been broken
                    if self.trickNum != 0 and self.currentTrick.cardsInTrick == 0:
                        if addCard.suit == Suit(
                                hearts) and not self.heartsBroken:
                            # if player only has hearts but hearts have not been broken,
                            # player can play hearts
                            if not curPlayer.hasOnlyHearts():
                                # print(curPlayer.hasOnlyHearts())
                                # print(curPlayer.hand.__str__())
                                print("Hearts have not been broken.")
                                addCard = None
                            else:
                                self.currentTrick.setTrickSuit(addCard)
                        else:
                            self.currentTrick.setTrickSuit(addCard)

                    # player tries to play off suit but has trick suit
                    if addCard is not None and addCard.suit != self.currentTrick.suit:
                        if curPlayer.hasSuit(self.currentTrick.suit):
                            print("Must play the suit of the current trick.")
                            addCard = None
                        elif addCard.suit == Suit(hearts):
                            self.heartsBroken = True

                    if self.trickNum == 0:
                        if addCard is not None:
                            if addCard.suit == Suit(hearts):
                                print(
                                    "Hearts cannot be broken on the first hand."
                                )
                                self.heartsBroken = False
                                addCard = None
                            elif addCard.suit == Suit(
                                    spades) and addCard.rank == Rank(queen):
                                print(
                                    "The queen of spades cannot be played on the first hand."
                                )
                                addCard = None

                    if addCard is not None and self.currentTrick.suit == Suit(
                            noSuit):
                        if addCard.suit == Suit(
                                hearts) and not self.heartsBroken:
                            print("Hearts not yet broken.")
                            addCard = None

                    if addCard is not None:
                        if addCard == Card(queen, spades):
                            self.heartsBroken = True
                        curPlayer.removeCard(addCard)

            self.currentTrick.addCard(addCard, curPlayerIndex)
            print('all players played')
        self.evaluateTrick(printOut=False)
        self.trickNum += 1

    def playTrick(self, start):
        shift = 0
        if self.trickNum == 0:
            startPlayer = self.players[start]
            addCard = startPlayer.play(self, option="play", c='2c')
            startPlayer.removeCard(addCard)

            self.currentTrick.addCard(addCard, start)

            shift = 1  # alert game that first player has already played

        # have each player take their turn
        for i in range(start + shift, start + len(self.players)):
            self.printCurrentTrick()
            curPlayerIndex = i % len(self.players)
            self.printPlayer(curPlayerIndex)
            curPlayer = self.players[curPlayerIndex]
            addCard = None

            while addCard is None:  # wait until a valid card is passed

                addCard = curPlayer.play(
                    self)  # change auto to False to play manually
                # print('addCard', addCard)

                # the rules for what cards can be played
                # card set to None if it is found to be invalid
                if addCard is not None:

                    # if it is not the first trick and no cards have been played,
                    # set the first card played as the trick suit if it is not a heart
                    # or if hearts have been broken
                    if self.trickNum != 0 and self.currentTrick.cardsInTrick == 0:
                        if addCard.suit == Suit(
                                hearts) and not self.heartsBroken:
                            # if player only has hearts but hearts have not been broken,
                            # player can play hearts
                            if not curPlayer.hasOnlyHearts():
                                print(curPlayer.hasOnlyHearts())
                                print(curPlayer.hand.__str__())
                                print("Hearts have not been broken.")
                                addCard = None
                            else:
                                self.currentTrick.setTrickSuit(addCard)
                        else:
                            self.currentTrick.setTrickSuit(addCard)

                    # player tries to play off suit but has trick suit
                    if addCard is not None and addCard.suit != self.currentTrick.suit:
                        if curPlayer.hasSuit(self.currentTrick.suit):
                            print("Must play the suit of the current trick.")
                            addCard = None
                        elif addCard.suit == Suit(hearts):
                            self.heartsBroken = True

                    if self.trickNum == 0:
                        if addCard is not None:
                            if addCard.suit == Suit(hearts):
                                print(
                                    "Hearts cannot be broken on the first hand."
                                )
                                self.heartsBroken = False
                                addCard = None
                            elif addCard.suit == Suit(
                                    spades) and addCard.rank == Rank(queen):
                                print(
                                    "The queen of spades cannot be played on the first hand."
                                )
                                addCard = None

                    if addCard is not None and self.currentTrick.suit == Suit(
                            noSuit):
                        if addCard.suit == Suit(
                                hearts) and not self.heartsBroken:
                            print("Hearts not yet broken.")
                            addCard = None

                    if addCard is not None:
                        if addCard == Card(queen, spades):
                            self.heartsBroken = True
                        curPlayer.removeCard(addCard)

            self.currentTrick.addCard(addCard, curPlayerIndex)

        self.evaluateTrick()
        self.trickNum += 1

    # print player's hand
    def printPlayer(self, i):
        p = self.players[i]
        print(p.name + "'s hand: " + str(p.hand))

    # print all players' hands
    def printPlayers(self):
        for p in self.players:
            print(p.name + ": " + str(p.hand))

    # show cards played in current trick
    def printCurrentTrick(self):
        trickStr = '\nCurrent table:\n'
        trickStr += "Trick suit: " + self.currentTrick.suit.__str__() + "\n"
        for i, card in enumerate(self.currentTrick.trick):
            if self.currentTrick.trick[i] is not 0:
                trickStr += self.players[i].name + ": " + str(card) + "\n"
            else:
                trickStr += self.players[i].name + ": None\n"
        print(trickStr)

    def getWinner(self):
        minScore = 200  # impossibly high
        winner = None
        for p in self.players:
            if p.score < minScore:
                winner = p
                minScore = p.score
        return winner
Exemplo n.º 25
0
def main():
    trainer = Hearts_env()
    tot_wins = 0
    sam_wins = 0
    current_odds = .5
    trainer.hearts_game = Hearts()
    for i in range(epochs):

        current_odds *= trainer.hearts_game.players[1].play_policy.decay_factor
        trainer.hearts_game.players[1].play_policy.odds_explore = current_odds
        # play until someone loses
        while trainer.hearts_game.losingPlayer is None or trainer.hearts_game.losingPlayer.score < max_score:

            while trainer.hearts_game.trick_num < total_tricks:
                if trainer.hearts_game.trick_num == 0:
                    trainer.hearts_game.playersPassCards()
                    trainer.hearts_game.getFirstTrickStarter()

                trainer.hearts_game.playTrick(trainer.hearts_game.trickWinner)

                # train anybody that needs to be trained
                for j, a_palyer in enumerate(trainer.hearts_game.players):
                    q_reward = trainer.get_reward(j)

                    a_palyer.store_reward(q_reward)

                trainer.hearts_game.currentTrick = Trick(trainer.hearts_game.trick_num)
            # tally scores
            trainer.hearts_game.handleScoring()

            # new round if no one has lost
            if trainer.hearts_game.losingPlayer.score < max_score:
                trainer.hearts_game.newRound()

            for j, a_palyer in enumerate(trainer.hearts_game.players):
                a_palyer.learn()

        winners = trainer.hearts_game.getWinner()
        winnerString = ""
        for w in winners:
            winnerString += w.name + " "
            if w.name == "Jack":
                tot_wins += 1
            if w.name == "Sam":
                sam_wins += 1

        if i % 25 == 0:
            print()
            for a, player in enumerate(trainer.hearts_game.players):
                print(player.name + ": " + str(player.score))
            print("Jack wins: ", tot_wins)
            print("Sam wins: ", sam_wins)
            print("num games: ", i)
            print(winnerString + "wins!")

        if i % 50 == 0:
            for player in trainer.hearts_game.players:
                try:
                    player.play_policy.save_model()
                except:
                    pass

        trainer.hearts_game.reset()
Exemplo n.º 26
0
def MonteCarloPlay(deck,
                   history_self,
                   history_A,
                   history_B,
                   history_C,
                   history_P0,
                   REPLAY=False):
    '''
    输入一摞牌,选出最应该出的牌

    规则打牌的判断机制,对于自己第几个出,自己出牌前已经打出的牌,红桃牌,黑桃Q的打出情况,
    以及应该打出大小点等各类情况都进行判断,从而选出应当打出的最适合的牌。
    input:
    deck:           列表,当前玩家手中的牌,如:
                    deck = [Card_C(point=7, suit=0),Card_C(point=10, suit=3),Card_C(point=11, suit=3)]
    history_self:   同deck列表,当前玩家已出的牌
    history_A:      同deck列表,玩家A已出的牌
    history_B:      同deck列表,玩家B已出的牌
    history_C:      同deck列表,玩家C已出的牌
    history_P0:     列表,每个回合第一个发牌的人的index。当前玩家:0, A:1, B:2, C:3
                    如:history_P0 = [0,1,1]表示第一回合是当前玩家先出的牌,第二回合玩家1先出的牌,第三回合还是玩家1先出的牌
    output:
    pos: Card_C类型,选出的最优的牌
    '''
    # -------------------------初始化MentorCarol类----------------------------------
    # 计算历史牌
    deck = sorted(deck, key=lambda x: x.suit * 10 + x.point)
    history = [history_self, history_A, history_B, history_C]

    #从输入参数中计算每轮出的牌
    allTurnsCard = []
    # 每个回合的出牌情况,总共三层,第一层为玩家i,出牌c,第二层为4个玩家,第三层为出了几个回合[[[1,Card(2,3)],[2,Card(3,3)],[],[]]]
    for i, j in enumerate(history_P0):
        tmp = []
        for k in range(4):
            now = history[(j + k) % 4]
            if len(now) > i:
                tmp.append([(j + k) % 4, now[i]])
        allTurnsCard.append(tmp)
    score_dict = getScoreFromAllcards(allTurnsCard)  # 每个玩家的得分dict
    thisTurnOutCard = allTurnsCard[-1] if allTurnsCard and len(
        allTurnsCard[-1]) != 4 else []  # 当前回合玩家出牌情况,按照出牌顺序排列
    #outQueen = True if [outCard for turn in allTurnsCard for outCard in turn if outCard[1] == Card_C(12,2)] else False
    outHeart = True if [j for i in allTurnsCard for j in i
                        if j[1].suit == 3] else False  # 红桃是否已出

    h = Hearts()
    # h是MonteCarlo使用的游戏类,在该类中,四个玩家轮流出牌并计算得分,计出MonteCarlo玩家出什么牌时得到最优的概率并选择出该牌
    oneMonte_threeNaive_anon = [
        Player("AI 1  ", PlayerTypes.MonteCarloAI, h),
        Player("AI 2 ", PlayerTypes.NaiveMinAI, h),
        Player("AI 3  ", PlayerTypes.NaiveMinAI, h),
        Player("AI 4  ", PlayerTypes.NaiveMaxAI, h)
    ]
    # 在模拟策略中使用一个MonteCarlo方法,其余三个使用Naive方法,此处可以设计不同的玩家规则来提高MonteCarlo模拟的表现
    h.players = oneMonte_threeNaive_anon
    h.heartsBroken = outHeart
    h.losingPlayer = None
    h.allTricks = []
    h.currentTrick = Trick()
    for j, i in enumerate(h.players):  # 更新四个玩家的得分
        i.score = score_dict[j]
    for i in thisTurnOutCard:  # 更新当前回合出的牌
        h.currentTrick.addCard(Card_C2Card(i[1]), i[0])
    h.trickWinner = thisTurnOutCard[0][0] if thisTurnOutCard else 0

    h.cardsPlayed = tuple(Card_C2Card(
        i[1]) for i in sum(allTurnsCard, []))  # keep track of state in a tuple
    h.cardsPlayedbyPlayer = {
        h.players[j]: [Card_C2Card(k) for k in i]
        for j, i in enumerate(history)
    }  # 每个玩家已出牌字典

    h.shift = len(thisTurnOutCard)  # 出牌次序
    h.winningPlayer = None
    h.winningPlayers = None  # list
    h.trickNum = len(history_P0) - 1  # 当前是第一轮出牌
    #h.dealer = 0 # so that first dealer is 0

    #更新模拟的Monto玩家的牌
    MontoPlayer = h.players[0]
    for j in deck:
        MontoPlayer.hand.addCard(Card(j.point, j.suit))
        MontoPlayer.hand.updateHand()  # 更新状态信息

    #--------------------------------------开始玩游戏----------------------------------------

    if MontoPlayer.hand.contains2ofclubs:  # 如果有梅花2,则调用play函数直接出2c
        addCard = MontoPlayer.play(option="play", c='2c')
    else:
        addCard = None
        while addCard is None:  # wait until a valid card is passed
            addCard = MontoPlayer.play(auto=True)
            if addCard is not None:
                if h.isValidCard(addCard, MontoPlayer) == False:
                    addCard = None
    out_card = Card_C(point=addCard.rank.rank,
                      suit=addCard.suit.iden)  # 输出牌转换为接口的nametuple类型
    return out_card
Exemplo n.º 27
0
class Hearts:
    def __init__(self):
        self.round_num = 0
        self.trick_num = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        self.passes = [1, -1, 2, 0]  # left, right, across, no pass
        self.currentTrick = Trick(self.trick_num)
        self.trickWinner = -1
        self.hearts_broken = False
        self.losingPlayer = None
        self.passingCards = [[], [], [], []]
        self.scoreboard = [0, 0, 0, 0]
        self.verbose = False
        '''
		Player physical locations:
		Game runs clockwise
			p3
		p2		p4
			p1
		'''
        self.players = [
            PolicyNN("Jason"),
            SimpleAI("Jack"),
            SimpleAI("Sam"),
            SimpleAI("JB")
        ]
        self.newRound()

    def reset(self):
        self.round_num = 0
        self.trick_num = 0  # initialization value such that first round is round 0
        self.dealer = -1  # so that first dealer is 0
        self.passes = [1, -1, 2, 0]  # left, right, across, no pass
        self.currentTrick = Trick(self.trick_num)
        self.trickWinner = -1
        self.hearts_broken = False
        self.losingPlayer = None
        self.passingCards = [[], [], [], []]
        self.scoreboard = [0, 0, 0, 0]

        for a_player in self.players:
            a_player.reset()

        self.newRound()

    def handleScoring(self):
        p, highestScore = None, 0
        if self.verbose:
            print("\n=====Scores=====")

        tempScores = []

        for aPlayer in self.players:
            tempScores.append(aPlayer.currentScore)

        if 26 in tempScores:
            player_shoot = tempScores.index(26)
            for i, player in enumerate(self.players):
                if i != player_shoot:
                    player.score += 26
        else:
            for a_player in self.players:
                a_player.score += a_player.currentScore

        for i, player in enumerate(self.players):
            if self.verbose:
                print(player.name + ": " + str(player.score))
            self.scoreboard[i] = player.score
            if player.score > highestScore:
                p = player
                highestScore = player.score
            self.losingPlayer = p

    def newRound(self):
        self.deck = Deck()
        self.deck.shuffle()
        self.dealCards()
        self.round_num += 1
        self.trick_num = 0
        self.trickWinner = -1
        self.hearts_broken = False
        self.dealer = (self.dealer + 1) % len(self.players)
        self.currentTrick = Trick(self.trick_num)
        self.passingCards = [[], [], [], []]
        for p in self.players:
            p.discardTricks()
            p.clearCurrentScore()

    def dealCards(self):
        i = 0
        while self.deck.size() > 0:
            self.players[i % len(self.players)].add_card(self.deck.deal())
            i += 1

    def passCards(self, index):
        passTo = self.passes[(self.round_num - 1) % 4]  # how far to pass cards
        passTo = (index + passTo) % len(
            self.players)  # the index to which cards are passed

        for i in range(cardsToPass):
            passCard = None
            while passCard is None:  # make sure string passed is valid
                passCard = self.players[index].pass_cards(passTo, i)
                if passCard is not None:
                    # remove card from player hand and add to passed cards
                    self.passingCards[passTo].append(passCard)
                    self.players[index].removeCard(passCard)

        if self.verbose:
            print(self.players[index].name + " is passing " +
                  self.printPassingCards(passTo) + " to " +
                  self.players[passTo].name)

    def distributePassedCards(self):
        for i, passed in enumerate(self.passingCards):
            for card in passed:
                self.players[i].add_card(card)

    def printPassingCards(self, playerIndex):
        out = "[ "
        for card in self.passingCards[playerIndex]:
            out += card.__str__() + " "
        out += "]"
        return out

    def playersPassCards(self):
        if self.round_num % 4 != 0:  # Don't pass on round 4
            if self.verbose:
                print("All player's hands before passing")
                self.printPlayers()

            for i in range(0, len(self.players)):
                if self.verbose:
                    print()  # spacing
                    curPlayer = self.players[i]
                    print(curPlayer.name + "'s hand: " + str(curPlayer.hand))
                self.passCards(i)

            self.distributePassedCards()
            if self.verbose:
                print()
                print("All player's hands after passing")
                self.printPlayers()

    def getFirstTrickStarter(self):
        for i, p in enumerate(self.players):
            if p.hand.hasCard('2c'):
                self.trickWinner = i

    def evaluateTrick(self):
        self.trickWinner = self.currentTrick.winner
        p = self.players[self.trickWinner]
        p.trickWon(self.currentTrick)

        if self.verbose:
            self.printCurrentTrick()
            print(p.name + " won the trick.")
            print()

    def getWinner(self):
        minScore = 200  # impossibly high
        winner = []
        for p in self.players:
            if p.score < minScore:
                winner = []
                winner.append(p)
                minScore = p.score
            elif p.score == minScore:
                winner.append(p)
        return winner

    def getLosers(self):
        return [pl for pl in self.players if pl.score >= 100]

    def playTrick(self, start):
        if self.verbose:
            print('\n==========Trick number ' + str(self.trick_num + 1) +
                  '==========')
        # have each player take their turn
        for i in range(start, start + len(self.players)):
            curPlayerIndex = i % len(self.players)
            curPlayer = self.players[curPlayerIndex]
            played_card = None
            if self.verbose:
                self.printCurrentTrick()
                print(curPlayer.name + "'s hand: " + str(curPlayer.hand))

            game_state = GameState(curPlayerIndex, self.currentTrick,
                                   self.hearts_broken, self.players)

            while played_card is None:  # wait until a valid card is passed

                played_card = curPlayer.play(game_state)
                suit = played_card[-1:]
                rank = played_card[:-1]

                # the rules for what cards can be played
                # card set to None if it is found to be invalid
                if played_card is not None:

                    # if it is not the first trick and no cards have been played,
                    # set the first card played as the trick suit if it is not a heart
                    # or if hearts have been broken
                    if self.trick_num != 0 and self.currentTrick.cardsInTrick == 0:
                        if suit == 'h' and not self.hearts_broken:
                            # if player only has hearts but hearts have not been broken,
                            # player can play hearts
                            if not curPlayer.hasOnlyHearts():
                                # print("Hearts have not been broken.")
                                played_card = None
                            else:
                                self.currentTrick.set_trick_suit(played_card)
                        else:
                            self.currentTrick.set_trick_suit(played_card)

                    # check if card played in first trick is not a heart or qs
                    if self.trick_num == 0:
                        if played_card is not None:
                            if self.currentTrick.suit == 'x' and played_card != '2c':
                                print(
                                    "First card of the round must be the 2 of clubs"
                                )
                                played_card = None
                            if suit == 'h' or (suit == 's' and rank == 'Q'):
                                if curPlayer.hand.has_only_points():
                                    print(
                                        "Points cannot be played on the first hand when possible."
                                    )
                                    played_card = None

                    # player tries to play off suit but has trick suit
                    if played_card is not None and suit != self.currentTrick.suit:
                        if curPlayer.has_suit(self.currentTrick.suit):
                            print("Must play the suit of the current trick.")
                            played_card = None
                        elif suit == 'h':
                            self.hearts_broken = True

                    if played_card is not None:
                        if rank == 'Q' and suit == 's':
                            self.hearts_broken = True
                        curPlayer.removeCard(played_card)

            self.currentTrick.add_card(played_card, curPlayerIndex)

        self.evaluateTrick()
        self.trick_num += 1

    def printPlayers(self):
        for p in self.players:
            print(p.name + ": " + str(p.hand))

    # show cards played in current trick
    def printCurrentTrick(self):
        if self.currentTrick.cardsInTrick == 4:
            trickStr = '\n=====Final Trick=====\n'
        else:
            trickStr = '\n=====Current Trick=====\n'
        trickStr += "Trick suit: " + self.currentTrick.suit.__str__() + "\n"
        for i, card in enumerate(self.currentTrick.trick):
            if self.currentTrick.trick[i] is not 0:
                trickStr += self.players[i].name + ": " + str(card) + "\n"
            else:
                trickStr += self.players[i].name + ": None\n"
        print(trickStr)
Exemplo n.º 28
0
class Hearts:
	def __init__(self):
		
		self.roundNum = 0
		self.trickNum = 0 # initialization value such that first round is round 0
		self.dealer = -1 # so that first dealer is 0
		self.passes = [1, -1, 2, 0] # left, right, across, no pass
		self.currentTrick = Trick()
		self.trickWinner = -1
		self.heartsBroken = False
		self.losingPlayer = None
		self.passingCards = [[], [], [], []]


		# Make four players

		self.players = [Player("Danny"), Player("Desmond"), Player("Ben"), Player("Tyler")]
		
		'''
		Player physical locations:
		Game runs clockwise

			p3
		p2		p4
			p1

		'''

		# Generate a full deck of cards and shuffle it
		self.newRound()

	def handleScoring(self):
		p, highestScore = None, 0
		print "\nScores:\n"
		for player in self.players:
			print player.name + ": " + str(player.score)
			if player.score > highestScore:
				p = player
				highestScore = player.score
			self.losingPlayer = p

		

	def newRound(self):
		self.deck = Deck()
		self.deck.shuffle()
		self.roundNum += 1
		self.trickNum = 0
		self.trickWinner = -1
		self.heartsBroken = False
		self.dealer = (self.dealer + 1) % len(self.players)
		self.dealCards()
		self.currentTrick = Trick()
		self.passingCards = [[], [], [], []]
		for p in self.players:
			p.discardTricks()

	def getFirstTrickStarter(self):
		for i,p in enumerate(self.players):
			if p.hand.contains2ofclubs:
				self.trickWinner = i

	def dealCards(self):
		i = 0
		while(self.deck.size() > 0):
			self.players[i % len(self.players)].addCard(self.deck.deal())
			i += 1


	def evaluateTrick(self):
		self.trickWinner = self.currentTrick.winner
		p = self.players[self.trickWinner]
		p.trickWon(self.currentTrick)
		self.printCurrentTrick()
		print p.name + " won the trick."
		# print 'Making new trick'
		self.currentTrick = Trick()
		print self.currentTrick.suit
		

	def passCards(self, index):
		print self.printPassingCards()
		passTo = self.passes[self.trickNum] # how far to pass cards
		passTo = (index + passTo) % len(self.players) # the index to which cards are passed
		while len(self.passingCards[passTo]) < cardsToPass: # pass three cards
			passCard = None
			while passCard is None: # make sure string passed is valid
				passCard = self.players[index].play(option='pass')
				if passCard is not None:
					# remove card from player hand and add to passed cards
					self.passingCards[passTo].append(passCard)
					self.players[index].removeCard(passCard)

	def distributePassedCards(self):
		for i,passed in enumerate(self.passingCards):
			for card in passed:
				self.players[i].addCard(card)
		self.passingCards = [[], [], [], []]


	def printPassingCards(self):
		out = "[ "
		for passed in self.passingCards:
			out += "["
			for card in passed:
				out += card.__str__() + " "
			out += "] "
		out += " ]"
		return out


	def playersPassCards(self):
		
		self.printPlayers()
		if not self.trickNum % 4 == 3: # don't pass every fourth hand
			for i in range(0, len(self.players)):
				print # spacing
				self.printPlayer(i)
				self.passCards(i % len(self.players))

			self.distributePassedCards()
			self.printPlayers()

	def playTrick(self, start):
		shift = 0
		if self.trickNum == 0:
			startPlayer = self.players[start]
			addCard = startPlayer.play(option="play", c='2c')
			startPlayer.removeCard(addCard)

			self.currentTrick.addCard(addCard, start)

			shift = 1 # alert game that first player has already played

		# have each player take their turn
		for i in range(start + shift, start + len(self.players)):
			self.printCurrentTrick()
			curPlayerIndex = i % len(self.players)
			self.printPlayer(curPlayerIndex)
			curPlayer = self.players[curPlayerIndex]
			addCard = None

			while addCard is None: # wait until a valid card is passed
				
				addCard = curPlayer.play(auto=auto) # change auto to False to play manually


				# the rules for what cards can be played
				# card set to None if it is found to be invalid
				if addCard is not None:
					
					# if it is not the first trick and no cards have been played,
					# set the first card played as the trick suit if it is not a heart
					# or if hearts have been broken
					if self.trickNum != 0 and self.currentTrick.cardsInTrick == 0:
						if addCard.suit == Suit(hearts) and not self.heartsBroken:
							# if player only has hearts but hearts have not been broken,
							# player can play hearts
							if not curPlayer.hasOnlyHearts():
								print curPlayer.hasOnlyHearts()
								print curPlayer.hand.__str__()
								print "Hearts have not been broken."
								addCard = None
							else:
								self.currentTrick.setTrickSuit(addCard)
						else:
							self.currentTrick.setTrickSuit(addCard)

					# player tries to play off suit but has trick suit
					if addCard is not None and addCard.suit != self.currentTrick.suit:
						if curPlayer.hasSuit(self.currentTrick.suit):
							print "Must play the suit of the current trick."
							addCard = None
						elif addCard.suit == Suit(hearts):
							self.heartsBroken = True

					if self.trickNum == 0:
						if addCard is not None:
							if addCard.suit == Suit(hearts):
								print "Hearts cannot be broken on the first hand."
								self.heartsBroken = False
								addCard = None
							elif addCard.suit == Suit(spades) and addCard.rank == Rank(queen):
								print "The queen of spades cannot be played on the first hand."
								addCard = None

					if addCard is not None and self.currentTrick.suit == Suit(noSuit):
						if addCard.suit == Suit(hearts) and not self.heartsBroken:
							print "Hearts not yet broken."
							addCard = None

					

					if addCard is not None:
						if addCard == Card(queen, spades):
							self.heartsBroken = True
						curPlayer.removeCard(addCard)


			self.currentTrick.addCard(addCard, curPlayerIndex)
			
		self.evaluateTrick()
		self.trickNum += 1

	# print player's hand
	def printPlayer(self, i):
		p = self.players[i]
		print p.name + "'s hand: " + str(p.hand)

	# print all players' hands
	def printPlayers(self):
		for p in self.players:
			print p.name + ": " + str(p.hand) 

	# show cards played in current trick
	def printCurrentTrick(self):
		trickStr = '\nCurrent table:\n'
		trickStr += "Trick suit: " + self.currentTrick.suit.__str__() + "\n"
		for i, card in enumerate(self.currentTrick.trick):
			if self.currentTrick.trick[i] is not 0:
				trickStr += self.players[i].name + ": " + str(card) + "\n"
			else:
				trickStr += self.players[i].name + ": None\n"
		print trickStr

	def getWinner(self):
		minScore = 200 # impossibly high
		winner = None
		for p in self.players:
			if p.score < minScore:
				winner = p
				minScore = p.score
		return winner