Пример #1
0
    def play(self):
        poker_players = []

        num_players = input("How many players? ")
        for i in range(int(num_players)):
            player_name = input("Name of poker player {}? ".format(i + 1))
            poker_player = PokerPlayer(player_name)
            poker_players.append(poker_player)

        print("Dealing cards")
        deck = Deck()
        deck.shuffle()
        for i in range(7):
            for poker_player in poker_players:
                poker_player.add_card(deck.deal())
                print(poker_player)

            if (i < 6):
                dealmore = input("Deal more card(y or n)? ")
                if (dealmore.lower() == 'n'):
                    return

        for poker_player in poker_players:
            poker_player.review_all_fiver_hands()
            poker_score = poker_player.get_top_poker_score()
            print(poker_player.name.center(30, '-'))
            print(poker_score)
Пример #2
0
    def __init__(self):
        deck = Deck()

        deck.shuffle()

        deck = deck.get_cards()

        piles: List[List[Card]] = []

        for i in range(Game.PILES):
            piles.append([])
            pile_len = i + 1

            for j in range(pile_len):
                card = deck.pop()

                if not j == pile_len - 1:
                    card.visible = False

                piles[i].append(card)

        hand: List[Card] = []

        self.varInput = VarInput()

        self.deck = deck
        self.hand = hand
        self.piles = piles
        self.finished = [0] * len(Card.SUITS)
Пример #3
0
class DeckTests(unittest.TestCase):
    def setUp(self):
        self.deck = Deck()

    def test_init(self):
        self.assertTrue(isinstance(self.deck.cards, list))
        self.assertEqual(len(self.deck.cards), 52)

    def test_repr(self):
        self.assertEqual(repr(self.deck), 'Deck of 52 cards')

    def test_count(self):
        self.assertEqual(self.deck.count(), 52)
        self.deck.cards.pop()
        self.assertEqual(self.deck.count(), 51)

    def test_deal_sufficient_cards(self):
        cards = self.deck._deal(10)
        self.assertEqual(len(cards), 10)
        self.assertEqual(self.deck.count(), 42)

    def test_deal_insufficient_cards(self):
        cards = self.deck._deal(100)
        self.assertEqual(len(cards), 52)
        self.assertEqual(self.deck.count(), 0)

    def test_deal_no_cards(self):
        self.deck._deal(self.deck.count())
        with self.assertRaises(ValueError):
            self.deck._deal(1)

    def test_deal_card(self):
        card = self.deck.cards[-1]
        dealt_card = self.deck.deal_card()
        self.assertEqual(card, dealt_card)
        self.assertEqual(self.deck.count(), 51)

    def test_deal_hand(self):
        cards = self.deck.deal_hand(20)
        self.assertEqual(len(cards), 20)
        self.assertEqual(self.deck.count(), 32)

    def test_shuffle_full_deck(self):
        cards = self.deck.cards[:]
        self.deck.shuffle()
        self.assertNotEqual(cards, self.deck.cards)
        self.assertEqual(self.deck.count(), 52)

    def test_shuffle_not_full_deck(self):
        self.deck.deal(1)
        with self.assertRaises(ValueError):
            self.deck.shuffle()
Пример #4
0
class Blackjack(object):
    def __init__(self):
        self._deck = Deck()
        self._deck.shuffle()

        # Pass the player and dealer two cards each
        self._player = Player([self._deck.deal(), self._deck.deal()])
        self._dealer = Dealer([self._deck.deal(), self._deck.deal()])

    def play(self):
        print("Player:\n", self._player)
        print("Dealer:\n", self._dealer)

        # Player hits until user says NO
        while True:
            choice = input("Do you want a hit? [y/n]: ")
            if choice in ("Y", "y"):
                self._player.hit(self._deck.deal())
                points = self._player.getPoints()
                print("Player:\n", self._player)
                if points >= 21:
                    break
            else:
                break
        playerPoints = self._player.getPoints()
        if playerPoints > 21:
            print("You bust and lose")
        else:
            # Dealer's turn to hit
            self._dealer.hit(self._deck)
            print("Dealer:\n", self._dealer)
            dealerPoints = self._dealer.getPoints()

            # Determine the outcome
            if dealerPoints > 21:
                print(" Dealer busts and you win")
            elif dealerPoints > playerPoints:
                print("Dealer wins")
            elif dealerPoints < playerPoints and playerPoints <= 21:
                print("You win")
            elif dealerPoints == playerPoints:
                if self._player.hasBlackjack() and \
                        not self._dealer.hasBlackjack():
                    print("You win")
                elif not self._player.hasBlackjack() and \
                        self._dealer.hasBlackjack():
                    print("Dealer wins")
                else:
                    print("There is a tie")
Пример #5
0
class CardDemo(Frame):
    def __init__(self):
        """Sets up the window and widgets."""
        Frame.__init__(self)
        self.master.title("Card Demo")
        self.grid()
        self._deck = Deck()
        self._backImage = PhotoImage(file=Card.BACK_NAME)
        self._cardImage = None
        self._imageLabel = Label(self, image=self._backImage)
        self._imageLabel.grid(row=0, column=0, rowspan=3)
        self._textLabel = Label(self, text="")
        self._textLabel.grid(row=3, column=0)

        # DealButton
        self._dealButton = Button(self, text="Deal", command=self._deal)
        self._dealButton.grid(row=0, column=1)
        # ShuffleButton
        self._shuffleButton = Button(self,
                                     text="Shuffle",
                                     command=self._shuffle)
        self._shuffleButton.grid(row=1, column=1)
        # newButton
        self._newButton = Button(self, text="New Deck", command=self._new)
        self._newButton.grid(row=2, column=1)

    def _deal(self):
        """If the deck is not empty, deals and display the
        next card.  Otherwise, returns the program to its
        initial state."""
        card = self._deck.deal()
        if card != None:
            self._cardImage = PhotoImage(file=card.fileName)
            self._imageLabel["image"] = self._cardImage
            self._textLabel["text"] = str(card)
        else:
            self._new()

    def _shuffle(self):
        self._deck.shuffle()

    def _new(self):
        """Returns the program to its initial state."""
        self._deck = Deck()
        self._cardImage = None
        self._imageLabel["image"] = self._backImage
        self._textLabel["text"] = ""
Пример #6
0
class BlackJack:
    def __init__(self):
        self.deck = Deck()
        self.players = [Dealer(), Player()]
        self.max_players = max_players

    def add_player(self, player):
        if len(self.players) <= 8:
            raise TooManyPlayers

        self.players.append(player)

    def initial_deal(self):
        self.deck.shuffle()
        self.deck.cut()

    def deal(self):
        for player in players:
            player.hand.add_card(self.deck.draw())
Пример #7
0
if __name__ == '__main__':
    import doctest
    doctest.testmod()

#   Play around
    verbose = False
    deck = Deck()
    n_hands = 1000000

    hist = {}

    total = 0
    mn = 30
    mx = -1
    for h in range(n_hands):
        deck.shuffle()

        hand = []
        for i in range(4):
            hand.append(deck.deal.next())
        starter = deck.deal.next()

        if verbose:
            print("Hand {}: [{}] {} {} {} {}".format(h, starter, *hand))

        pts = score_hand(hand, starter, verbose)
        if pts in hist:
            hist[pts] += 1
        else:
            hist[pts] = 1
Пример #8
0
    def card_count(self):
        return len(self.hand)

    def has_empty_hand(self):
        return not self.hand


if __name__ == '__main__':
    from card import Deck
    """Reference: Implementing an Unordered List: Linked Lists
    http://interactivepython.org/courselib/static/pythonds/BasicDS/ImplementinganUnorderedListLinkedLists.html
    """

    deck = Deck()
    deck.shuffle()

    john = Player('John')
    jane = Player('Jane')
    jess = Player('Jess')
    june = Player('June')
    jack = Player('Jack')

    player_list = ActivePlayer(john, jane, jess, june)
    # player_list.in_control(june)
    # player_list.remove(june)
    # print(player_list.next_turn())
    # print(player_list.next_turn())
    # print(player_list.next_turn())
    # print(player_list.next_turn())
    # print(player_list.next_turn())
