Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Simple game of blackjack."""
- from textwrap import dedent
- import requests
- class Card:
- """Simple dataclass for holding card information."""
- def __init__(self, value: str, suit: str, code: str):
- """
- Unit.
- :param value:
- :param suit:
- :param code:
- """
- self.value = value
- self.suit = suit
- self.code = code
- def __repr__(self) -> str:
- """
- Repr.
- :return:
- """
- return self.code
- class Hand:
- """Simple class for holding hand information."""
- def __init__(self):
- """Unit."""
- self.score = 0
- self.cards = []
- self.ace_used = 0
- self.aces_in_hand = 0
- def add_card(self, card: Card):
- """
- Add card.
- :param card:
- :return:
- """
- self.score = 0
- self.cards.append(card)
- for card in self.cards:
- if card.value == "ACE":
- self.score += 11
- self.aces_in_hand += 1
- elif len(card.value) < 3:
- self.score += int(card.value)
- elif card.value == "JACK":
- self.score += 10
- elif card.value == "QUEEN":
- self.score += 10
- elif card.value == "KING":
- self.score += 10
- while self.score > 21 and self.ace_used < self.aces_in_hand:
- self.score -= 10
- self.ace_used += 1
- class Deck:
- """Deck of cards. Provided via api over the network."""
- def __init__(self, shuffle=False):
- """
- Tell api to create a new deck.
- :param shuffle: if shuffle option is true, make new shuffled deck.
- """
- self.is_shuffled = shuffle
- if self.is_shuffled is False:
- shuffle = requests.get('https://deckofcardsapi.com/api/deck/new').json()
- elif self.is_shuffled is True:
- shuffle = requests.get('https://deckofcardsapi.com/api/deck/new/shuffle').json()
- self.deck_id = shuffle['deck_id']
- def shuffle(self):
- """Shuffle the deck."""
- if self.is_shuffled is False:
- requests.get('https://deckofcardsapi.com/api/deck/' + self.deck_id + '/shuffle')
- self.is_shuffled = True
- def draw(self) -> Card:
- """
- Draw card from the deck.
- :return: card instance.
- """
- card = requests.get('https://deckofcardsapi.com/api/deck/' + self.deck_id + '/draw').json()
- card_as_object = Card(card['cards'][0]["value"], card['cards'][0]["suit"], card['cards'][0]["code"])
- return card_as_object
- class BlackjackController:
- """Blackjack controller."""
- def __init__(self, deck: Deck, view: 'BlackjackView'):
- """
- Start new blackjack game.
- :param deck: deck to draw cards from.
- :param view: view to communicate with.
- """
- self.view = view
- if deck.is_shuffled is False:
- deck.shuffle()
- if deck.is_shuffled is True:
- self.lets_the_game_begin(deck, view)
- def lets_the_game_begin(self, deck: Deck, view: 'BlackjackView'):
- """
- Just helping function.
- :param deck:
- :param view:
- :return:
- """
- self.player = Hand()
- self.PyCharm = Hand()
- self.state = {'dealer': self.PyCharm, 'player': self.player}
- self.player.add_card(deck.draw())
- self.PyCharm.add_card(deck.draw())
- self.player.add_card(deck.draw())
- self.PyCharm.add_card(deck.draw())
- if self.player.score == 21:
- self.view.player_won(self.state)
- return
- if self.PyCharm.score == 21:
- self.view.player_lost(self.state)
- return
- if self.player.score < 21:
- if self.view.ask_next_move(self.state) == 'H':
- self.player.add_card(deck.draw())
- if self.player.score == 21:
- self.view.player_won(self.state)
- return
- if self.player.score > 21:
- self.view.player_lost(self.state)
- return
- if self.view.ask_next_move(self.state) == 'S':
- if self.PyCharm.score < 22 and self.PyCharm.score > self.player.score:
- view.player_lost(self.state)
- return
- if self.PyCharm.score > 21 and self.PyCharm.score > self.player.score:
- view.player_won(self.state)
- return
- class BlackjackView:
- """Minimalistic UI/view for the blackjack game."""
- def ask_next_move(self, state: dict) -> str:
- """
- Get next move from the player.
- :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
- :return: parsed command that user has choses. String "H" for hit and "S" for stand
- """
- self.display_state(state)
- while True:
- action = input("Choose your next move hit(H) or stand(S) > ")
- if action.upper() in ["H", "S"]:
- return action.upper()
- print("Invalid command!")
- def player_lost(self, state):
- """
- Display player lost dialog to the user.
- :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
- """
- self.display_state(state, final=True)
- print("You lost")
- def player_won(self, state):
- """
- Display player won dialog to the user.
- :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
- """
- self.display_state(state, final=True)
- print("You won")
- def display_state(self, state, final=False):
- """
- Display state of the game for the user.
- :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
- :param final: boolean if the given state is final state. True if game has been lost or won.
- """
- dealer_score = state["dealer"].score if final else "??"
- dealer_cards = state["dealer"].cards
- if not final:
- dealer_cards_hidden_last = [c.__repr__() for c in dealer_cards[:-1]] + ["??"]
- dealer_cards = f"[{','.join(dealer_cards_hidden_last)}]"
- player_score = state["player"].score
- player_cards = state["player"].cards
- print(dedent(
- f"""
- {"Dealer score":<15}: {dealer_score}
- {"Dealer hand":<15}: {dealer_cards}
- {"Your score":<15}: {player_score}
- {"Your hand":<15}: {player_cards}
- """
- ))
- if __name__ == '__main__':
- BlackjackController(Deck(), BlackjackView()) # start the game.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement