# Текстовый блэкджек

Я хотел сделать игру в блэкджек, чтобы пользоваться ею, когда мне скучно, но это оказалось намного сложнее, чем я думал.

``````from random import choice, randint

MASTER_DECK = ["A", "A", "A", "A",
"2", "2", "2", "2",
"3", "3", "3", "3",
"4", "4", "4", "4",
"5", "5", "5", "5",
"6", "6", "6", "6",
"7", "7", "7", "7",
"8", "8", "8", "8",
"9", "9", "9", "9",
"10", "10", "10", "10",
"J", "J", "J", "J",
"Q", "Q", "Q", "Q",
"K", "K", "K", "K"]

def setup(deck):
"""Sets up all game variables"""
# Initialize all of the hands
player_hand, deck = pick_cards(deck)
dealer_hand, deck = pick_cards(deck)
return deck, player_hand, dealer_hand

def pick_cards(deck):
"""Deals two random cards"""
hand = []
if len(deck) <= 6:
deck = MASTER_DECK.copy()
for card in range(0, 2):
chosen_card = choice(deck)
hand.append(chosen_card)
deck.remove(chosen_card)
return hand, deck

def print_ui(player_hand, dealer_hand, deck, game_state):
"""Prints out the display that tells the user there cards"""
print()
if game_state == "player_dealing":
print("The dealer has these cards:n_, " + ", ".join(dealer_hand[1:]))
print()
print("You have these cards:n" + ", ".join(player_hand))
print()
print(f"There are {len(deck)} cards left in the deck")
elif game_state == "dealer_dealing":
print("The dealer has these cards:n" + ", ".join(dealer_hand))
print()
print("You have these cards:n" + ", ".join(player_hand))
print()
if have_won(player_hand, dealer_hand):
print("You have beaten the dealer.")
else:
print("You have not beaten the dealer.")
else:
print("Something has gone wrong")
while True:
pass

def have_won(player_hand, dealer_hand):
"""Checks if the player has won"""
numeric_player_hand = numeric_cards(player_hand.copy())
player_hand_total = 0
for card in numeric_player_hand:
player_hand_total += card
numeric_dealer_hand = numeric_cards(dealer_hand.copy())
dealer_hand_total = 0
for card in numeric_dealer_hand:
dealer_hand_total += card
if dealer_hand_total > 21:
if player_hand_total > 21:
return False
return True
if dealer_hand_total == 21:
return False
if dealer_hand_total < 21:
if dealer_hand_total < player_hand_total <= 21:
return True
return False

def betting_phase(tokens):
"""Takes the users bet"""
print(f"You have {tokens} tokens.")
while True:
try:
bet = int(input("Please enter you bet: "))
if int(bet) > 0:
if (tokens - bet) >= 0:
break
print("Do not bet more than you have.")
else:
print("Please enter a number greater than zero.")
except ValueError:

def player_dealing(deck, player_hand, game_state):
"""Handles dealing to the player"""
if not deck:
print("As there are no more cards left, the round ends.")
game_state = "dealer_dealing"
else:
while True:
user_command = input("Would you like to hit or to stay? (H/S): ").lower()
if user_command == "h":
chosen_card = choice(deck)
player_hand.append(chosen_card)
deck.remove(chosen_card)
break
elif user_command == "s":
game_state = "dealer_dealing"
break
else:
print("Please only enter H for hit or S for stay.")
return deck, player_hand, game_state

def dealer_dealing(deck, dealer_hand):
"""Handles dealing to the dealer"""
while True:
if not deck:
break
numeric_dealer_hand = numeric_cards(dealer_hand.copy())
hand_total = 0
for card in numeric_dealer_hand:
hand_total += card
if hand_total < 16:
chosen_card = choice(deck)
dealer_hand.append(chosen_card)
deck.remove(chosen_card)
elif hand_total == 16:
if randint(0, 1):
chosen_card = choice(deck)
dealer_hand.append(chosen_card)
deck.remove(chosen_card)
else:
break
elif 11 in numeric_dealer_hand and hand_total > 21:
for card_number, card in enumerate(numeric_dealer_hand):
if card == 11:
numeric_dealer_hand[card_number] = 1
else:
break
return deck, dealer_hand

def numeric_cards(hand):
"""Turns card letters into their number values"""
for card_number, card in enumerate(hand):
if card == "J" or card == "Q" or card == "K":
hand[card_number] = 10
elif card == "A":
hand[card_number] = 11
else:
hand[card_number] = int(hand[card_number])
hand_total = 0
for card in hand:
hand_total += card
if hand_total > 21 and 11 in hand:
for card_number, card in enumerate(hand):
if card == 11:
hand[card_number] = 1
return hand

def play_again():
"""Allows user to play again or quit"""
while True:
play_again = input("Do you want to play again? (Y/N): ").lower()
if play_again == "y":
break
elif play_again == "n":
quit()
print("Please only enter a Y or N")

deck = MASTER_DECK.copy()
tokens = 200

while True:
game_state = "betting"
playing_game = True

deck, player_hand, dealer_hand = setup(deck)

while playing_game:
if game_state == "betting":
tokens, bet = betting_phase(tokens)
game_state = "player_dealing"
else:
print_ui(player_hand, dealer_hand, deck, game_state)
deck, player_hand, game_state = player_dealing(deck, player_hand, game_state)
if game_state == "dealer_dealing":
deck, dealer_hand = dealer_dealing(deck, dealer_hand)
if have_won(player_hand, dealer_hand):
tokens += 2 * bet
print_ui(player_hand, dealer_hand, deck, game_state)
playing_game = False
if tokens:
play_again()
else:
input("You have no more tokens to spend. Hit enter to quit.")
quit()

``````

Первоначально я хотел добавить несколько AI-плееров, а также включить функции split и double, но код стал настолько сложным, что я подумал, что лучше не включать их, если код не был очищен.

Есть ли способ очистить это и упростить добавление дополнительных функций? Кроме того, есть ли что-нибудь еще, что можно было бы улучшить?