Reputation: 1
When I run the following code, I receive this error message:
IndexError: list index out of range
What is causing this?
cardChosen = deck[random.randint(0, len(deck))]
should keep decreasing for its maximum range every round, but the program says I am out of range.
import random
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] * 4
scorePlayer1 = 0
scorePlayer2 = 0
player1 = input("Player 1: ")
player2 = input("Player 2: ")
while len(deck) > 0:
def player_turn(player_name, deck):
deck = deck
print(len(deck))
cardChosen = deck[random.randint(0, len(deck))]
deck.remove(cardChosen)
print(player_name + " chose " + str(cardChosen))
return(cardChosen)
a = player_turn(player1, deck)
b = player_turn(player2, deck)
if a > b:
scorePlayer1 += 2
print(player1 + " wins this round:)")
elif b > a:
scorePlayer2 += 2
print(player2 + " wins this round :)")
elif a == b:
print("War!")
print(scorePlayer1)
print(scorePlayer2)
else:
print("Game Over")
if scorePlayer1 > scorePlayer2:
print(player1 + " has won the game:)")
elif scorePlayer2 > scorePlayer1:
print(player2 + " has won the game:)")
elif scorePlayer1 == scorePlayer2:
print("There has been a tie, both players won:)")
Upvotes: 0
Views: 55
Reputation: 35
I encourage you to take a look at this rendition of your code. It can seem a little daunting at first, BUT it's only because there's so many #notes that I put in.
Here is the version with the notes
’’’
import random
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] * 4
#>>> suggestion below
length = len(deck)
round = 1
scorePlayer1 = 0
scorePlayer2 = 0
player1 = input("Player 1: ")
player2 = input("Player 2: ")
print("Round: {}".format(round)) #>>> used for user clarification
# >>> Removed "while" statement, and kept the
#main player turn function as its own stand alone function
def player_turn(player_name, length):
#deck = deck >>>Line not needed
#print(len(deck)) >>> removed
#cardChosen = deck[random.randint(0, len(deck))] >>>solution below
cardChosen = random.choice(deck)
deck.remove(cardChosen)
#suggestion below
length -= 1
#print(player_name + " chose " + str(cardChosen)) >>>suggestion below
print("{} drew the card: {}".format(player_name, cardChosen))
#return(cardChosen) >>> suggestion below
return cardChosen, length
#as long as the length of the deck (which is updated
#everytime the function is called) is greater than zero
while length > 0:
round += 1#>>> used for user clarification
#set the variables cardChosen and length to equal
#whatever the output of the player turn function (with
#2 argument given) returns
cardChosen, length = player_turn(player1, length)
#then set the players score to equal the card drawn
scorePlayer1 += cardChosen
player1_hand = cardChosen
#afterwards repeat the same for player 2
cardChosen, length = player_turn(player2, length)
scorePlayer2 += cardChosen
player2_hand = cardChosen
#>>>replace "a" and "b" with better, readable variables
#if a > b:
if scorePlayer1 > scorePlayer2:
scorePlayer1 += 2
#print(player1 + " wins this round:)") >>> use the format method, highly recommended. suggestion below
print("{} won this round".format(player1))
print("{}'s score: {}".format(player1, scorePlayer1))
print("{}'s score: {}".format(player2, scorePlayer2))
print("\n\n") #>>>adds a space between rounds
elif scorePlayer2 > scorePlayer1:
scorePlayer2 += 2
#print(player2 + " wins this round :)") >>>suggestion below
print("{} won this round".format(player2))
print("{}'s score: {}".format(player1, scorePlayer1))
print("{}'s score: {}".format(player2, scorePlayer2))
print("\n\n") # >>> adds a space between rounds
if player1_hand == player2_hand:
#print("War!") >>> suggestiom below
print("WAAAAAAAR!!!") #>>>How will anyone take you seriously if you dont scream!
print("{}'s score: {}".format(player1, scorePlayer1))
print("{}'s score: {}".format(player2, scorePlayer2))
print("\n\n") # >>> adds a space between rounds
#else: >>> unneeded "else" statement since the "while" loop automatically
#stops once there are no more cards in the deck
#add a pause so the viewer can comprehend what the heck just happened
print("Number of cards left: {}".format(length))
pause = input("Press ENTER to continue...")
print("============================\n\n") #>>> adds a space
print("Round: {}".format(round))
print("Game Over")
if scorePlayer1 > scorePlayer2:
#print(player1 + " has won the game:)") >>> suggestion below
print("{} has won the game".format(player1))
elif scorePlayer2 > scorePlayer1:
#print(player2 + " has won the game:)") >>> suggestion below
print("{} has won the game".format(player2))
elif scorePlayer1 == scorePlayer2:
print("There has been a tie, both players won:)")
```
And here is the version without the notes. Notice that it's just about the same size.
import random
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] * 4
length = len(deck)
round = 1
scorePlayer1 = 0
scorePlayer2 = 0
player1 = input("Player 1: ")
player2 = input("Player 2: ")
print("Round: {}".format(round))
def player_turn(player_name, length):
cardChosen = random.choice(deck)
deck.remove(cardChosen)
length -= 1
print("{} drew the card: {}".format(player_name, cardChosen))
return cardChosen, length
while length > 0:
round += 1
cardChosen, length = player_turn(player1, length)
scorePlayer1 += cardChosen
player1_hand = cardChosen
cardChosen, length = player_turn(player2, length)
scorePlayer2 += cardChosen
player2_hand = cardChosen
if scorePlayer1 > scorePlayer2:
scorePlayer1 += 2
print("{} won this round".format(player1))
print("{}'s score: {}".format(player1, scorePlayer1))
print("{}'s score: {}".format(player2, scorePlayer2))
print("\n\n")
elif scorePlayer2 > scorePlayer1:
scorePlayer2 += 2
print("{} won this round".format(player2))
print("{}'s score: {}".format(player1, scorePlayer1))
print("{}'s score: {}".format(player2, scorePlayer2))
print("\n\n")
if player1_hand == player2_hand:
print("WAAAAAAAR!!!")
print("{}'s score: {}".format(player1, scorePlayer1))
print("{}'s score: {}".format(player2, scorePlayer2))
print("\n\n")
print("Number of cards left: {}".format(length))
pause = input("Press ENTER to continue...")
print("============================\n\n")
print("Round: {}".format(round))
print("Game Over")
if scorePlayer1 > scorePlayer2:
print("{} has won the game".format(player1))
elif scorePlayer2 > scorePlayer1:
print("{} has won the game".format(player2))
elif scorePlayer1 == scorePlayer2:
print("There has been a tie, both players won:)")
Please know that I am a beginner too, but I figure that we gotta help each other out you know?
So to answer your question, the problem like others have said can be solved using the random.choice(list) method
But other stuff that I would point out that could GREATLY shorten your code would be to start dipping your toes in classes. It's so much easier than it looks, but classes will allow you to create a 'player' class, that has objects called score, or name, or card_drawn so players.name = 'Mike', players.score = 27 etc...
I also restructured and placed your functions up top. This way your actual game play can be seperate. I very loosely think of functions as labels that alter the way the program is run. If you've ever used command prompts GOTO command it can almost in some small way be looked at the same way. The program STOPS, and goes to the function no matter where it is AS LONG as the function has ALREADY been defined.
If you have any questions please feel free to ask me, you could probably even help me out some too.
Upvotes: 0
Reputation: 4649
You are fetching random items 1 too far.
When the length of your list is 1 and you only have a choice left, cardChosen = deck[random.randint(0, len(deck))]
is equivalent to cardChosen = deck[0]
or deck[1]
which does not exist.
You want to use random.randint(0, len(deck)-1)
.
Edit: always check the documentation of the libraries you use. For example, the built-in range(a, b)
does not include b
while random.randint(a, b)
does.
Upvotes: 2