diff --git a/Acronymbot.py b/Acronymbot.py index e21a209..d160a58 100644 --- a/Acronymbot.py +++ b/Acronymbot.py @@ -62,11 +62,11 @@ async def test(interaction:discord.Interaction): class HitOrStand(discord.ui.View): def __init__(self, *, timeout=180): super().__init__(timeout=timeout) - self.content = None + self.content = False @discord.ui.button(label="Hit", style=discord.ButtonStyle.green) async def hit(self, interaction: discord.Interaction, button: discord.ui.Button): - self.content = "h" + self.content = True for child in self.children: child.disabled = True await interaction.response.edit_message(content="You Hit!", view=self) @@ -74,7 +74,7 @@ class HitOrStand(discord.ui.View): @discord.ui.button(label="Stand", style=discord.ButtonStyle.red) async def stand(self, interaction: discord.Interaction, button: discord.ui.Button): - self.content = "s" + self.content = False for child in self.children: child.disabled = True await interaction.response.edit_message(content="You stood!", view=self) @@ -85,7 +85,8 @@ async def bj(interaction: discord.Interaction): discinput = lambda m: discordInput(interaction, m) discoutput = lambda m: discordOutput(interaction, m) await interaction.response.send_message("Let's play Black Jack!") - await blackJack.play_game(interaction.user.id, 100, discinput, discoutput) + await blackJack.play_game(discinput, discoutput) + # await blackJack.play_game(interaction.user.id, 100, discinput, discoutput) async def discordInput(interaction: discord.Interaction, message:str): response = HitOrStand() diff --git a/BlackJack.py b/BlackJack.py index ff1462c..18734f2 100644 --- a/BlackJack.py +++ b/BlackJack.py @@ -1,258 +1,215 @@ import random -import Ledger +from Ledger import Ledger # Game States INIT = 0 -PLAYING = 1 -ENDING = 2 +PLAYERTURN = 1 +DEALERTURN = 2 FINISHED = 3 OVER = 5 CHECKING = 6 +""" +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 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 = "♠" + def __init__(self, value, suit) -> None: + self.value = value + self.suit = suit + self.hidden = False - cardNumber = cardNumber % 13 + def turn_card(self): + # XOR to flip hidden element + self.hidden = self.hidden != True - 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 + def get_value(self): + return self.value - while aces > 0: - if i < 20: - card = 11 - if (i + card) > 21: - card = 1 - i += card - aces -= 1 - return i + def get_suit(self): + return self.suit -def showDeck(deck): - string = "" - for card in deck: - string += convertNumberToCard(card) - return string + def __str__(self) -> str: + suits = ["J", "♥", "♦", "♠", "♣"] + special_cards = {1: "A", 11: "J", 12: "Q", 13: "K"} + strValue = "" -class BlackJack: - def __init__(self): - self.gameInSession = False - self.playerTurn = True - self.deck = generateDeck() - random.shuffle(self.deck) + if self.value in special_cards.keys(): + strValue = special_cards[self.value] + else: + strValue = str(self.value) + + string = "" + string = f"{suits[self.suit]}{strValue}" + if self.hidden: + string = "??" + return string + + def __repr__(self) -> str: + return str(self) +""" +Class for interacting with a deck of cards +""" +class Deck(): + def __init__(self, joker = False) -> None: + self.deck = [] self.discard = [] - self.playerHand = [] - self.dealerHand = [] - self.ledger = Ledger.Ledger() + self.joker = joker - def returnCards(self): - self.discard.extend(self.playerHand) - self.playerHand.clear() - self.discard.extend(self.dealerHand) - self.dealerHand.clear() + self.deck.extend([Card(x, Card.HEARTS) for x in range(1, 13)]) + self.deck.extend([Card(x, Card.DIAMONDS) for x in range(1, 13)]) + self.deck.extend([Card(x, Card.SPADES) for x in range(1, 13)]) + self.deck.extend([Card(x, Card.CLUBS) for x in range(1, 13)]) - def deal(self): - generateHand(self.playerHand, self.deck) - generateHand(self.dealerHand, self.deck) + if joker: + self.deck.append(Card(0, 0)) 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" - - async def play_game(self, ID, bet, recv, send): - - if self.gameInSession: - await send("Fuck you") - return - else: - self.gameInSession = True - gameState = INIT + def sort(self): + self.deck.sort() + 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 += str(card) + return string + +class Hand(): + def __init__(self) -> None: + self.hand = [] + + def sortHand(self): + self.hand.sort() + + def add_to_hand(self, card): + self.hand.append(card) + + def remove_from_hand(self, index): + return self.hand.pop(index) + + def hide_card(self, index): + card = self.remove_from_hand(index) + card.turn_card() + self.add_to_hand(card) + + def __str__(self) -> str: + string = "" + for card in self.hand: + string += str(card) + string += " " + return string + + def __repr__(self) -> str: + value = 0 + for card in self.hand: + value += card.value + return str(value) + + def __iter__(self): + self.iter = iter(self.hand) + return self.iter + + def __next__(self): + return next(self.iter) + + +class BlackJack: + def __init__(self) -> None: + self.deck = Deck() + self.playerHand = Hand() + self.dealerHand = Hand() + self.ledger = Ledger() + + def deal_card(self, hand): + hand.add_to_hand(self.deck.take_from_deck()) + + def game_setup(self): + # Deal cards in alternate order + self.deck.shuffle() + for _ in range(2): + self.deal_card(self.playerHand) + self.deal_card(self.dealerHand) + + # Hide one of the dealers cards + self.dealerHand.hide_card(1) + + async def show_cards(self, send, displayDealerScore=False): + # Show Cards to player + string = f"Player Hand = {repr(self.playerHand)}: {self.playerHand}\nDealer Hand = ??: {self.dealerHand}" + if displayDealerScore: + string = f"Player Hand = {repr(self.playerHand)}: {self.playerHand}\nDealer Hand = {repr(self.dealerHand)}: {self.dealerHand}" + + await send(string) + + async def play_game(self, recv, send): + gameState = INIT + while gameState != OVER: - if gameState == INIT: + # TODO: Load player statistics + self.game_setup() + gameState = PLAYERTURN - 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) + if gameState == PLAYERTURN: - play = None - playerStood = False - dealerStood = False - validInput = False - - gameState = CHECKING - - 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?") - 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 + await self.show_cards(send) + playerHit = await recv("Hit or Stand?") + if playerHit: + self.deal_card(self.playerHand) else: - gameState = PLAYING - - elif gameState == FINISHED: - - 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() + gameState = DEALERTURN + if int(repr(self.playerHand)) >= 21: + + self.dealerHand.hide_card(1) + gameState = FINISHED + + if gameState == DEALERTURN: + + self.dealerHand.hide_card(1) + self.deal_card(self.dealerHand) + if int(repr(self.dealerHand)) >= 17: + gameState = FINISHED + + if gameState == FINISHED: + + await self.show_cards(send, True) + await send("You won or lost idk lmao") gameState = OVER - self.gameInSession = False + + +def main(): + game = BlackJack() + trueFalseInput = lambda x: input(x) == "h" + game.play_game(recv=trueFalseInput, send=print) + +if __name__ == "__main__": + main() + + diff --git a/BlackJack2.py b/BlackJack2.py deleted file mode 100644 index 62cfc6c..0000000 --- a/BlackJack2.py +++ /dev/null @@ -1,167 +0,0 @@ -import random -from Ledger import Ledger - -""" -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 - self.hidden = False - - def turn_card(self): - # XOR to flip hidden element - self.hidden = self.hidden != True - - def get_value(self): - return self.value - - def get_suit(self): - return self.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 = f"{suits[self.suit]}{strValue}" - if self.hidden: - string = "??" - return string - - def __repr__(self) -> str: - return str(self) -""" -Class for interacting with a deck of cards -""" -class Deck(): - def __init__(self, joker = False) -> None: - self.deck = [] - self.discard = [] - self.joker = joker - - self.deck.extend([Card(x, Card.HEARTS) for x in range(1, 13)]) - self.deck.extend([Card(x, Card.DIAMONDS) for x in range(1, 13)]) - self.deck.extend([Card(x, Card.SPADES) for x in range(1, 13)]) - self.deck.extend([Card(x, Card.CLUBS) for x in range(1, 13)]) - - if joker: - self.deck.append(Card(0, 0)) - - def shuffle(self): - random.shuffle(self.deck) - - def sort(self): - self.deck.sort() - - 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 += str(card) - return string - -class Hand(): - def __init__(self) -> None: - self.hand = [] - - def sortHand(self): - self.hand.sort() - - def add_to_hand(self, card): - self.hand.append(card) - - def remove_from_hand(self, index): - return self.hand.pop(index) - - def hide_card(self, index): - card = self.remove_from_hand(0) - card.turn_card() - self.add_to_hand(card) - - def __str__(self) -> str: - string = "" - for card in self.hand: - string += str(card) - string += " " - return string - - def __iter__(self): - self.iter = iter(self.hand) - return self.iter - - def __next__(self): - return next(self.iter) - - -class BlackJack: - def __init__(self) -> None: - self.deck = Deck() - self.playerHand = Hand() - self.dealerHand = Hand() - self.ledger = Ledger() - - def deal_card(self, hand): - hand.add_to_hand(self.deck.take_from_deck()) - - def game_setup(self): - # Deal cards in alternate order - self.deck.shuffle() - for _ in range(2): - self.deal_card(self.playerHand) - self.deal_card(self.dealerHand) - - # Hide one of the dealers cards - self.dealerHand.hide_card(1) - - def play_game(self): - # Load player statistics - - self.game_setup() - - # Show Cards to player - print("Player Hand:", end=" ") - print(self.playerHand) - print("Dealer Hand:", end=" ") - print(self.dealerHand) - - - -def main(): - game = BlackJack() - game.play_game() - -if __name__ == "__main__": - main() - - diff --git a/BlackJackOld.py b/BlackJackOld.py new file mode 100644 index 0000000..ff1462c --- /dev/null +++ b/BlackJackOld.py @@ -0,0 +1,258 @@ +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" + + async def play_game(self, ID, bet, recv, send): + + if self.gameInSession: + await 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: + + await send("Players hand = " + str(getHandTotal(self.playerHand)) + ": " + handNumbersToCards( + self.playerHand) + "\n" + "Dealers hand = ??: " + convertNumberToCard(self.dealerHand[0]) + "??") + play = await 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: + + 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() + + gameState = OVER + self.gameInSession = False diff --git a/__pycache__/BlackJack.cpython-310.pyc b/__pycache__/BlackJack.cpython-310.pyc index febc2c1..2f67a35 100644 Binary files a/__pycache__/BlackJack.cpython-310.pyc and b/__pycache__/BlackJack.cpython-310.pyc differ