Ошибка Pop from Empty List во время игры Black Jack - PullRequest
0 голосов
/ 13 июля 2020

Хорошо, у меня странная ошибка, и, к сожалению, я не знаю, могу ли я показать здесь оба примера.

Взгляните на следующий код (извиняюсь за длину):

import random

suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
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,suit,rank):
        self.suit = suit
        self.rank = rank
        ## Attributes listed in the __init__ statement do not have to
        ## correlate to called objects (ie: suit,rank)
        self.value = values[rank]
        ## Values represents the integer value of each card as compared
        ## to it's string (word) based rank
    
    def __str__(self):
        return self.rank + " of " + self.suit
        ## Allows for printing in the form of X of Y, or Two of Hearts as an example
        
# Deck will be a compilation of all card objects to a single list
# that can then be shuffled, dealt from, etc.
class Deck():
    
    def __init__(self):
        ## All cards starts off with a blank list
        self.all_cards = []
        
        ## For each suit in suits
        for suit in suits:
            ### For each rank in ranks
            for rank in ranks:
                #### Create the Card object equal to the suit and rank of the card
                #### ie: Two of spades, three of clubs, etc.
                created_card = Card(suit,rank)
                #### Then append each card created to the self.all_cards list.
                self.all_cards.append(created_card)
    
    def shuffle(self):
        ## Method call to randomize the self.all_cards list internally
        random.shuffle(self.all_cards)
        
    def deal_one(self):
        return self.all_cards.pop()
    
game_deck = Deck()

game_deck.shuffle()

## Checking to make sure the deck is full before continuing
print(len(game_deck.all_cards))

## Attempt without watching tutorial

class Player():
    
    def __init__(self,name):
        self.name = name
        self.player_hand = []
        self.balance = 100
        self.bet = 0
    
    def deposit(self,dep_amt):
        self.balance += dep_amt
        print(f'{dep_amt} added to balance.  New balance is: ${self.balance}')
    
    def withdraw(self,wit_amt):
        self.balance -= wit_amt
        print(f'{wit_amt} subtracted from balance.  New balance is: ${self.balance}')
        
    def player_bet(self,bet_amt = 0):
        while True:
            bet_amt = int(input("How much would you like to bet? \n"))
            if bet_amt > self.balance:
                print("Sorry, you don't have enough money, try again.")
            elif bet_amt < 1:
                print('Sorry, you must bet at least $1')
            else:
                print(f'Thanks, your bet is ${bet_amt}')
                self.balance -= bet_amt
                print(f'Your remaining balance is ${self.balance}')
                break
    
    ## May need to be adjusted to clear the hand entirely, unsure
    def remove_one(self):
        return self.player_hand.pop(0)
    
    # NOTE: The most cards a player can hold without busting is 11
    
    def add_cards(self,new_cards):
        ### Single card object
        self.player_hand.append(new_cards)
                
    def __str__(self):
        return f'{self.name} has a balance of ${self.balance}.'
    
## Attempt without watching tutorial

class Dealer():
    
    def __init__(self,name):
        self.name = name
        self.player_hand = []
        self.balance = 500
    
    def deposit(self,dep_amt):
        self.balance += dep_amt
        print(f'{dep_amt} added to balance.  New balance is: ${self.balance}')
    
    def withdraw(self,wit_amt):
        self.balance -= wit_amt
        print(f'{wit_amt} subtracted from balance.  New balance is: ${self.balance}')
    
    def remove_one(self):
        return self.player_hand.pop(0)
    def add_cards(self,new_cards):
        ### Single card object
        self.player_hand.append(new_cards)
                
    def __str__(self):
        return f'{self.name} has a balance of ${self.balance}.'
    
## Full Game Code

game_on = True
playing = False

while game_on == True:

    game_check = input('Would you like to play Black Jack, Y/N? ').lower()

    if game_check == 'y':
        round_counter = 0
        dealer_name = 'Klaus the Dealer'
        dealer = Dealer(dealer_name)
        player_name = input("Player One, what is your name? ")
        player_one = Player(player_name)
        print(f"Nice to meet you {player_name}, you'll be playing against {dealer_name}\n")
        print(player_one)
        print(dealer)
        print("Let's play Black Jack!\n")
        playing = True
    else:
        print('Ok, have a nice day')
        game_on = False
        break

    while playing == True:
        
        round_counter +=1

        for x in range(2):
            player_one.add_cards(game_deck.deal_one())
            dealer.add_cards(game_deck.deal_one())

Итак, когда я запускаю этот код сразу, в самых последних двух строках, я получаю ошибку индекса, когда код попадает в player_one.add_cards(game_deck.deal_one()) с указанием IndexError: pop from empty list

Дело в том, что если я запускаю этот код в отдельных строках в блокноте Jupiter и отделяю вызовы классов от остальной части игрового кода, player_one.add_cards(game_deck.deal_one()) работает нормально.

Может ли кто-нибудь сказать мне, что вызывает эту ошибку?

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Хорошо, поэтому спасибо Jeff H за то, что он указал, что призыв к раздаче карты был внутри бесконечного l oop, хотя я не мог решить проблему, нарушив l oop сам, я выяснил, как начать начальную раздачу, включив ее в game_check выражение выше, например:

while game_on == True:

    game_check = input('Would you like to play Black Jack, Y/N? ').lower()

    if game_check == 'y':
        round_counter = 0
        dealer_name = 'Klaus the Dealer'
        dealer = Dealer(dealer_name)
        player_name = input("Player One, what is your name? ")
        player_one = Player(player_name)
        print(f"Nice to meet you {player_name}, you'll be playing against {dealer_name}\n")
        print(player_one)
        print(dealer)
        print("Let's play Black Jack!\n")
        playing = True
        for x in range(2):
            player_one.add_cards(game_deck.deal_one())
            dealer.add_cards(game_deck.deal_one())

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

0 голосов
/ 13 июля 2020

У вас заканчиваются карты ...:)

строка, на которую вы ссылаетесь, находится внутри бесконечного l oop.

while playing == True:

  round_counter +=1

  for x in range(2):
    player_one.add_cards(game_deck.deal_one())
    dealer.add_cards(game_deck.deal_one())

предложение: пока вы устраняете неполадки, просто вставьте небольшой оператор печати в функцию deal_one (), чтобы увидеть, что происходит, а затем удалите его позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...