Advertisement
Alekal

Untitled

Dec 4th, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.88 KB | None | 0 0
  1. """Simple game of blackjack."""
  2. from textwrap import dedent
  3. import requests
  4.  
  5.  
  6. class Card:
  7. """Simple dataclass for holding card information."""
  8.  
  9. def __init__(self, value: str, suit: str, code: str):
  10. """
  11. Unit.
  12.  
  13. :param value:
  14. :param suit:
  15. :param code:
  16. """
  17. self.value = value
  18. self.suit = suit
  19. self.code = code
  20.  
  21. def __repr__(self) -> str:
  22. """
  23. Repr.
  24.  
  25. :return:
  26. """
  27. return self.code
  28.  
  29.  
  30. class Hand:
  31. """Simple class for holding hand information."""
  32.  
  33. def __init__(self):
  34. """Unit."""
  35. self.score = 0
  36. self.cards = []
  37. self.ace_used = 0
  38. self.aces_in_hand = 0
  39.  
  40. def add_card(self, card: Card):
  41. """
  42. Add card.
  43.  
  44. :param card:
  45. :return:
  46. """
  47. self.score = 0
  48. self.cards.append(card)
  49. for card in self.cards:
  50. if card.value == "ACE":
  51. self.score += 11
  52. self.aces_in_hand += 1
  53. elif len(card.value) < 3:
  54. self.score += int(card.value)
  55. elif card.value == "JACK":
  56. self.score += 10
  57. elif card.value == "QUEEN":
  58. self.score += 10
  59. elif card.value == "KING":
  60. self.score += 10
  61. while self.score > 21 and self.ace_used < self.aces_in_hand:
  62. self.score -= 10
  63. self.ace_used += 1
  64.  
  65.  
  66. class Deck:
  67. """Deck of cards. Provided via api over the network."""
  68.  
  69. def __init__(self, shuffle=False):
  70. """
  71. Tell api to create a new deck.
  72.  
  73. :param shuffle: if shuffle option is true, make new shuffled deck.
  74. """
  75. self.is_shuffled = shuffle
  76. if self.is_shuffled is False:
  77. shuffle = requests.get('https://deckofcardsapi.com/api/deck/new').json()
  78. elif self.is_shuffled is True:
  79. shuffle = requests.get('https://deckofcardsapi.com/api/deck/new/shuffle').json()
  80. self.deck_id = shuffle['deck_id']
  81.  
  82. def shuffle(self):
  83. """Shuffle the deck."""
  84. if self.is_shuffled is False:
  85. requests.get('https://deckofcardsapi.com/api/deck/' + self.deck_id + '/shuffle')
  86. self.is_shuffled = True
  87.  
  88. def draw(self) -> Card:
  89. """
  90. Draw card from the deck.
  91.  
  92. :return: card instance.
  93. """
  94. card = requests.get('https://deckofcardsapi.com/api/deck/' + self.deck_id + '/draw').json()
  95. card_as_object = Card(card['cards'][0]["value"], card['cards'][0]["suit"], card['cards'][0]["code"])
  96. return card_as_object
  97.  
  98.  
  99. class BlackjackController:
  100. """Blackjack controller."""
  101.  
  102. def __init__(self, deck: Deck, view: 'BlackjackView'):
  103. """
  104. Start new blackjack game.
  105.  
  106. :param deck: deck to draw cards from.
  107. :param view: view to communicate with.
  108. """
  109. self.view = view
  110. if deck.is_shuffled is False:
  111. deck.shuffle()
  112. if deck.is_shuffled is True:
  113. self.lets_the_game_begin(deck, view)
  114.  
  115. def lets_the_game_begin(self, deck: Deck, view: 'BlackjackView'):
  116. """
  117. Just helping function.
  118.  
  119. :param deck:
  120. :param view:
  121. :return:
  122. """
  123. self.player = Hand()
  124. self.PyCharm = Hand()
  125. self.state = {'dealer': self.PyCharm, 'player': self.player}
  126. self.player.add_card(deck.draw())
  127. self.PyCharm.add_card(deck.draw())
  128. self.player.add_card(deck.draw())
  129. self.PyCharm.add_card(deck.draw())
  130. if self.player.score == 21:
  131. self.view.player_won(self.state)
  132. return
  133. if self.PyCharm.score == 21:
  134. self.view.player_lost(self.state)
  135. return
  136. if self.player.score < 21:
  137. if self.view.ask_next_move(self.state) == 'H':
  138. self.player.add_card(deck.draw())
  139. if self.player.score == 21:
  140. self.view.player_won(self.state)
  141. return
  142. if self.player.score > 21:
  143. self.view.player_lost(self.state)
  144. return
  145. if self.view.ask_next_move(self.state) == 'S':
  146. if self.PyCharm.score < 22 and self.PyCharm.score > self.player.score:
  147. view.player_lost(self.state)
  148. return
  149. if self.PyCharm.score > 21 and self.PyCharm.score > self.player.score:
  150. view.player_won(self.state)
  151. return
  152.  
  153.  
  154. class BlackjackView:
  155. """Minimalistic UI/view for the blackjack game."""
  156.  
  157. def ask_next_move(self, state: dict) -> str:
  158. """
  159. Get next move from the player.
  160.  
  161. :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
  162. :return: parsed command that user has choses. String "H" for hit and "S" for stand
  163. """
  164. self.display_state(state)
  165. while True:
  166. action = input("Choose your next move hit(H) or stand(S) > ")
  167. if action.upper() in ["H", "S"]:
  168. return action.upper()
  169. print("Invalid command!")
  170.  
  171. def player_lost(self, state):
  172. """
  173. Display player lost dialog to the user.
  174.  
  175. :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
  176. """
  177. self.display_state(state, final=True)
  178. print("You lost")
  179.  
  180. def player_won(self, state):
  181. """
  182. Display player won dialog to the user.
  183.  
  184. :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
  185. """
  186. self.display_state(state, final=True)
  187. print("You won")
  188.  
  189. def display_state(self, state, final=False):
  190. """
  191. Display state of the game for the user.
  192.  
  193. :param state: dict with given structure: {"dealer": dealer_hand_object, "player": player_hand_object}
  194. :param final: boolean if the given state is final state. True if game has been lost or won.
  195. """
  196. dealer_score = state["dealer"].score if final else "??"
  197. dealer_cards = state["dealer"].cards
  198. if not final:
  199. dealer_cards_hidden_last = [c.__repr__() for c in dealer_cards[:-1]] + ["??"]
  200. dealer_cards = f"[{','.join(dealer_cards_hidden_last)}]"
  201.  
  202. player_score = state["player"].score
  203. player_cards = state["player"].cards
  204. print(dedent(
  205. f"""
  206. {"Dealer score":<15}: {dealer_score}
  207. {"Dealer hand":<15}: {dealer_cards}
  208.  
  209. {"Your score":<15}: {player_score}
  210. {"Your hand":<15}: {player_cards}
  211. """
  212. ))
  213.  
  214.  
  215. if __name__ == '__main__':
  216. BlackjackController(Deck(), BlackjackView()) # start the game.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement