Индекс списка вне диапазона: len (list) не обновляется после нескольких итераций - PullRequest
0 голосов
/ 24 февраля 2020

Когда я запускаю следующий код, я получаю это сообщение об ошибке:

IndexError: список индекса выходит за пределы диапазона

Что вызывает это?

cardChosen = deck[random.randint(0, len(deck))]

должен продолжать уменьшаться для своего максимального диапазона каждый раунд, но программа говорит, что я вне диапазона.

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:)")

Ответы [ 2 ]

2 голосов
/ 24 февраля 2020

Вы выбираете случайные элементы 1 слишком далеко.

Когда длина вашего списка равна 1, и у вас есть только выбор, cardChosen = deck[random.randint(0, len(deck))] эквивалентно cardChosen = deck[0] или deck[1], что не существовать.

Вы хотите использовать random.randint(0, len(deck)-1).

Редактировать: всегда проверяйте документацию библиотек, которые вы используете. Например, встроенный range(a, b) не включает b, а random.randint(a, b) -.

0 голосов
/ 25 февраля 2020

Я призываю вас взглянуть на это исполнение вашего кода. Поначалу это может показаться немного сложным, НО это только потому, что я вставил так много #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:)")
```

А вот версия без заметок. Обратите внимание, что он примерно одинакового размера.

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:)")

Пожалуйста, знайте, что я тоже новичок, но я думаю, что мы должны помочь друг другу, вы знаете?

Итак, чтобы ответить на ваш вопрос, проблема, как говорили другие, может быть решена с помощью метода random.choice (list)

Но другие вещи, на которые я хотел бы обратить внимание, которые могут БОЛЬШО сократить ваш код, - это начать опускать пальцы в классах. Это намного проще, чем кажется, но классы позволят вам создать класс 'player', в котором есть объекты, называемые Score, или name, или card_drawn, так что Players.name = 'Mike', Players.score = 27 et c ...

Я также реструктурировал и поставил ваши функции на первое место. Таким образом, ваш фактический игровой процесс может быть отдельным. Я очень слабо отношусь к функциям как к меткам, которые изменяют способ запуска программы. Если вы когда-либо использовали команду GOTO, она может выглядеть почти так же. Программа Останавливается и переходит к функции независимо от того, где она ДОЛЖНА, так как функция УЖЕ определена.

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

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