From 50251c3f1d685e76fd1fdacfd232bced58058285 Mon Sep 17 00:00:00 2001 From: BigGamerGary Date: Wed, 5 Jul 2023 09:40:01 +1000 Subject: [PATCH] Started working on rewriting blackjack --- BlackJack.py | 53 ++--- BlackJack2.py | 89 +++++++++ BlackJackTest.py | 271 ++++++++++++++++++++++++++ Calculator.py | 2 +- __pycache__/BlackJack.cpython-310.pyc | Bin 6101 -> 5929 bytes ledger.db | Bin 8192 -> 8192 bytes 6 files changed, 389 insertions(+), 26 deletions(-) create mode 100644 BlackJack2.py create mode 100644 BlackJackTest.py diff --git a/BlackJack.py b/BlackJack.py index 99f4bd1..e2bc738 100644 --- a/BlackJack.py +++ b/BlackJack.py @@ -84,7 +84,7 @@ def showDeck(deck): class BlackJack: def __init__(self): - self.gameState = INIT + self.gameInSession = False self.playerTurn = True self.deck = generateDeck() random.shuffle(self.deck) @@ -93,12 +93,6 @@ class BlackJack: 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() @@ -164,30 +158,38 @@ class BlackJack: async def play_game(self, ID, bet, recv, send): - self.gameState = INIT + if self.gameInSession: + await send("Fuck you") + return + else: + self.gameInSession = True + gameState = INIT - while self.gameState != OVER: + while gameState != OVER: - if self.gameState == INIT: + if gameState == INIT: + self.returnCards() playerStats = self.ledger.read(ID) if playerStats is None: self.ledger.write(ID) playerStats = self.ledger.read(ID) self.deal() - + playerWinState = self.checkHandState(self.playerHand) + dealerWinState = self.checkHandState(self.dealerHand) + play = None - self.playerTurn = True playerStood = False dealerStood = False validInput = False - self.gameState = PLAYING + + gameState = CHECKING - elif self.gameState == PLAYING: + elif gameState == PLAYING: 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)") + play = await recv("Hit or Stand?") while not validInput: if play == "h": self.hit() @@ -197,12 +199,12 @@ class BlackJack: playerStood = True validInput = True - self.dealerHitLogic() + dealerStood = self.dealerHitLogic() playerWinState = self.checkHandState(self.playerHand) dealerWinState = self.checkHandState(self.dealerHand) - self.gameState = CHECKING + gameState = CHECKING - elif self.gameState == ENDING: + elif gameState == ENDING: # Players turn self.stand() @@ -215,18 +217,18 @@ class BlackJack: if dealerWinState == "c": dealerWinState = self.compareHands() - self.gameState = CHECKING + gameState = CHECKING - elif self.gameState == CHECKING: + elif gameState == CHECKING: if self.checkGameOver(playerWinState) or self.checkGameOver(dealerWinState): - self.gameState = FINISHED + gameState = FINISHED elif playerStood: - self.gameState = ENDING + gameState = ENDING else: - self.gameState = PLAYING + gameState = PLAYING - elif self.gameState == FINISHED: + elif gameState == FINISHED: await send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards(self.playerHand) + "\n" + "Dealers hand = " + str(getHandTotal(self.dealerHand)) + ": " + handNumbersToCards(self.dealerHand)) @@ -252,4 +254,5 @@ class BlackJack: await send("Shuffling Deck") self.shuffle() - self.gameState = OVER + gameState = OVER + self.gameInSession = False diff --git a/BlackJack2.py b/BlackJack2.py new file mode 100644 index 0000000..337c316 --- /dev/null +++ b/BlackJack2.py @@ -0,0 +1,89 @@ +import random + +""" +Class which describes playing cards +""" +class Card(): + """ + A joker card has value 0 and suit 0 + """ + HEARTS = 1 + DIAMONDS = 2 + SPADES = 3 + CLUBS = 4 + + def __init__(self, value, suit) -> None: + self.value = value + self.suit = suit + + def __str__(self) -> str: + suits = ["J", "♥", "♦", "♠", "♣"] + special_cards = {1: "A", 11: "J", 12: "Q", 13: "K"} + strValue = "" + + if self.value in special_cards.keys(): + strValue = special_cards[self.value] + else: + strValue = str(self.value) + + string = "" + string.format("%s %s", suits[self.suit], strValue) + return string + + + + +""" +Class for interacting with a deck of cards +""" +class Deck(): + def __init__(self) -> None: + self.deck = [] + self.discard = [] + self.joker = False + if self.joker: + self.deck = [x for x in range(0, 52)] + else: + self.deck = [x for x in range(0, 51)] + + def shuffle(self): + random.shuffle(self.deck) + + def take_from_deck(self): + card = self.deck.pop() + return card + + def return_to_deck_top(self, card): + self.deck.insert(0, card) + + def returnToDeckBottom(self, card): + self.deck.append(card) + + def addToDiscard(self, card): + self.discard.insert(0, card) + + def returnFromDiscard(self): + self.returnToDeckTop(self.discard.pop()) + + def __str__(self) -> str: + string = "" + for card in self.deck: + string += convertNumberToCard(card) + return string + +class Hand(): + def __init__(self) -> None: + self.hand = [] + + def sortHand(self): + self.hand.sort() + + def addToHand(self, card): + self.hand.append(card) + + def removeFromHand(self, index): + card = self.hand.remove(index) + return card + + + \ No newline at end of file diff --git a/BlackJackTest.py b/BlackJackTest.py new file mode 100644 index 0000000..2f1ba72 --- /dev/null +++ b/BlackJackTest.py @@ -0,0 +1,271 @@ +import random +import Ledger + +# Game States +INIT = 0 +PLAYING = 1 +ENDING = 2 +FINISHED = 3 +OVER = 5 +CHECKING = 6 + + + +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 + aces = 0 + for card in hand: + card = cardValue(card) + if card == 1: + aces += 1 + else: + i += card + + while aces > 0: + if i < 20: + card = 11 + if (i + card) > 21: + card = 1 + i += card + aces -= 1 + return i + +def showDeck(deck): + string = "" + for card in deck: + string += convertNumberToCard(card) + return string + +class BlackJack: + def __init__(self): + self.gameInSession = False + self.playerTurn = True + self.deck = generateDeck() + random.shuffle(self.deck) + self.discard = [] + self.playerHand = [] + self.dealerHand = [] + self.ledger = Ledger.Ledger() + + 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): + total = getHandTotal(self.dealerHand) + if total > 17: + self.stand() + return True + else: + self.hit() + + + def checkGameOver(self, state): + gameOver = False + if state == "w": + gameOver = True + elif state == "l": + gameOver = True + return gameOver + + def compareHands(self): + dealerTotal = getHandTotal(self.dealerHand) + playerTotal = getHandTotal(self.playerHand) + if dealerTotal < playerTotal: + return "l" + else: + return "w" + + def play_game(self, ID, bet, recv, send): + + if self.gameInSession: + send("Fuck you") + return + else: + self.gameInSession = True + gameState = INIT + + while gameState != OVER: + + if gameState == INIT: + + self.returnCards() + playerStats = self.ledger.read(ID) + if playerStats is None: + self.ledger.write(ID) + playerStats = self.ledger.read(ID) + self.deal() + playerWinState = self.checkHandState(self.playerHand) + dealerWinState = self.checkHandState(self.dealerHand) + + play = None + playerStood = False + dealerStood = False + validInput = False + + gameState = CHECKING + + elif gameState == PLAYING: + + send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards( + self.playerHand) + "\n" + "Dealers hand = ??: " + convertNumberToCard(self.dealerHand[0]) + "??") + play = recv("Hit or Stand?") + while not validInput: + if play == "h": + self.hit() + validInput = True + elif play == "s": + self.stand() + playerStood = True + validInput = True + + dealerStood = self.dealerHitLogic() + playerWinState = self.checkHandState(self.playerHand) + dealerWinState = self.checkHandState(self.dealerHand) + gameState = CHECKING + + elif gameState == ENDING: + + # Players turn + self.stand() + # Dealers turn + dealerStood = self.dealerHitLogic() + # Loop ends when game is over + dealerWinState = self.checkHandState(self.dealerHand) + if dealerStood: + + if dealerWinState == "c": + + dealerWinState = self.compareHands() + gameState = CHECKING + + elif gameState == CHECKING: + + if self.checkGameOver(playerWinState) or self.checkGameOver(dealerWinState): + gameState = FINISHED + elif playerStood: + gameState = ENDING + else: + gameState = PLAYING + + elif gameState == FINISHED: + + send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards(self.playerHand) + + "\n" + "Dealers hand = " + str(getHandTotal(self.dealerHand)) + ": " + handNumbersToCards(self.dealerHand)) + if playerWinState == "w": + send("You won!") + win = (2*bet, 1, 0, ID) + self.ledger.update(ID, win) + elif playerWinState == "l": + send("You busted!") + loss = (-bet, 0, 1, ID) + self.ledger.update(ID, loss) + elif dealerWinState == "w": + send("The Dealer reached 21 before you!") + loss = (-bet, 0, 1, ID) + self.ledger.update(ID, loss) + elif dealerWinState == "l": + 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: + send("Shuffling Deck") + self.shuffle() + + gameState = OVER + self.gameInSession = False + +def send(str): + return input(str) + +def main(): + + bj = BlackJack() + bj.play_game(12, 100, send, print) + + +if __name__ == "__main__": + main() + diff --git a/Calculator.py b/Calculator.py index bfabc35..37437e0 100644 --- a/Calculator.py +++ b/Calculator.py @@ -127,7 +127,7 @@ class Calculator(discord.ui.View): displayOutput = " ".join(['`', ' ' * padding, f"{self.inputTwo}", f"{funckyDict[self.expression]}", f"{self.inputOne}", "=", f"{self.output}", "`"]) return displayOutput - @discord.ui.button(label="=", style=discord.ButtonStyle.green, row=4) + @discord.ui.button(label="=", style=discord.ButtonStyle.green, row=3) async def equals(self, interaction: discord.Interaction, button: discord.ui.Button): if self.inputTwo is None: diff --git a/__pycache__/BlackJack.cpython-310.pyc b/__pycache__/BlackJack.cpython-310.pyc index 27c346363569c47b782b882ac4908b1ba6c15dc9..5591cd5c5ebc5e3c40848ff407f260104955c6d6 100644 GIT binary patch delta 1711 zcmaJ>O>7%Q6rR~#uh;uyr?DL;Eh^5TNTyNvOAE9rQU2|uxM`hMBs~<@vq=*NyP92t z64r82Brbp`45;cU_N7uJB!mP434stus1gzqLL9o{0z#ZXh$|=F8z&8=0e8gIi~K= zq6o|}`n>quT&82ITGX`Ddbe@G5A4hl^VM2UwJw(^UU)Bb#3*Yu4d<6XB zH+zJ7V$gY?zAV0TUhkd8r6oJ#pri*Ik}p^-tGVRx7WHx8q(k5Ag+F z5O(4j`lgsmH1q;8^5W~nIeJ43^gP*0fFlCqD;VCmO2{i9%NpTMpfS2d3xtt8p@5~X zRK%yvND%Rrs(PLBZLnxn;b#NVRy&XfT$GS@Xj2b#MjC`4lRh1N|B91#wACfG4M>Us zDGG(qHo-O+X~vk^G+|gUY~N}|uG3l`7PVo~_n<}1cl%-owcV}b463}VcJ@~=TF2e3V+H0_!VUR?ABczbufCPo6A zUjtvVLz>oZ^Y?888?XHiZKt5ZH+vP31^d5ClY0&Oi2R2#47I;a?n*m-5d9Ci} z6(|;A2J4kH{6D+2xTGBiJ-W+X23mT5x&LJy0#!U=?vm|#rgrzYkK z#hEZVe|l^Y44%T^qX;>K3t1h9K|(Ge@2OBJOfIRHT|d;gTX`|mJh#S{Vt9GNzI}Jex+(?2i6W8QF#+-WLGMHC>5Qjp~X7oXHd>|rzPCxdbj+P2p;Kyv7rvRY> z)G)>4eWQmpnD^Y;OpdRYE7e&T!`Q|pY^#`yi#Pfn9+sj?32{4JF{CU~QItgrftnCr k5r6azn*CrJ#Gr;L4rh)YT)@a8!V7%Q6rQ)X*SqWW=ErM0zrvIs#S~f)ZAn^al*CD$G;z`-qWrc*87Bk>HyUq* zQmt{@0OC-IiV+AQMY0b)v=;=e6eI*fAaURX5*+Y_BNCTNa6=q;Z?={N2Vht8?VE4j z`)1}n?YnX4$HVap@wmnCIq~6JeCXr&?I?Kit7y^XJ#Vn*9Nx?O@Y})rmsoZ{9yGFN zJ?69XzyVS7Lc25zdy%^Cvsc0m0Jcs{RH32J^sKtoAU4Js%4mh>SG#A( z`7}aS6Qg7oFO9@pW#Yy63ZchdK~c&9aSbtW?v)C8Rs=(ov2}z9}}4 z>mm-n-LyI07Z0Uu2kn@bpwpLs!!__+6yI;D1d&y|UEA9?#4SI@ZS=c^e6qn>3bpe0 zN+N+vKj2czw;E9SMp?M2_|{9SjlS@s;yce(_NPJW%C}Wyx};%=-u_>ii(}@3>^gU| zTWh5kiN7V$;*Js?MB$EBI-FI=p6uTR zo+>d+;hQLuZi}GXfO69)=_=LuH&iU@JgWQj6y#6cBW@zU;bks}4ECNfAI%KCe7KU8 znZzK>%9Dv6n3HD{o3%l4gnqoE2+i>P)02zhDP@Y{3U5YU6B}MpOq0hkqN5A5W6w?( zP6?N&M+uG-WC_v)CkW`T7wZ2%L)JV()0oIlPMpTrraoE7k;XF8kBB9;IEAfpDLf2i!TcyYo9oj6GgZ49w)2t&)ZoeJd+FaQw3hJm8`MLYB+;i`hzqYuz_5Cffa% zHa<_?ypZjbcajecQy&+T1a#aWPju4Y?kWp(ccHRC7gcu_Yx3t*TAoW;&H!=-!yPR= aOGt{;!9G=v=gId)f^!7V5WFDwQ{pe7LXi{z diff --git a/ledger.db b/ledger.db index 0704eba57212b255ba317d48d164f154da629cd1..552732d3f13ddb17d0e787388a54e75eb9492c3b 100644 GIT binary patch delta 87 zcmZp0XmFSy&6qY(#+fl~W5N=CE@uAI4E#6v-|(N_EGV#--;|q~je(Jgk&%aK4;z~h mBO3!7ki)n=esWX;10(+eadsglh!~S)?UWiO1_mh|Jy`&*a}o&v delta 84 zcmZp0XmFSy&1gPR#+lK4W5N=C4krE^4E#6v-)t5X*u_6FfYVTcjfsJwc6