Пример #9
0
class Game:
    def __init__(self):
        self.state = None
        self.state_history = []
        self.width = 1300
        self.height = 700
        self.window = None
        self.clock = None  # used for fps
        self.game_over = False  # true when game is over
        self.title_image = None  # title image
        self.empty_table = None  # empty table image

        self.cards = Deck()
        self.cards.shuffle()  # O(n)
        self.table = Table()
        self.player = Player('p')
        self.bot = Bot()

    def init(self):
        pygame.init()  # setup pygame

        self.window = pygame.display.set_mode(
            (self.width, self.height))  # initializes the window
        pygame.display.set_caption("Texas Holdem")  # Title of window

        self.clock = pygame.time.Clock()

        self.title_image = pygame.image.load("PNG-cards-1.3/title_image.png")
        self.title_image = pygame.transform.scale(
            self.title_image, (self.width, self.height))  # resizing

        self.empty_table = pygame.image.load("PNG-cards-1.3/empty_table.jpg")
        self.empty_table = pygame.transform.scale(
            self.empty_table, (self.width, self.height))  # resizing

        self.game_over = False

    def set_game_state(self, state):
        self.state = state
        self.state_history.append(state)

    def infer_state(self, player_turn, table, current_call, can_raise, done):
        if done:
            self.set_game_state(GameState.END_ROUND)
            return

        if not can_raise:
            self.set_game_state(GameState.ALL_IN)
            return

        self.set_game_state(
            GameState.calc_state(
                table, player_turn,
                type(current_call) is int and current_call > 0))
        return

    def get_events(self):
        return pygame.event.get()

    def is_over(self):
        return self.game_over

    def end_game(self):
        pygame.quit()
        quit()
Пример #10
0
class TestDeck(unittest.TestCase):

    def setUp(self):
        self.deck = Deck()
        self.deck_multiple = Deck(10)

    def tearDown(self):
        del self.deck
        del self.deck_multiple

    def test_deck_all_cards_is_list(self):
        self.assertIsInstance(
            self.deck.all_cards, list,
            'Deck is not a list. Check the deck constructor'
        )

    def test_deck_all_cards_has_card_instance(self):
        for elem in self.deck.all_cards:
            self.assertIsInstance(
                elem, Card,
                'Deck has no card instance. Check the deck constructor.'
            )

    def test_deck__len__(self):
        self.assertEqual(
            len(self.deck.all_cards), 52,
            'Deck does not have 52 cards. Check the suits, ranks and values, global variables for any discrepency.'
        )

    def test_deck_imlements_multiple(self):
        self.assertEqual(
            len(self.deck_multiple), 520, 'Multiple decks not implemented.'
        )

    def test_deck_shuffle_different_than_original_deck(self):
        original_deck = copy.deepcopy(self.deck)
        self.deck.shuffle()
        self.assertNotEqual(
            self.deck.all_cards, original_deck.all_cards,
            'Shuffle method not working. Check if random is imported or the deck value is assigned to another variable.'
        )

    def test_deck_shuffle_deck_not_none(self):
        self.deck.shuffle()
        self.assertIsNotNone(
            self.deck, 'Deck is None object. Check the shuffle method.'
        )

    def test_deck_lenght_deck_after_dealing_one(self):
        original_deck = copy.deepcopy(self.deck)
        self.deck.deal_one_card()
        self.assertEqual(
            len(self.deck),
            len(original_deck) - 1,
            'Deal one card is not working. Check if pop is implemented and calling the right object.'
        )

    def test_deck_deal_one_card_if_element_is_card(self):
        self.assertIsInstance(
            self.deck.deal_one_card(), Card,
            'Deal one card method is not returning card objects.'
        )

    def test_deck_lenght_deck_after_dealing_two(self):
        original_deck = copy.deepcopy(self.deck)
        self.deck.deal_two_cards()
        self.assertEqual(
            len(self.deck),
            len(original_deck) - 2,
            'Deal two cards is not working. Check if method is implemented and calling the right object.'
        )

    def test_deck_deal_two_cards_if_return_is_list(self):
        self.assertEqual(
            type(self.deck.deal_two_cards()), list,
            'Deal two cards is not producing a list. Check if the return value of the method is actually a list.'
        )

    def test_deck_deal_two_cards_if_elements_are_card(self):
        for elem in self.deck.deal_two_cards():
            self.assertIsInstance(
                elem, Card,
                'Deal two cards is not adding Card objects. Check if the object reference is correct.'
            )
