212 lines
6.0 KiB
Python
212 lines
6.0 KiB
Python
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): return [convertNumberToCard(a) for a in hand]
|
|
|
|
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):
|
|
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
|
|
|
|
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.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!")
|
|
# self.writeLedger(ID, 2*bet, True)
|
|
elif playerWinState == "l":
|
|
await self.send("You busted!")
|
|
# self.writeLedger(ID, -bet, False)
|
|
elif dealerWinState == "w":
|
|
await self.send("The Dealer reached 21 before you!")
|
|
# self.writeLedger(ID, -bet, False)
|
|
elif dealerWinState == "l":
|
|
await self.send("The Dealer busted before you!")
|
|
# self.writeLedger(ID, 2*bet, True)
|