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)
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)
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()
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")
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"] = ""
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())
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
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())
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()
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.' )
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)
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()
# 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)
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)
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)
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()