Пример #11
0
class App:
	'''The main card game application.  This GUI creates a Deck and Board
	model objects and uses them to keep track of legal moves, where the
	cards are on the board, etc., and then displays card images for the
	cards on a created BoardGui (the GUI view).
	'''

	def __init__(self, document, canv):
		'''Store the main window, create the Board and Deck models;
		create all the buttons and labels to allow the user to manipulate the game.
		'''

		self._doc = document
		self._canv = canv	# fabric Canvas object

		self._canv.on("mouse:up", self.onCardClick)

		self.loadCardMoveSound()
		self.loadCardInPlaceSound()
		self.loadEndOfRoundSound()
		self.loadFanfareSound()
		self._playSounds = True

		self._board = Board()
		self._deck = Deck()
		self._deck.addAllCards()
		self._copyOfDeck = self._deck.makeCopy()

		# We'll fill this in when we remove the aces from the board.
		self._removedAces = []

		# keeps track of cards that can be moved: each item is a tuple:
		# (card, row, col)
		self._moveableCards = []

		# A mapping from card object to CardImg object.  We do it this way
		# so that the card object (in the model) remains agnostic of the view
		# being used on it.
		self._card2ImgDict = {}

		self._score = 0
		# a list of templates of high scores we can update when high scores
		# change, so the screen changes immediately
		self._score_val = []
		self._storage = local_storage.storage
		self.loadSettingsFromStorage()

		# count of cards correctly placed, per round. 1st round is in
		# index 0, and initialized to 0 cards placed.
		self._cardsPlacedPerRound = [0]

		self._roundNum = 1

		# 2 rows of info about the game.
		self._game_info_elem = html.DIV(Class="game-info")
		self._doc <= self._game_info_elem
		self._game_info2_elem = html.DIV(Class="game-info")
		self._doc <= self._game_info2_elem

		self._next_round_btn = html.BUTTON(
			"Next Round", Class="button", disabled=True)
		self._next_round_btn.bind('click', self.nextRound)
		self._game_info_elem <= self._next_round_btn

		self._round_info_elem = \
			html.SPAN("Round: {roundNum}",
					  Class="info-text", id="round_num")
		self._game_info_elem <= self._round_info_elem
		self._round_num_val = template.Template(self._round_info_elem)
		self.updateRoundNum()

		self._cardsInPlace = self._board.countCardsInPlace()
		self._cards_in_place_elem = html.SPAN(
			"Cards in place: {cardsInPlace}", Class="info-text")
		self._game_info_elem <= self._cards_in_place_elem
		self._cardsInPlace_val = template.Template(self._cards_in_place_elem)
		self.updateCardsInPlace()

		self._score_info_elem = html.SPAN(
			"Score: {score}", Class="info-text")
		self._game_info_elem <= self._score_info_elem
		self._scoreInfo_val = template.Template(self._score_info_elem)

		self._pts_per_card_info_elem = html.SPAN(
			"Pts per card: {ptsPerCard}", Class="info-text")
		self._game_info_elem <= self._pts_per_card_info_elem
		self._ptsPerCardInfo_val = template.Template(
			self._pts_per_card_info_elem)
		self.updateScore()

		self._new_game_btn = html.BUTTON(
			"New Game", Class="button", disabled=True)
		self._new_game_btn.bind('click', self.newGameClickHandler)
		self._game_info_elem <= self._new_game_btn

		self._repeat_game_btn = html.BUTTON(
			"Repeat Game", Class="button")
		self._repeat_game_btn.bind('click', self.repeatGameClickHandler)
		self._game_info_elem <= self._repeat_game_btn

		self._messageDiv = self.createMessageDiv()

		switch_button = html.BUTTON ('Switch Deck', Class = 'button')
		switch_button.bind ('click', switch_card_sources)
		self._game_info_elem <= switch_button

		self._status_elem = html.SPAN("{status}")
		self._game_info2_elem <= self._status_elem
		self._status_val = template.Template(self._status_elem)
		self.setStatus("Cards placed this round: 0")

		self._playSoundsSpan = html.SPAN()
		self._game_info2_elem <= self._playSoundsSpan
		self._playSoundsLabel = html.LABEL("Play sounds: ")
		self._playSoundsSpan <= self._playSoundsLabel
		self._playSoundsCheckBox = html.INPUT(
			type="checkbox", checked=self._playSounds)
		self._playSoundsCheckBox.bind('click', self.togglePlaySounds)
		self._playSoundsSpan <= self._playSoundsCheckBox

		# A mapping from Card object to CardImg object.  This is needed so
		# that we map a card in the board layout to the CardImg, which should
		# then be placed at a certain location.  (We don't keep a reference to
		# the CardImg in Card because it just shouldn't know how it is displayed.)
		cards = self._deck.getCards()
		for card in cards:
			cardimg = CardImg(card, self._canv)
			self._card2ImgDict[id(card)] = cardimg

		self._boardGui = BoardGui(self._board, self._canv, self._card2ImgDict)

		self.loadHighScores()

		self.initNewGame()

	def initNewGame(self):

		self._board.layoutCards(self._deck)

		self._boardGui.displayLayout()
		self._cardsInPlace = self._board.countCardsInPlace()
		self._cardsPlacedPerRound = [self._cardsInPlace]

		self.updateCardsInPlace()
		self.updateScore()

		# Disable the "next round" button.
		self.disableNextRoundBtn()
		timer.set_timeout(self.removeAces, 1500)

	def removeAces(self):
		'''Go through the board and remove the aces from the board.
		Then hide the corresponding CardImgs in the BoardGui for the
		aces.
		'''
		self._removedAces = self._board.removeAces()
		for card in self._removedAces:
			self._card2ImgDict[id(card)].erase()

		self.enableNewGameButton()

		if self.isEndOfRoundOrGame():
			return

		self._moveableCards = self._board.findPlayableCards()
		self.highlightMovableCards()
		self.markGoodCards()

	def isEndOfRoundOrGame(self):
		'''Check if the game is over or the round is over.  Return True
		if it is.
		'''
		if self._board.gameCompletelyDone():
			score = self.currentScore()
			self.displayMessageOverCanvas(
				f"Congratulations!\n\nYou finished the game in {self._roundNum} rounds\n" +
				f"with a score of {score}.\n" +
				"Click 'New Game' to try again.", 5000)
			self.addScoreToHighScoresTable(score)
			self.setStatus("Cards placed this round: " +
						   str(self._cardsPlacedPerRound[self._roundNum - 1]))
			self.playFanfareSound()
			return True

		if not self._board.moreMoves():
			self.setStatus("No more moves")
			# enable the next round button by deleting the disabled attribute
			self.playEndOfRoundSound()
			self.enableNextRoundBtn()
		return False

	def onCardClick(self, event):
		'''Called back when a card is clicked to be moved into an open spot:
		Figure out when card was clicked using the _imgDict to map id to cardImg.
		Find the related card object in the board, and from that, the cards
		  current row/col.
		Check with the board object to see if the card can be moved and if so
		  what is the dest row/col.
		Move the card in the board and in the boardGui.
		Check if there are more moves, the game is done, etc.
		'''
		DEBUG and debug ('Got click!')

		# print("number of objects = ", len(self._canv.getObjects()))

		ptr = self._canv.getPointer(event)
		x = ptr.x
		y = ptr.y
		card = self.getClickedCard(x, y)
		if card is None:
			return

		DEBUG and debug ('got card')
		if self.cardIsMoveable(card):

			fromRow, fromCol = self._board.findCardLocation(card)
			DEBUG and debug ('got card location')

			res = self._board.getMoveableCardDest(card)
			if res is None:
				print("Cannot move that card.")
				return
			toRow, toCol = res   # split into the 2 parts.
			DEBUG and debug ('got card dest')

			self.eraseMovableCardHighlights()
			cardsInPlaceBeforeMove = self._cardsInPlace
			self._board.moveCard(card, fromRow, fromCol, toRow, toCol)
			self._boardGui.moveCard(card, toRow, toCol)
			self._cardsInPlace = self._board.countCardsInPlace()
			DEBUG and debug ('moved card')
			newCardsInPlace = self._cardsInPlace - cardsInPlaceBeforeMove
			if newCardsInPlace > 0:
				self.playCardInPlaceSound()
				DEBUG and debug ('played card in place sound')
				self._cardsPlacedPerRound[self._roundNum-1] += newCardsInPlace
				DEBUG and debug ('calced cardsPlacedPerRound')
				self.updateCardsInPlace()
				DEBUG and debug ('updates Cards in palce')
				self.updateScore()
				DEBUG and debug ('scores udpated')
				self.markGoodCards()
				DEBUG and debug ('marked good cards')
				self.setStatus("Cards placed this round: " +
							   str(self._cardsPlacedPerRound[self._roundNum - 1]))
			else:
				# just a normal move
				self.playCardMoveSound()

			DEBUG and debug ('checking if end of round or game')
			if self.isEndOfRoundOrGame():
				return

			DEBUG and debug ('updating movable cards')
			self._moveableCards = self._board.findPlayableCards()
			DEBUG and debug ('updated movable cards')
			self.highlightMovableCards()
			DEBUG and debug ('highlighted movable cards')

		else:
			# user clicked another card: so highlight the card it would
			# have to go to the right of.
			# E.g., you click 7D, highlight 6D
			(card, row, col) = self._board.findLowerCard(card)
			if card is not None:
				self.flashLowerCard(card, row, col)

	def toggle_card_type (self, ev):
		self.newGameClickHandler (ev, self._copyOfDeck)

	def repeatGameClickHandler(self, ev):
		self.newGameClickHandler(ev, self._copyOfDeck)

	def newGameClickHandler(self, ev, deck=None):
		'''Call back when New Game button is pressed.
		'''

		self.disableNewGameButton()
		self._boardGui.clear()

		self._roundNum = 1
		self.updateRoundNum()
		self._cardsPlacedPerRound = [0]

		# Add all the cards on the board to the deck.
		if deck:
			self._deck = deck
			self._copyOfDeck = self._deck.makeCopy()
		else:
			self._deck.addCards(self._board.getAllCards())
			if self._deck.numCards() == 48:
				# The board had aces removed, so add the aces back to the deck.
				for card in self._removedAces:
					self._deck.addCard(card)
			self._deck.shuffle()

		self._board.reinit()

		self.initNewGame()

	def nextRound(self, ev):
		'''Callback for when the user clicks the "Next Round" button.
		Increment the round number counter;
		Remove the cards from the board that are not in the correct place;
		Add those cards, and the aces, back to the deck; shuffle it;
		Update the display to show the good cards only, for 1 second;
		Register nextRoundContined() to be called.
		'''

		self.disableNewGameButton()

		# No cards placed yet in this round
		self._cardsPlacedPerRound.append(0)
		self._roundNum += 1
		self.updateRoundNum()
		discarded = self._board.removeIncorrectCards()
		self._deck.addCards(discarded)
		# Add the aces back to the deck.
		for card in self._removedAces:
			self._deck.addCard(card)
		self._deck.shuffle()

		# display the board with only "good cards" for 1 second.
		for card in discarded:
			cardimg = self._card2ImgDict[id(card)]
			cardimg.erase()
		self.updateScore()

		self.setStatus("Cards placed this round: " +
					   str(self._cardsPlacedPerRound[self._roundNum - 1]))

		timer.set_timeout(self.nextRoundContinued, 1000)

	def nextRoundContinued(self):
		'''Continuation of nextRound():
		Lay out all the cards from the deck on the board;
		Update the button states;
		Wait a bit, then call removeAces().
		'''

		# Deck is shuffled.  Now, add cards to the board.
		self._board.layoutCards(self._deck)
		self._boardGui.displayLayout()

		self.disableNextRoundBtn()
		# After 1.5 seconds of showing all cards, remove the aces.
		timer.set_timeout(self.removeAces, 1500)

	def getClickedCard(self, x, y):
		cards = self._board.getAllCards()
		for card in cards:
			cardImg = self._card2ImgDict[id(card)]
			if (x, y) in cardImg:
				return card
		return None

	def cardIsMoveable(self, card):
		for mcard, row, col in self._moveableCards:
			if mcard == card:
				return True
		return False

	def eraseMovableCardHighlights(self):
		for card, row, col in self._moveableCards:
			self.eraseOutline(card)

	def highlightMovableCards(self):
		'''Get the cards that have a space after them, find the cards
		that could go in those spaces, and draw a rectangle around those
		cards.
		'''
		for card, row, col in self._moveableCards:
			self.drawOutline(card, MOVABLE_CARD_COLOR)

	def markGoodCards(self):
		'''Redraw all the outlines around good cards.'''
		goodCards = self._board.getCardsInPlace()
		DEBUG and debug ('got cards in place')
		for card, r, c in goodCards:
			self.drawOutline(card, CARDS_IN_PLACE_COLOR)

	def flashLowerCard(self, card, row, col):
		cardimg = self._card2ImgDict[id(card)]
		cardimg.bounce()

	# def unflashLowerCard(self):
	#	 self.eraseOutline(self._flashingCard)
	#	 # the card that was flashed may have been one of these others
	#	 # so we have to redraw everything.
	#	 self.highlightMovableCards()
	#	 self.markGoodCards()

	def drawOutline(self, card, color):
		cardimg = self._card2ImgDict[id(card)]
		cardimg.displayOutline(color)

	def eraseOutline(self, card):
		cardimg = self._card2ImgDict[id(card)]
		cardimg.eraseOutline()

	def enableNextRoundBtn(self):
		del self._next_round_btn.attrs['disabled']

	def disableNextRoundBtn(self):
		self._next_round_btn.attrs['disabled'] = True

	def getPtsPerCard(self):
		'''10 pts for round 1, 9 for round 2, etc...'''
		return 11 - self._roundNum

	def currentScore(self):
		'''Compute the total score each time by summing the number of
		cards placed correctly in a round * the value of a card per round.'''
		res = 0
		for rnd in range(len(self._cardsPlacedPerRound)):
			res += (10 - rnd) * self._cardsPlacedPerRound[rnd]
		return res

	def updateScore(self):
		self._scoreInfo_val.render(score=self.currentScore())
		self._ptsPerCardInfo_val.render(ptsPerCard=self.getPtsPerCard())

	def updateCardsInPlace(self):
		self._cardsInPlace_val.render(cardsInPlace=self._cardsInPlace)

	def updateRoundNum(self):
		self._round_num_val.render(roundNum=self._roundNum)

	def setStatus(self, status):
		self._status_val.render(status=status)

	def enableNewGameButton(self):
		del self._new_game_btn.attrs['disabled']

	def disableNewGameButton(self):
		self._new_game_btn.attrs['disabled'] = True

	def createMessageDiv(self):
		elem = html.DIV(Class="message-box")
		elem.style.top = f"{CANVAS_HEIGHT / 3}px"
		elem.style.left = f"{CANVAS_WIDTH / 3}px"
		elem.style.width = f"{CANVAS_WIDTH / 3}px"
		# elem.style.height = f"{CANVAS_HEIGHT / 3}px"
		return elem

	def displayMessageOverCanvas(self, msg, ms):
		'''Split msg on newlines and put each result into its own div,
		which is then centered in the containing div, and displayed
		on over the canvas.  Undisplay it after *ms* milliseconds.
		'''
		self._messageDiv.style.display = "block"
		lines = msg.split('\n')
		htmls = [html.DIV(line, Class="center") for line in lines]
		for h in htmls:
			self._messageDiv <= h
		self._doc <= self._messageDiv
		timer.set_timeout(self.eraseMessageBox, ms)

	def eraseMessageBox(self):
		self._messageDiv.style.display = "none"
		self._messageDiv.clear()

	def loadCardMoveSound(self):
		self._moveCardSound = self.loadSound("snap3.wav")

	def loadCardInPlaceSound(self):
		self._cardInPlaceSound = self.loadSound("inplace.wav")

	def loadEndOfRoundSound(self):
		self._endOfRoundSound = self.loadSound("lose.wav")

	def loadFanfareSound(self):
		self._fanfareSound = self.loadSound("fanfare.wav")

	def loadSound(self, file):
		sound = document.createElement("audio")
		sound.src = file
		sound.setAttribute("preload", "auto")
		sound.setAttribute("controls", "none")
		sound.style.display = "none"
		self._doc <= sound
		return sound

	def playCardMoveSound(self):
		if self._playSounds:
			self._moveCardSound.play()

	def playCardInPlaceSound(self):
		if self._playSounds:
			self._cardInPlaceSound.play()

	def playEndOfRoundSound(self):
		if self._playSounds:
			self._endOfRoundSound.play()

	def playFanfareSound(self):
		if self._playSounds:
			self._fanfareSound.play()

	def togglePlaySounds(self, ev):
		self._playSounds = ev.target.checked
		self.storePlaySoundsSetting()

	def loadHighScores(self):
		# storing up to 5 high scores.
		self._score = [0] * 5
		try:   # there may be less than 5 values stored so far.
			for i in range(5):
				self._score[i] = int(self._storage[f'highScore{i}'])
		except:
			pass
		self._scores_span = html.SPAN()
		self._game_info2_elem <= self._scores_span

		header = html.SPAN('High Scores: ')
		self._scores_span <= header

		for i in range(5):
			span = html.SPAN("{score}")
			self._score_val.append(template.Template(span))
			self._scores_span <= span
			self._score_val[i].render(score=self._score[i])

	def addScoreToHighScoresTable(self, score):
		changed = False
		for i in range(5):
			if score >= self._score[i]:
				self._score.insert(i, score)
				changed = True
				break
		if changed:
			for i in range(5):
				self._storage[f'highScore{i}'] = str(self._score[i])
				# update the screen
				self._score_val[i].render(score=self._score[i])

	def loadSettingsFromStorage(self):
		try:
			self._playSounds = self._storage['playSounds'] == "True"
		except:
			print("no playsounds in storage")
			# If we haven't stored a choice, the default is True
			self._playSounds = True

	def storePlaySoundsSetting(self):
		self._storage['playSounds'] = str(self._playSounds)
Пример #12
0
class DeckTest(unittest.TestCase):
    def setUp(self):
        self.deck = Deck()

    def test_init(self):
        """decks should have a cards attr"""
        self.assertTrue(isinstance(self.deck.cards, list))
        self.assertEqual(len(self.deck.cards), 52)

    def test_repr(self):
        """repr should return a string of the form deck"""
        self.assertEqual(repr(self.deck), "Deck of 52 cards")

    def test_count(self):
        """should return a count of the number of cards"""
        self.assertEqual(self.deck.count(), 52)
        self.deck.cards.pop()
        self.assertEqual(self.deck.count(), 51)

    def test_deal_suffic_cards(self):
        """deal should deal the number of cards specified"""
        cards = self.deck._deal(10)
        self.assertEqual(len(cards), 10)
        self.assertEqual(self.deck.count(), 42)

    def test_deal_insufficient(self):
        """_deal should deal the number of cards left in a deck"""
        cards = self.deck._deal(100)
        self.assertEqual(len(cards), 52)
        self.assertEqual(self.deck.count(), 0)

    def test_deal_no_card(self):
        """should throw a value error if the deck is empty"""
        self.deck._deal(self.deck.count())
        with self.assertRaises(ValueError):
            self.deck._deal(1)

    def test_deal_card(self):
        """should deal a single card from deck"""
        card = self.deck.cards[-1]
        dealt_card = self.deck.deal_card()
        self.assertEqual(card, dealt_card)
        self.assertEqual(self.deck.count(), 51)

    def test_deal_hand(self):
        """should deal number of cards passed into it"""
        cards = self.deck.deal_hand(20)
        self.assertEqual(len(cards), 20)
        self.assertEqual(self.deck.count(), 32)

    def test_shuffle_full_deck(self):
        """shuffle should shuffle the deck if the deck if full"""
        cards = self.deck.cards[:]
        self.deck.shuffle()
        self.assertNotEqual(cards, self.deck.cards)
        self.assertEqual(self.deck.count(), 52)

    def test_shuffle_not_full_deck(self):
        """should throw a value error if the deck isnt full"""
        self.deck._deal(1)
        with self.assertRaises(ValueError):
            self.deck.shuffle()
Пример #13
0
    # GAME START
    ask = input('Game is about to start, are you ready? y/n\n')
    if ask == 'y' or ask == 'yes' or ask == 'Yes' or ask == 'YES':
        pass
    else:
        print('Game exited')
        exit()

    # initialize chips amount
    player = chips()
    print("You have 100 chips")

    while player.amount > 0:
        new_deck = Deck()
        new_deck.shuffle()

        # First turn, place your bets
        bet = player_bet(player.amount)

        # initialize NPC and player Hand
        computer_hand = Hand()
        computer_hand.add_card(new_deck.deal())
        computer_hand.add_card(new_deck.deal())

        player_hand = Hand()
        player_hand.add_card(new_deck.deal())
        player_hand.add_card(new_deck.deal())

        print_hidden_card(player_hand, computer_hand)
Пример #14
0
class Game():
    def __init__(self,
                 gameid,
                 draw_pile=None,
                 players=[],
                 game_board=[],
                 prev_turn=[]):
        if not draw_pile:
            self.draw_pile = Deck()
            self.draw_pile.shuffle()
        else:
            self.draw_pile = draw_pile

        self.players = players
        self.game_board = game_board
        self.id = gameid
        self.prev_turn = prev_turn

    def deal_start(self):
        """
        deals the cards for the start of the game
        @return: tuple( hand:3Card deck table: 4 card Deck)
        """
        hand = Deck([])
        table = Deck([])
        for i in range(0, 3):
            hand.cards.append(self.draw_pile.draw())
        for i in range(0, 4):
            table.cards.append(self.draw_pile.draw())
        return (hand, table)

    def deal(self):
        """
        deals a card if permitted
        @return: None if there are no Cards, a Card off the top of the deck otherwise
        """
        if self.draw_pile.deck_length == 0:
            return None
        return self.draw_pile.draw()

    def join(self, player_user):
        """
        adds a player to the game
        @param: players username
        @return: False if player exists, True otherwise
        """
        if player_user in self.players:
            return False
        self.players.append(player_user)
        return True

    def burn_deck(self):
        """
        gets rid of the current game stack
        """
        self.game_board = []

    def process_turn(self, turn):
        """
        process turn for player
        @param: player_user: the username for the player
        @param: turn: the list of Cards submitted for a players turn
        @return: False if the turn couln't be processed, True otherwise
        """
        if len(turn) == 0:
            return False
        for card in turn:
            self.game_board.append(card)
        player = self.players.pop()
        self.players = [player] + self.players
        if len(self.game_board) > 3:
            if self.game_board[-1].rank == self.game_board[
                    -2].rank == self.game_board[-3].rank == self.game_board[
                        -4].rank:
                self.burn_deck()
        return True
class PokerGame:

    # Constructor
    # create instance of a poker game.
    # 2 Players, one human, one AI, 5000 chips each
    def __init__(self, num_players=2):
        self.deck = Deck()
        self.hands = []
        self.community_cards = []
        self.num_players = num_players
        self.pot = 0
        self.bet_amt = 0

    # shuffle function, just shuffles deck
    def shuffle(self):
        self.deck.shuffle()

    # reset the game state for a new hand
    def reset(self):
        self.shuffle()
        self.community_cards = []
        self.hands = []
        self.pot = 0

    # deal in 2 card to all players
    # returns a list of hands
    def dealIn(self):
        for i in range(self.num_players):
            hand = []
            hand.extend(self.deck.deal(2))
            self.hands.append(hand)

        # debug, print hands
#         print(self.getStateStr())

# flop
# deals 3 card to community card

    def flop(self):
        print("Flop!")
        self.community_cards = self.deck.deal(3)

        # debug, print table
        print(self.getStateStr())

    # turn
    # deals 1 card to community card
    def turn(self):
        print("Turn!")
        self.community_cards.extend(self.deck.deal(1))

        # debug, print table
        print(self.getStateStr())

    # river
    # deals 1 card to community card
    def river(self):
        print("River!")
        self.community_cards.extend(self.deck.deal(1))

        # debug, print table
        print(self.getStateStr())

    # assign hand types a label
    def handLabel(self, hand_type):
        if hand_type == 0:
            return "High Card"
        elif hand_type == 1:
            return "Pair"
        elif hand_type == 2:
            return "Two Pair"
        elif hand_type == 3:
            return "Three of a Kind"
        elif hand_type == 4:
            return "Straight"
        elif hand_type == 5:
            return "Flush"
        elif hand_type == 6:
            return "Full House"
        elif hand_type == 7:
            return "Four of a Kind"
        elif hand_type == 8:
            return "Straight Flush"
        else:
            return "Royal Flush"

    # get str representation of hand
    # param: hand is a list with any number of card
    # return a str displaying each card in hand
    def cards2Str(self, hand):
        text = ""
        for c in hand:
            text += str(c) + " "
        return text

    # check if hand has a pair
    # return -1 if no, value of highest pair if yes
    def hasPair(self, hand):
        self.sortHand(hand)
        print(self.cards2Str(hand))
        result = -1
        for c in hand:
            for c2 in hand:
                if c.value == c2.value and c.suit != c2.suit:
                    result = c.value
        return result

    # check if hand has 3 of a kind
    # return -1 if no, value of 3 if yes
    def has3ofKind(self, hand):
        self.sortHand(hand)
        print(self.cards2Str(hand))
        result = -1
        for c in hand:
            num = 0
            for c2 in hand:
                if c2.value == c.value:
                    num += 1
            if num >= 3:
                result = c2.value
        return result

    # sort 7 card hand by card.value
    def sortHand(self, hand):
        hand.sort(key=lambda x: x.value)

    # getStateStr()
    # function prints all values related to current game state
    # returns str representation of state
    def getStateStr(self):
        text = "=== Current Hand State ===\n"
        text += "Community Cards: " + self.cards2Str(
            self.community_cards) + "\n"
        for h in self.hands:
            text += self.cards2Str(h) + "\n"
        text += "Pot: " + str(self.pot) + "\n"
        text += "========================="
        return text

    # score()
    # scores the best 5 card hand given 7 card
    # param: hand to score
    # returns an int between 0 and 9 representing score
    def score(self, hand):
        score = 0
        kicker = []
        # Look for all hand types in hand
        # start with weakest and move up

        # check for pairs first
        pairs = {}
        prev = 0

        # remember how many pairs you have, which pairs
        for card in hand:
            if prev == card.value:
                key = card.value
                if key in pairs:
                    pairs[key] += 1
                else:
                    pairs[key] = 2
            prev = card.value

        # remember number of pairs.
        nop = {}
        for k, v in pairs.items():
            if v in nop:
                nop[v] += 1
            else:
                nop[v] = 1
        # find best possible combination
        if 4 in nop:
            score = 7
            kicker = list(pairs)
            kicker = [key for key in kicker if pairs[key] == 4]
            key = kicker[0]
            #Gets a list of all the card remaining once the the 4 of a kind is removed
            temp = [card.value for card in hand if card.value != key]
            #Get the final card in the list which is the highest card left, used in
            #case of a tie
            card_value = temp.pop()
            kicker.append(card_value)

            return [score, kicker]

        elif 3 in nop:  #Has At least 3 of A Kind
            if nop[3] == 2 or 2 in nop:  #Has two 3 of a kind, or a pair and 3 of a kind (fullhouse)
                score = 6

                #gets a list of all the pairs and reverses it
                kicker = list(pairs)
                kicker.reverse()
                temp = kicker

                #ensures the first kicker is the value of the highest 3 of a king
                kicker = [key for key in kicker if pairs[key] == 3]
                if (
                        len(kicker) > 1
                ):  # if there are two 3 of a kinds, take the higher as the first kicker
                    kicker.pop()  #removes the lower one from the kicker

                #removes the value of the kicker already in the list
                temp.remove(kicker[0])
                #Gets the highest pair or 3 of kind and adds that to the kickers list
                card_value = temp[0]
                kicker.append(card_value)

            else:  #Has Only 3 of A Kind
                score = 3

                kicker = list(pairs)  #Gets the value of the 3 of a king
                key = kicker[0]

                #Gets a list of all the card remaining once the three of a kind is removed
                temp = [card.value for card in hand if card.value != key]
                #Get the 2 last card in the list which are the 2 highest to be used in the
                #event of a tie
                card_value = temp.pop()
                kicker.append(card_value)

                card_value = temp.pop()
                kicker.append(card_value)

        elif 2 in nop:  #Has at Least a Pair
            if nop[2] >= 2:  #Has at least 2  or 3 pairs
                score = 2

                kicker = list(pairs)  #Gets the card value of all the pairs
                kicker.reverse()  #reverses the key so highest pairs are used

                if (len(kicker) == 3
                    ):  #if the user has 3 pairs takes only the highest 2
                    kicker.pop()

                key1 = kicker[0]
                key2 = kicker[1]

                #Gets a list of all the card remaining once the the 2 pairs are removed
                temp = [
                    card.value for card in hand
                    if card.value != key1 and card.value != key2
                ]
                #Gets the last card in the list which is the highest remaining card to be used in
                #the event of a tie
                if len(temp) != 0:
                    card_value = temp.pop()
                else:
                    card_value = 0
                kicker.append(card_value)

            else:  #Has only a pair
                score = 1

                kicker = list(pairs)  #Gets the value of the pair
                key = kicker[0]

                #Gets a list of all the card remaining once pair are removed
                temp = [card.value for card in hand if card.value != key]
                #Gets the last 3 card in the list which are the highest remaining card
                #which will be used in the event of a tie
                card_value = temp.pop()
                kicker.append(card_value)

                card_value = temp.pop()
                kicker.append(card_value)

                card_value = temp.pop()
                kicker.append(card_value)

        # Straight???
        #Doesn't check for the ace low straight
        counter = 0
        high = 0
        straight = False

        #Checks to see if the hand contains an ace, and if so starts checking for the straight
        #using an ace low
        if (hand[6].value == 14):
            prev = 1
        else:
            prev = None

            #Loops through the hand checking for the straight by comparing the current card to the
            #the previous one and tabulates the number of card found in a row
            #***It ignores pairs by skipping over card that are similar to the previous one
        for card in hand:
            if prev and card.value == (prev + 1):
                counter += 1
                if counter == 4:  #A straight has been recognized
                    straight = True
                    high = card.value
            elif prev and prev == card.value:  #ignores pairs when checking for the straight
                pass
            else:
                counter = 0
            prev = card.value

        #If a straight has been realized and the hand has a lower score than a straight
        if (straight or counter >= 4) and score < 4:
            straight = True
            score = 4
            kicker = [
                high
            ]  #Records the highest card value in the straight in the event of a tie

        # Flush???
        flush = False
        total = {}

        #Loops through the hand calculating the number of card of each symbol.
        #The symbol value is the key and for every occurrence the counter is incremented
        for card in hand:
            key = card.suit
            if key in total:
                total[key] += 1
            else:
                total[key] = 1

        #key represents the suit of a flush if it is within the hand
        key = -1
        for k, v in total.items():
            if v >= 5:
                key = int(k)

        #If a flush has been realized and the hand has a lower score than a flush
        if key != -1 and score < 5:
            flush = True
            score = 5
            kicker = [card.value for card in hand if card.suit == key]

        #Straight/Royal Flush???
        if flush and straight:

            #Doesn't check for the ace low straight
            counter = 0
            high = 0
            straight_flush = False

            #Checks to see if the hand contains an ace, and if so starts checking for the straight
            #using an ace low
            if (kicker[len(kicker) - 1] == 14):
                prev = 1
            else:
                prev = None

            #Loops through the hand checking for the straight by comparing the current card to the
            #the previous one and tabulates the number of card found in a row
            #***It ignores pairs by skipping over card that are similar to the previous one
            for card in kicker:
                if prev and card == (prev + 1):
                    counter += 1
                    if counter >= 4:  #A straight has been recognized
                        straight_flush = True
                        high = card
                elif prev and prev == card:  #ignores pairs when checking for the straight
                    pass
                else:
                    counter = 0
                prev = card

            #If a straight has been realized and the hand has a lower score than a straight
            if straight_flush:
                if high == 14:
                    score = 9
                else:
                    score = 8
                kicker = [high]
                return [score, kicker]

        if flush:  #if there is only a flush then determines the kickers
            kicker.reverse()

            #This ensures only the top 5 kickers are selected and not more.
            length = len(kicker) - 5
            for i in range(0, length):
                kicker.pop(
                )  #Pops the last card of the list which is the lowest

        # High Card
        if score == 0:  #If the score is 0 then high card is the best possible hand

            #It will keep track of only the card's value
            kicker = [int(card.value) for card in hand]
            #Reverses the list for easy comparison in the event of a tie
            kicker.reverse()
            #Since the hand is sorted it will pop the two lowest card position 0, 1 of the list
            kicker.pop()
            kicker.pop()
            #The reason we reverse then pop is because lists are inefficient at popping from
            #the beginning of the list, but fast at popping from the end therefore we reverse
            #the list and then pop the last two elements which will be the two lowest card
            #in the hand

        #Return the score, and the kicker to be used in the event of a tie
        return [score, kicker]

    # getWinner()
    # this function calculates the winner of the
    # hand given the current game state.
    # returns the index of the winning player


