import random import Ledger def convertNumberToCard(cardNumber): # Cards index from 0 i.e ace is 0, and the highest card value is 51 if cardNumber <= 12: cardSuit = "♣" elif cardNumber <= 25: cardSuit = "♦" elif cardNumber <= 38: cardSuit = "♥" elif cardNumber <= 51: cardSuit = "♠" cardNumber = cardNumber % 13 if cardNumber == 0: cardNumber = "A" elif cardNumber == 10: cardNumber = "J" elif cardNumber == 11: cardNumber = "Q" elif cardNumber == 12: cardNumber = "K" else: cardNumber += 1 return "{value}{suit} ".format(value=str(cardNumber), suit=cardSuit) def generateDeck(): return [x for x in range(0, 51)] def addCardToHand(hand, deck): card = deck.pop(0) hand.append(card) def generateHand(hand, deck, handSize = 2): i = 0 while i < handSize: addCardToHand(hand, deck) i += 1 def handNumbersToCards(hand): cards = "" for card in hand: cards += convertNumberToCard(card) return cards def getHandTotal(hand): cardValue = lambda c: min(c % 13 + 1, 10) i = 0 for card in hand: card = cardValue(card) if (card == 1) and (i < 20): card = 11 if (i + card) > 21: card = 1 i += card return i def showDeck(deck): string = "" for card in deck: string += convertNumberToCard(card) return string class BlackJack: def __init__(self): self.playerTurn = True self.deck = generateDeck() random.shuffle(self.deck) self.discard = [] self.playerHand = [] self.dealerHand = [] self.ledger = Ledger.Ledger() def getPH(self): return self.playerHand def getDH(self): return self.dealerHand def returnCards(self): self.discard.extend(self.playerHand) self.playerHand.clear() self.discard.extend(self.dealerHand) self.dealerHand.clear() def deal(self): generateHand(self.playerHand, self.deck) generateHand(self.dealerHand, self.deck) def shuffle(self): self.deck.extend(self.discard) self.discard.clear() random.shuffle(self.deck) def stand(self): if self.playerTurn: self.playerTurn = False def hit(self): if self.playerTurn: addCardToHand(self.playerHand, self.deck) self.playerTurn = False else: addCardToHand(self.dealerHand, self.deck) self.playerTurn = True def checkHandState(self, hand): # Check the hand state and return w if game is won, l if lost and c for continue total = getHandTotal(hand) if total == 21: return "w" elif total > 21: return "l" else: return "c" def dealerHitLogic(self, hand): total = getHandTotal() if total > 17: self.stand() elif total <= 16: self.hit() def checkGameOver(self, state): gameOver = False if state == "w": gameOver = True elif state == "l": gameOver = True return gameOver async def play_game(self, ID, bet, recv, send): gameOver = False playerStats = self.ledger.read(ID) if playerStats is None: self.ledger.write(ID) playerStats = self.ledger.read(ID) self.deal() while not gameOver: play = None playerStood = False validInput = False playerWinState = self.checkHandState(self.playerHand) dealerWinState = self.checkHandState(self.dealerHand) gameOver = self.checkGameOver(playerWinState) or self.checkGameOver(dealerWinState) if gameOver: continue await send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards( self.playerHand) + "\n" + "Dealers hand = ??: " + convertNumberToCard(self.dealerHand[0]) + "??") play = await recv("Hit or Stand? (h/s)") while not validInput: if play == "h": self.hit() validInput = True elif play == "s": self.stand() validInput = True playerStood = True playerWinState = self.checkHandState(self.playerHand) if self.checkGameOver(playerWinState): continue # Dealers turn if playerStood: while dealerWinState == 'c': # Dealer hits self.hit() # Player stands self.stand() # Loop ends when game is over dealerWinState = self.checkHandState(self.dealerHand) else: self.hit() dealerWinState = self.checkHandState(self.dealerHand) if self.checkGameOver(dealerWinState): continue await send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards(self.playerHand) + "\n" + "Dealers hand = " + str(getHandTotal(self.dealerHand)) + ": " + handNumbersToCards(self.dealerHand)) if playerWinState == "w": await send("You won!") win = (2*bet, 1, 0, ID) self.ledger.update(ID, win) elif playerWinState == "l": await send("You busted!") loss = (-bet, 0, 1, ID) self.ledger.update(ID, loss) elif dealerWinState == "w": await send("The Dealer reached 21 before you!") loss = (-bet, 0, 1, ID) self.ledger.update(ID, loss) elif dealerWinState == "l": await send("The Dealer busted before you!") win = (2*bet, 1, 0, ID) self.ledger.update(ID, win) self.returnCards() if len(self.deck) < 0.25 * 52: await send("Shuffling Deck") self.shuffle()