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(): deck = [] while len(deck) < 52: newCard = random.randint(0, 51) if deck.count(newCard) == 0: deck.append(newCard) return deck 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 a in hand: cards += convertNumberToCard(a) 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 class BlackJackLedger(Ledger.Ledger): def __init__(self) -> None: super().__init__() def updateLedger(self, data, oldData): ID, money, wins, losses = oldData _, newMoney, newWins, newLosses = data wins += newWins losses += newLosses money += newMoney data = [ID, money, wins, losses] return data class BlackJack: def __init__(self, recv, send): self.playerTurn = True self.deck = generateDeck() self.playerHand = [] generateHand(self.playerHand, self.deck) self.dealerHand = [] generateHand(self.dealerHand, self.deck) self.recv = recv self.send = send self.ledger = BlackJackLedger() def getPH(self): return self.playerHand def returnCards(self): self.playerHand.clear() self.dealerHand.clear() def shuffle(self): self.returnCards() self.deck = generateDeck() generateHand(self.playerHand, self.deck) generateHand(self.dealerHand, self.deck) def getDH(self): return self.dealerHand 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): validInput = False gameOver = False playerStood = False playerStats = self.ledger.readLedger(ID) if playerStats is None: playerStats = (ID, 100, 0, 0) while not gameOver: playerWinState = self.checkHandState(self.playerHand) dealerWinState = self.checkHandState(self.dealerHand) gameOver = self.checkGameOver(playerWinState) or self.checkGameOver(dealerWinState) if gameOver: continue await self.send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards( self.playerHand) + "\n" + "Dealers hand = ??: " + convertNumberToCard(self.dealerHand[0]) + "??") play = await self.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 self.send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards(self.playerHand) + "\n" + "Dealers hand = " + str(getHandTotal(self.dealerHand)) + ": " + handNumbersToCards(self.dealerHand)) if playerWinState == "w": await self.send("You won!") win = (ID, 2*bet, 1, 0) self.ledger.writeLedger(ID, win) elif playerWinState == "l": await self.send("You busted!") loss = (ID, -bet, 0, 1) self.ledger.writeLedger(ID, loss) elif dealerWinState == "w": await self.send("The Dealer reached 21 before you!") loss = (ID, -bet, 0, 1) self.ledger.writeLedger(ID, loss) elif dealerWinState == "l": await self.send("The Dealer busted before you!") win = (ID, 2*bet, 1, 0) self.ledger.writeLedger(ID, win) await self.send(f"{ID}'s score: {self.ledger.readLedger(ID)}")