#     def getWinner(self):

    def scoreHand(self, community_cards, hands):
        for hand in hands:
            hand.extend(community_cards)
            # sort hands
            #             hand.sort(key=lambda x: x.value)
            self.sortHand(hand)

        results = []
        for hand in hands:
            overall = self.score(hand)
            results.append([overall[0], overall[1]])  # store results

        return results

    #determine winner of round
    def findWinner(self, results):
        # show hands TODO: update printing hands with best hand label
        print("Finding Winner...")
        for i in range(len(results)):
            text = ""
            text += self.cards2Str(self.hands[i]) + " " + self.handLabel(
                results[i][0])
            print(text)
        # highest score if found
        high = 0
        for r in results:
            if r[0] > high:
                high = r[0]

            # print(r)

        kicker = {}
        counter = 0
        # kickers only compared if hands are tied (haha, hands are tied)
        for r in results:
            if r[0] == high:
                kicker[counter] = r[1]

            counter += 1

        # if kickers of multiple players are here, there is a tie
        if (len(kicker) > 1):
            print("Tie. Kickers:")
            for k, v in kicker.items():
                print(str(k) + " : " + str(v))
            num_kickers = len(kicker[list(kicker).pop()])
            for i in range(0, num_kickers):
                high = 0
                for k, v in kicker.items():
                    if v[i] > high:
                        high = v[i]

                # only hands with highest kicker matching compared
                kicker = {k: v for k, v in kicker.items() if v[i] == high}
                print("---Round " + str(i) + " ---")
                for k in kicker:
                    print(k)

                # if only one kicker remains they win
                if (len(kicker) <= 1):
                    return list(kicker).pop()

        else:  # one winner found, no kickers needed
            return list(kicker).pop()

        # tie, return list of winners
        return list(kicker)
Пример #16
0
class DeckTestCase(unittest.TestCase):
    def setUp(self):
        self.full_deck = Deck()
        self.empty_deck = Deck()

        while len(self.empty_deck.get_cards()) > 0:
            self.empty_deck.remove_random_card()

    @staticmethod
    def generate_full_deck():
        cards = []
        for val in range(2, 15):
            for suit in ["Hearts", "Diamonds", "Spades", "Clubs"]:
                cards.append((val, suit))

        return cards

    @staticmethod
    def sort_by_suit(cards):
        cards.sort(key=lambda card: (card[1], card[0]))

    @staticmethod
    def equal_cards(cards1, cards2, after_sort=True):
        if len(cards1) != len(cards2):
            return False

        if after_sort:
            DeckTestCase.sort_by_suit(cards1)
            DeckTestCase.sort_by_suit(cards2)

        for i, card in enumerate(cards1):
            if card[0] != cards2[i][0] or card[1] != cards2[i][1]:
                return False

        return True

    def test_initializer(self):
        deck = Deck()
        self.assertEqual(52, len(deck.get_cards()))

    def test_print_cards(self):
        cards = DeckTestCase.generate_full_deck()

        _, output = StdoutCapture(
            lambda: self.full_deck.print_cards()).capture()

        self.assertTrue(str(52) in output)
        self.assertTrue(str(cards) in output)

    def test_get_cards(self):
        all_cards = DeckTestCase.generate_full_deck()
        cards = self.full_deck.get_cards()

        self.assertTrue(DeckTestCase.equal_cards(all_cards, cards))

    def test_shuffle(self):
        old_cards = self.full_deck.get_cards().copy()
        self.full_deck.shuffle()

        new_cards = self.full_deck.get_cards()
        self.assertFalse(
            DeckTestCase.equal_cards(old_cards, new_cards, after_sort=False))

    def test_remove_random_card_exists(self):
        cards = self.full_deck.get_cards().copy()
        card = self.full_deck.remove_random_card()

        self.assertTrue(card in cards)
        self.assertFalse(card in self.full_deck.get_cards())

    def test_remove_random_card_nonexistent(self):
        card, output = StdoutCapture(
            lambda: self.empty_deck.remove_random_card()).capture()

        self.assertEqual(card, None)
        self.assertEqual("Deck is empty", output.strip())

    def test_remove_top_card_exists(self):
        cards = self.full_deck.get_cards().copy()
        card = self.full_deck.remove_top_card()

        self.assertEqual(card, cards[0])
        self.assertFalse(card in self.full_deck.get_cards())

    def test_remove_top_card_nonexistent(self):
        card, output = StdoutCapture(
            lambda: self.empty_deck.remove_top_card()).capture()

        self.assertEqual(card, None)
        self.assertEqual("Deck is empty", output.strip())

    def test_remove_card_exists(self):
        target_card = (2, "Spades")
        self.assertTrue(target_card in self.full_deck.get_cards())

        self.full_deck.remove_card(target_card)
        self.assertFalse(target_card in self.full_deck.get_cards())

    def test_remove_card_nonexistent(self):
        card, output = StdoutCapture(lambda: self.empty_deck.remove_card(
            (2, "Spades"))).capture()

        self.assertEqual(card, None)
        self.assertEqual("Deck is empty", output.strip())

    def test_deal(self):
        player1 = Player("p1")
        player2 = Player("p2")

        self.assertEqual(52, len(self.full_deck.get_cards()))
        self.assertEqual(0, len(player1.get_cards()))
        self.assertEqual(0, len(player2.get_cards()))

        self.full_deck.deal([player1, player2], 2)

        self.assertEqual(48, len(self.full_deck.get_cards()))
        self.assertEqual(2, len(player1.get_cards()))
        self.assertEqual(2, len(player2.get_cards()))

    def test_collect(self):
        player1 = Player("p1")
        player2 = Player("p2")

        player1_cards = [(2, "Spades"), (2, "Hearts")]
        player2_cards = [(4, "Hearts")]

        for card in player1_cards:
            player1.add_card(card)

        for card in player2_cards:
            player2.add_card(card)

        self.assertEqual(0, len(self.empty_deck.get_cards()))
        self.assertEqual(2, len(player1.get_cards()))
        self.assertEqual(1, len(player2.get_cards()))

        self.empty_deck.collect([player1, player2])

        self.assertEqual(3, len(self.empty_deck.get_cards()))

        for card in player1_cards:
            self.assertTrue(card in self.empty_deck.get_cards())

        for card in player2_cards:
            self.assertTrue(card in self.empty_deck.get_cards())

    def test_have_all_cards(self):
        full_deck = Deck()

        self.assertTrue(full_deck.have_all_cards())
        full_deck.remove_random_card()
        self.assertFalse(full_deck.have_all_cards())

    def test_push_to_table(self):
        table = Table()

        self.assertEqual(0, len(table.get_cards()))
        self.assertEqual(52, len(self.full_deck.get_cards()))

        self.full_deck.push_to_table(table, 3)

        self.assertEqual(3, len(table.get_cards()))
        self.assertEqual(49, len(self.full_deck.get_cards()))

    def test_print(self):
        _, output = StdoutCapture(lambda: print(self.empty_deck)).capture()
        self.assertEqual("Deck of cards", output.strip())
class Round:
    def __init__(self, player1, player2, player3, player4):
        self.cpu1 = player1
        self.cpu2 = player2
        self.cpu3 = player3
        self.cpu4 = player4

        self.deck = Deck()
        self.deck.shuffle()

        self.games = BIDDINGS
        self.game_to_be_played = 'Pass'

        self.cpu1.coplayer = self.cpu3
        self.cpu2.coplayer = self.cpu4
        self.cpu3.coplayer = self.cpu1
        self.cpu4.coplayer = self.cpu2

        self.team1 = p.Team(self.cpu1, self.cpu3)
        self.team2 = p.Team(self.cpu2, self.cpu4)

        self.single_hand = [self.cpu1, self.cpu2, self.cpu3, self.cpu4]

    def valid_games(self, called):
        if called == 'Pass' or called not in self.games:
            pass
        else:
            i = self.games.index(called)
            self.games = self.games[:i]

    def set_pregame(self):
        self.cpu1.add_cards(self.deck[0:5])
        self.cpu2.add_cards(self.deck[5:10])
        self.cpu3.add_cards(self.deck[10:15])
        self.cpu4.add_cards(self.deck[15:20])
        self.deck.remove(self.deck[0:20])

    def pregame(self):
        self.set_pregame()

        c1 = self.cpu1.pregame(self.games)
        c2 = self.cpu2.pregame(self.games)
        c3 = self.cpu3.pregame(self.games)
        c4 = self.cpu4.pregame(self.games)

        if all([c == 'Pass' for c in [c1, c2, c3, c4]]):
            self.game_to_be_played = 'Pass'

        else:
            BREAKER = -1
            while True:
                c1 = self.cpu1.pregame(self.games)
                self.valid_games(c1)
                if c1 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c2
                    break

                c2 = self.cpu2.pregame(self.games)
                self.valid_games(c2)
                if c2 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c3
                    break
                c3 = self.cpu3.pregame(self.games)
                self.valid_games(c3)
                if c3 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c4
                    break
                c4 = self.cpu4.pregame(self.games)
                self.valid_games(c4)
                if c4 == 'Pass':
                    BREAKER += 1
                else:
                    BREAKER = 0
                if BREAKER == 3:
                    self.game_to_be_played = c1
                    break

    def set_rest_of_cards(self):
        self.cpu1.add_cards(self.deck[0:3])
        self.cpu2.add_cards(self.deck[3:6])
        self.cpu3.add_cards(self.deck[6:9])
        self.cpu4.add_cards(self.deck[9:12])
        self.deck.remove(self.deck[0:12])

    def reorder(self, index):
        self.single_hand = self.single_hand[index:] + self.single_hand[:index]

    def take_cards(self):
        curr_type = p.ALL_GIVEN_CARDS_ON_TABLE[0].type
        if self.game_to_be_played == 'All Trumps':
            arr = []
            for c in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                if c.type == curr_type:
                    arr.append(c)
            if len(arr) == 0:
                return 0
            else:
                res = [all_trumps_dic[c.value] for c in arr]
                max_value = max(res)
                if max_value < all_trumps_dic[p.ALL_GIVEN_CARDS_ON_TABLE[0].value]:
                    return 0
                else:
                    for i in range(len(arr)):
                        if all_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])

        elif self.game_to_be_played == 'No Trumps':
            arr = []
            for c in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                if c.type == curr_type:
                    arr.append(c)
            if len(arr) == 0:
                return 0
            else:
                res = [no_trumps_dic[c.value] for c in arr]
                max_value = max(res)
                if max_value < no_trumps_dic[p.ALL_GIVEN_CARDS_ON_TABLE[0].value]:
                    return 0
                else:
                    for i in range(len(arr)):
                        if no_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])
        else:
            arr = []
            curr_type = self.game_to_be_played
            if p.ALL_GIVEN_CARDS_ON_TABLE[0].type == curr_type:
                for card in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                    if card.type == curr_type and all_trumps_dic[card.value] > all_trumps_dic[p.ALL_GIVEN_CARDS_ON_TABLE[0].value]:
                        arr.append(card)
                if len(arr) == 0:
                    return 0
                else:
                    result = [all_trumps_dic[c.value] for c in arr]
                    max_value = max(result)
                    for i in range(len(arr)):
                        if all_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])
            elif p.ALL_GIVEN_CARDS_ON_TABLE[0].type != curr_type:
                for card in p.ALL_GIVEN_CARDS_ON_TABLE[1:]:
                    if card.type == curr_type:
                        arr.append(card)
                if len(arr) != 0:
                    result = [all_trumps_dic[c.value] for c in arr]
                    max_value = max(result)
                    for i in range(len(arr)):
                        if all_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])
                else:
                    result = [no_trumps_dic[c.value] for c in p.ALL_GIVEN_CARDS_ON_TABLE]
                    max_value = max(result)
                    for i in range(len(arr)):
                        if no_trumps_dic[arr[i].value] == max_value:
                            return p.ALL_GIVEN_CARDS_ON_TABLE.index(arr[i])




    def game_on(self):
        self.pregame()
        print(self.game_to_be_played)
        self.set_rest_of_cards()

        print([str(x) for x in self.cpu1.cards])
        print([str(x) for x in self.cpu2.cards])
        print([str(x) for x in self.cpu3.cards])
        print([str(x) for x in self.cpu4.cards])

        cur_res1 = 0
        cur_res2 = 0
        while len(p.ALL_GIVEN_CARDS) < 32:
            if len(p.ALL_GIVEN_CARDS_ON_TABLE) == 0:
                if self.game_to_be_played == 'All Trumps':
                    print(self.single_hand[0].name)
                    self.single_hand[0].throw_card(
                        all_trumps_logic(self.single_hand[0], self.single_hand[2]))
                    print(self.single_hand[1].name)
                    self.single_hand[1].throw_card(
                        all_trumps_logic(self.single_hand[1], self.single_hand[3]))
                    print(self.single_hand[2].name)
                    self.single_hand[2].throw_card(
                        all_trumps_logic(self.single_hand[2], self.single_hand[0]))
                    print(self.single_hand[3].name)
                    self.single_hand[3].throw_card(
                        all_trumps_logic(self.single_hand[3], self.single_hand[1]))
                    print("\n")

                elif self.game_to_be_played == 'No Trumps':
                    print(self.single_hand[0].name)
                    self.single_hand[0].throw_card(
                        no_trumps_logic(self.single_hand[0], self.single_hand[2]))
                    print(self.single_hand[1].name)
                    self.single_hand[1].throw_card(
                        no_trumps_logic(self.single_hand[1], self.single_hand[3]))
                    print(self.single_hand[2].name)
                    self.single_hand[2].throw_card(
                        no_trumps_logic(self.single_hand[2], self.single_hand[0]))
                    print(self.single_hand[3].name)
                    self.single_hand[3].throw_card(
                        no_trumps_logic(self.single_hand[3], self.single_hand[1]))
                    print("\n")

                elif self.game_to_be_played in CARD_TYPES:
                    self.single_hand[0].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[0], self.single_hand[2]))
                    print(game_type_logic(self.game_to_be_played, self.single_hand[0], self.single_hand[2]))
                    self.single_hand[1].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[1], self.single_hand[3]))
                    print(game_type_logic(self.game_to_be_played, self.single_hand[1], self.single_hand[3]))
                    self.single_hand[2].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[2], self.single_hand[0]))
                    print('---------------------')
                    print(game_type_logic(self.game_to_be_played, self.single_hand[2], self.single_hand[0]))
                    self.single_hand[3].throw_card(
                        game_type_logic(self.game_to_be_played, self.single_hand[3], self.single_hand[1]))
                    print(game_type_logic(self.game_to_be_played, self.single_hand[3], self.single_hand[1]))

                else:
                    break

            winner = self.take_cards()
            if winner == 0 or winner == 2:
                self.team1.take_hand(p.ALL_GIVEN_CARDS_ON_TABLE)
                self.reorder(winner)
                cur_res1 += self.team1.cards_to_points(self.game_to_be_played)

                del p.ALL_GIVEN_CARDS_ON_TABLE[:]
            else:
                self.team2.take_hand(p.ALL_GIVEN_CARDS_ON_TABLE)
                self.reorder(winner)
                cur_res2 += self.team2.cards_to_points(self.game_to_be_played)

                del p.ALL_GIVEN_CARDS_ON_TABLE[:]
            sleep(2)
