Проблема с потоком при успешных блоках операторов if в Jupiter Notebook

У меня есть этот файл, который я создал с помощью Jupiter Notebook. Это простая игра в блэкджек. Первые ячейки используются для создания классов и функций. Последний включает логику игры (которая также объясняется на верхнем уровне документа записной книжки).

В конце каждого раунда игрока спрашивают, хочет ли он играть снова. Если нет, игра окончена. Если да, то цикл будет продолжаться до тех пор, пока игрок не скажет "нет". Проблема, с которой я сталкиваюсь, заключается в том, что иногда (и на мой взгляд, это кажется случайным) в конце раунда игрока не спрашивают, хочет ли он продолжить игру, а скорее все останавливается. Кажется, я не понимаю, почему.

Я считаю, что проблема заключается в потоке, на уровне того, где логика игры объединяется (последняя ячейка), где есть x2 блока операторов if, следующих друг за другом на одном уровне отступа в пределах цикла while.. Пожалуйста помоги.

Справка:if player.value <= 21:и т.дif yes_no():

1 ответ

Игра

Чтобы разыграть руку в блэкджек, необходимо выполнить следующие шаги:

  1. Соберите колоду из 52 карт.
  2. Перемешайте колоду
  3. Спросите у игрока его ставку
  4. Убедитесь, что ставка игрока не превышает его доступных фишек.
  5. Раздайте две карты дилеру и две карты игроку.
  6. Показать только одну карту крупье, вторая остается скрытой
  7. Покажите обе карты игрока
  8. Спросите игрока, хочет ли он ударить, и возьмите еще одну карту.
  9. Если рука игрока не переборет (больше 21), спросите, не хочет ли он еще раз ударить.
  10. Если игрок стоит, разыграйте руку крупье. Крупье всегда будет бить, пока значение дилера не достигнет или не превысит 17.
  11. Определите победителя и соответствующим образом отрегулируйте фишки игрока.
  12. Спросите игрока, не хочет ли он снова сыграть

Импорт

      import random
from IPython.display import clear_output

(clear_output доступен только в Юпитере)

Значения карт

      ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 
            'Nine':9, 'Ten':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':11}

Классы

      class Card:
    
    def __init__(self,rank,suit):
        
        #create card attributes
        
        self.rank = rank
        self.suit = suit
        self.value = values[rank]
        
    def __str__(self):
        
        #output card ID to user
        
        return self.rank + ' of ' + self.suit


class Deck:
    
    def __init__(self):
        
        #create a deck list and fill it with 52 cards
        
        self.all_cards = []
        
        for rank in ranks:
            for suit in suits:
                created_card = Card(rank,suit)
                self.all_cards.append(created_card)
        
    def shuffle(self):
        
        #shuffle cards
        
        random.shuffle(self.all_cards)
        
    def __str__(self):
        
        #print how many cards in the deck
        
        return f'This deck has {len(self.all_cards)} cards'
    
    def deal_one(self):
        
        return self.all_cards.pop()


class Hand:
    
    def __init__(self):
        
        self.hand = []
        self.value = 0
        self.aces = 0
    
    def add_one(self,card):
        
        self.hand.append(card)
        
        self.value += values[card.rank]
        
        if card.rank == 'Ace':
            self.aces += 1
    
    def adjust_aces(self):
        
        while self.value > 21 and self.aces:
            self.value -= 10
            self.aces -= 1


class PlayerPurse:
    
    def __init__(self,balance=0):

        self.balance = balance
        
    def __str__(self):
        
        #print purse balance
        
        return f"Player current balance: £{self.balance}"
        
    def win_bet(self,win):
        
        #deposit funds
        
        self.balance += win
        
        return f"Player current balance: £{self.balance}"
        
    def loose_bet(self,loose):
        
        #withdraw funds (but only if withdrawal amount is under or equal to the current balance)

        self.balance -= loose
        
        return f"Player current balance: £{self.balance}"    

Функции

      def show_hand(who,who1):
    
    hand_comp = ''
    
    for card in who.hand:
        hand_comp += " "+card.__str__()+","
        
    print(f"{who1}'s hand has:" + hand_comp[:-1], f"= {who.value}")


def yes_no():
    
    choice = 'wrong'

    while choice.lower()[0] not in ['y','n']:
        
        choice = input('Are you ready to play? Enter Yes or No.')
        
        if choice.lower()[0] not in ['y','n']:
            print('You did not enter the correct value. Enter Yes or No.')
    
    if choice.lower()[0] == 'y':
        return True
    
    else:
        return False


