Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
665 views
in Technique[技术] by (71.8m points)

Python 3: Getting IndexError: list index out of range on shuffle method

I'm building a blackjack command line game and I've run into a snag. The shuffle feature on my deck class object keeps coming up with IndexError: list index out of range on line 29. It is a sporadic bug, id say about 50% of the time it comes up. Here is the code:

import random

#class constructor for cards
class card:
    def __init__(self, suit, card_name, card_value):
        self.suit = suit
        self.card_name = card_name
        self.card_value = card_value

#class constructor for the deck
class deck:
    def __init__(self):
        self.current_deck = []
        self.suits = ['hearts', 'diamonds','spades','clubs']
        self.cards = ['ace','2','3','4','5','6','7','8','9','10','jack','queen','king']
    def initialize(self):
        for i in range(len(self.suits)):
            for j in range(len(self.cards)):
                if (self.cards[j]=='2' or self.cards[j]=='3' or self.cards[j]=='4' or self.cards[j]=='5' or self.cards[j]=='6' or self.cards[j]=='7' or self.cards[j]=='8' or self.cards[j]=='9'):
                    self.current_deck.append(card(self.suits[i], self.cards[j], int(self.cards[j])))
                elif (self.cards[j]=='10' or self.cards[j]=='jack' or self.cards[j]=='queen' or self.cards[j]=='king'):   
                    self.current_deck.append(card(self.suits[i], self.cards[j], 10))
                else:
                    self.current_deck.append(card(self.suits[i], self.cards[j], 11))
    def shuffle(self):
        for card in self.current_deck:
            j = random.randint(0, len(playing_deck.current_deck))
            temp = card
            card = self.current_deck[j]
            self.current_deck[j] = temp

class dealer:
    def __init__(self):
        self.money = 10000
        self.hand = []
    def hit(self, deck_):
        self.hand.append(deck_.pop())
    def deal(self, deck_, player_):
        self.hand.append(deck_.pop())

class player: 
    def __init__(self, name):
        self.name = name
        self.money = 200
        self.hand = []
    def hit(self, deck_):
        self.hand.append(deck_.pop())

josh = player('josh')

playing_deck = deck()

playing_deck.initialize()
playing_deck.shuffle()

josh.hit(playing_deck.current_deck)


for i in range(len(playing_deck.current_deck)):
    print(vars(playing_deck.current_deck[i]))
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're calling randint:

Return a random integer N such that a <= N <= b. Alias for randrange(a, b+1).

If it's not obvious why this is a problem, let's use a much smaller example:

>>> a = ['x', 'y']
>>> len(a)
2
>>> a[0]
'x'
>>> a[1]
'y'
>>> a[2]
IndexError: list index out of range
>>> randint(0, 2)
1
>>> randint(0, 2)
2 # oops

This is why Python usually uses half-open ranges, where a <= N < b, instead of a <= N <= b. And why you normally want to use randrange instead of randint.


Or, even more often, when you find yourself reaching for randint or randrange, there's a good chance you wanted shuffle (which will randomly reorder the whole list in one go), or choice (which will pick a value out of a list, without needing to first pick an index), etc., so skim through the docs to see if what you want is already written.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...