# from common.inputChecking.choiceInput import choiceInput from os import get_terminal_size, system from math import ceil import random class Card: def __init__(self, cardId, color): """ cardId goes from 1 to 1 where 1 is A and 13 is K """ self.id = cardId self.color = color cardNums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] cardSyms = { 'spade': '♠', 'heart': '♥', 'diamond': '♦', 'club': '♣' } self.num = cardNums[cardId-1] self.sym = cardSyms[color] WIDTH = 11 def __str__(self): return f"""┌─────────┐ │{self.num}{' ' if self.id != 10 else ''} │ │ │ │ │ │ {self.sym} │ │ │ │ │ │ {' ' if self.id != 10 else ''}{self.num}│ └─────────┘""" def emptyCard(): result = Card(1,'spade') result.num = '?' result.sym = '?' return result class CardHandler: def __init__(self, cards, printSep=5, aceValue = 1): self.cards = cards self.printSeparator = printSep self.aceValue = aceValue def addCard(self, card): self.cards.append(card) def _concatenateCards(self, cards): """ Concatenate several card objects into an list of sublists where each sublist contains the strings for the cards to be printed for a specific horizontal line. """ cardStringLists = [(str(card)).split('\n') for card in cards] cardHeight = len(cardStringLists[0]) linesToPrint = [[] for line in range(cardHeight)] for cardStringList in cardStringLists: [linesToPrint[line].append(cardStringList[line]) for line in range(cardHeight)] return linesToPrint def printCards(self, cardsPerLine): """ Print cardsPerLine cards per line, horizontally aligned """ splitCards =[[] for _ in range(ceil(len(self.cards)/cardsPerLine))] for i, card in enumerate(self.cards): splitCards[i // cardsPerLine].append(card) SplitCardStrings = [self._concatenateCards(cardList) for cardList in splitCards] printCardList = lambda cardList: print('\n'.join([ (' ' * self.printSeparator).join(line) for line in cardList ])) [ printCardList(SplitCardString) for SplitCardString in SplitCardStrings ] def safePrintCards(self): """ Print the amount of cards that there is room for depending on the terminal width """ cardWidth = Card.WIDTH extendedCardWidth = (cardWidth + self.printSeparator) terminalWidth = get_terminal_size().columns isRoomForExtraCard = terminalWidth % extendedCardWidth >= cardWidth cardsPerLine = terminalWidth // extendedCardWidth + (1 if isRoomForExtraCard else 0) self.printCards(cardsPerLine) @property def cardSum(self): values = { 'A': self.aceValue, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'J': 10, 'Q': 10, 'K': 10 } return sum([values[card.num] for card in self.cards]) def animator(self): while True: frame = 1 yield frame # # ┌─────────┐ # │? │ # │ │ # │ │ # │ ? │ # │ │ # │ │ # │ ?│ # └─────────┘ # # # ┌────────┐ # │? │ # │ │ # │ │ # │ ? │ # │ │ # │ │ # │ ?│ # └────────┘ # # # ┌───────┐ # │? │ # │ │ # │ │ # │ ? │ # │ │ # │ │ # │ ?│ # └───────┘ # class Blackjack: def __init__(self): self.handler = CardHandler([]) self.emptyHandler = CardHandler([emptyCard(), emptyCard()]) self.dealerHandler = CardHandler([]) self.reset() def generateNewCard(self): cardTypes = range(1,14) cardColors = ['spade', 'heart', 'diamond', 'club'] return Card(random.choice(cardTypes), random.choice(cardColors)) def generateNewCards(self): self.dealerHandler.cards = [ self.generateNewCard() for _ in range(2) ] self.handler.cards = [ self.generateNewCard() for _ in range(2) ] def determineAceValue(self): if self.dealerHandler.cardSum <= 9: self.handler.aceValue = 13 def reset(self): self.generateNewCards() self.determineAceValue() def printCards(self): self.handler.safePrintCards() def update(self): system('clear') print('\nDEALERS CARDS\n') self.emptyHandler.safePrintCards() print('\nYOUR CARDS\n') self.handler.safePrintCards() print() input('Continue?') self.handler.addCard(self.generateNewCard()) def loop(self): while True: self.update() if __name__ == "__main__": game = Blackjack() game.loop()