def hit():
    
    choice = 'wrong'

    while choice.lower()[0] not in ['y','n']:
        
        choice = input('Do you want to Hit? Enter Yes or No.')
        
        if choice.lower()[0] not in ['y','n']:
            print('You did not enter the correct value. Enter Yes or No.')
    
    if choice.lower()[0] == 'y':
        return True
    
    else:
        return False


def fund_purse():
    
    incorrect_choice = True
    
    while incorrect_choice:
        
        ask_purse = input('How much would you like to transfer to your betting purse?')

        #if player input is not a number
        while ask_purse.isdigit() == False or int(ask_purse) <= 0:
            print('Sorry, you did not enter the correct value. Try again!')
            break

        #fill up the Player's purse with the deposit
        if ask_purse.isdigit() == True and int(ask_purse) > 0:
            incorrect_choice = False
            return int(ask_purse)


def bet(who):
    
    incorrect_choice = True
    
    while incorrect_choice:
        
        ask_bet = input(f'Your current balance is: £{who.balance}\nHow much would you like to bet for your next hand?')

        #if player input is not a number or (is a number but negative or equal to 0)
        while (ask_bet.isdigit() == False) or (ask_bet.isdigit() == True and int(ask_bet) <= 0):
            print("You need to enter the correct value!")
            break

        if ask_bet.isdigit() == True:
            
            ask_bet = int(ask_bet)
        
            #if player bet is superior to its balance
            while ask_bet > who.balance:
                print(f"You can't bet over your current balance of {who.balance}")
                break

            #create pending bet, which will then be dealt with in diffreent manners when win/loose
            if ask_bet <= who.balance:
                return ask_bet

Логика игры

      print('Hello and welcome to Blackjack')

ask1 = True

while ask1:
    
    ask1 = False
    #ask to play game
    if ask1 == yes_no():
        break
    
    else:
        #fund the purse
        clear_output()
        player_bank = PlayerPurse(fund_purse())
        ask2 = True
        
    while ask2:
        
        game_on = True
        
        while game_on:

            #create a new deck
            game_deck = Deck()

            #shuffle the new deck
            game_deck.shuffle()

            #reset pending bet
            pending_bet = 0

            #ask player for their bet
            clear_output()
            pending_bet = bet(player_bank)

            #create hands for the Dealer & Player
            dealer = Hand()
            player = Hand()

            #deal two cards to the Dealer & Player
            dealer.add_one(game_deck.deal_one())
            player.add_one(game_deck.deal_one())
            dealer.add_one(game_deck.deal_one())
            player.add_one(game_deck.deal_one())

            #show one of the dealer's top card
            clear_output()
            print(f"Dealer first card: {dealer.hand[0]}")

            #show player's hand
            show_hand(player,"Player")
            player.adjust_aces()

            #ask the Player if they wish to Hit, and take another card
            while player.value <= 21:
                
                if hit() == True:
                    clear_output()
                    player.add_one(game_deck.deal_one())
                    player.adjust_aces()
                    print(f"Dealer first card: {dealer.hand[0]}")
                    show_hand(player,"Player")
                
                else:
                    break

            #if the player done hitting and not bust, dealer's turn
            if player.value <= 21:

                #dealer to hit given the established conditions
                while dealer.value < 17 or dealer.value < player.value:
                    clear_output()
                    dealer.add_one(game_deck.deal_one())
                    dealer.adjust_aces()
                    show_hand(dealer,"Dealer")
                    show_hand(player,"Player")

                #when dealer goes bust
                if dealer.value > 21 or dealer.value < player.value:
                    clear_output()
                    pending_bet = pending_bet*2
                    player_bank.win_bet(pending_bet)
                    show_hand(dealer,"Dealer")
                    show_hand(player,"Player")
                    print(f'Player wins £{pending_bet}. Player balance is now £{player_bank.balance}')

                #when dealer wins
                elif dealer.value > player.value:
                    clear_output()
                    player_bank.loose_bet(pending_bet)
                    show_hand(dealer,"Dealer")
                    show_hand(player,"Player")
                    print(f'Dealer wins £{pending_bet}. Player balance is now £{player_bank.balance}')

                #push
                else:
                    clear_output()
                    show_hand(dealer,"Dealer")
                    show_hand(player,"Player")
                    print(f"It's a tie. The £{pending_bet} bet goes back to the Player who's balance is now £{player_bank.balance}")

            #if the player goes bust after hitting
            else:
                clear_output()
                player_bank.loose_bet(pending_bet)
                show_hand(dealer,"Dealer")
                show_hand(player,"Player")
                print(f'Busted. Dealer wins £{pending_bet}. Player balance is now £{player_bank.balance}')

            #ask if want to play again
           
                ask2 = True
                break
            else:
                ask1 = False
                ask2 = False
                game_on = False
                break
        
print('Thanks for playing. Bye now!')
Другие вопросы по тегам