Пример #18
0
class Round:

    LOGGER = logging.getLogger(name="Round")

    def __init__(self, seats, small_blind, min_denomination):
        self.LOGGER.debug("NEW ROUND")
        self.seats = seats
        self.small_blind = small_blind
        self.min_denomination = min_denomination
        self.cards = []

    def play(self):
        self.shuffle_and_deal()
        self.put_in_blinds()
        starting_bet = self.small_blind * 2
        remaining_seats = self.seats

        first_betting_round = PreFlop(self.seats, remaining_seats, self.cards,
                                      starting_bet)
        remaining_seats = first_betting_round.play()

        if len(remaining_seats) == 1:
            self.distribute_winnings(remaining_seats)
            return self.get_seat_statuses()

        self.deal_flop()
        self.LOGGER.debug("Flop  {}".format(" ".join(
            str(card) for card in self.cards)))

        if self.players_can_bet(remaining_seats):
            second_betting_round = BettingRound(self.seats, remaining_seats,
                                                self.cards)
            remaining_seats = second_betting_round.play()

        if len(remaining_seats) == 1:
            self.distribute_winnings(remaining_seats)
            return self.get_seat_statuses()

        self.deal_turn()
        self.LOGGER.debug("Turn  {}".format(" ".join(
            str(card) for card in self.cards)))

        if self.players_can_bet(remaining_seats):
            third_betting_round = BettingRound(self.seats, remaining_seats,
                                               self.cards)
            remaining_seats = third_betting_round.play()

        if len(remaining_seats) == 1:
            self.distribute_winnings(remaining_seats)
            return self.get_seat_statuses()

        self.deal_river()
        self.LOGGER.debug("River {}".format(" ".join(
            str(card) for card in self.cards)))

        if self.players_can_bet(remaining_seats):
            final_betting_round = BettingRound(self.seats, remaining_seats,
                                               self.cards)
            remaining_seats = final_betting_round.play()

        if len(remaining_seats) == 1:
            self.distribute_winnings(remaining_seats)
            return self.get_seat_statuses()

        winners = self.winners_from_remaining(remaining_seats)

        winner_string = ", ".join(str(winner.index) for winner in winners)
        self.LOGGER.debug("Winning player(s): {}".format(winner_string))

        self.distribute_winnings(winners)

        return self.get_seat_statuses()

    def players_can_bet(self, remaining_seats):
        can_bet = sum(1 for seat in remaining_seats if seat.chips > 0)
        return can_bet > 1

    def get_seat_statuses(self):
        still_in = deque(seat for seat in self.seats if seat.chips > 0)
        gone_out = [seat for seat in self.seats if seat.chips == 0]

        return still_in, gone_out

    def shuffle_and_deal(self):
        self.deck = Deck()
        self.deck.shuffle()

        for seat in self.seats:
            seat.set_card_1(self.deck.deal())

        for seat in self.seats:
            seat.set_card_2(self.deck.deal())

    def put_in_blinds(self):
        small_blind = self.small_blind
        big_blind = self.small_blind * 2

        self.seats[1].bet_chips(small_blind)
        self.seats[2 % len(self.seats)].bet_chips(big_blind)

    def deal_flop(self):
        # burn card
        self.deck.deal()

        # deal three cards as the flop
        for _ in range(3):
            self.cards.append(self.deck.deal())

    def deal_turn(self):
        # burn card
        self.deck.deal()

        # deal turn
        self.cards.append(self.deck.deal())

    def deal_river(self):
        # burn card
        self.deck.deal()

        # deal turn
        self.cards.append(self.deck.deal())

    def winners_from_remaining(self, remaining_seats):
        hands = []

        for seat in remaining_seats:
            hand = get_best_hand(seat.get_cards(), self.cards)
            hands.append((seat, hand))

        best_hand = max(hands, key=lambda seat_hand_pair: seat_hand_pair[1])
        return [
            seat_hand_pair[0] for seat_hand_pair in hands
            if seat_hand_pair[1] == best_hand[1]
        ]

    def distribute_winnings(self, winners):
        winners.sort(key=lambda seat: seat.pot)
        winners_by_deal_order = [
            seat for seat in self.seats if seat in winners
        ]

        while len(winners) > 0:
            winner = winners[0]
            winnings = 0
            winnings_cap = winner.pot

            # create a side pot
            for seat in self.seats:
                winnings += seat.get_chips_from_pot(winnings_cap)

            # split that side pot
            normalized_winnings = winnings // self.min_denomination
            quotient = (normalized_winnings // len(winners)) * \
                self.min_denomination
            remainders = normalized_winnings % len(winners)

            for winner in winners:
                winner.take_winnings(quotient)

            for index in range(remainders):
                winners_by_deal_order[index].take_winnings(
                    self.min_denomination)

            del winners[0]

        for seat in self.seats:
            seat.reclaim_remaining_pot()