Ошибка типа: индексы списка должны быть целыми числами или фрагментами, а не нетипичными в игре connect 4

#python #python-3.x #while-loop

#python #python-3.x #цикл while

Вопрос:

Я изучаю python и для обучения создаю игру connect4. Поскольку я пытаюсь стереть все ошибочные входные данные из «player», я хотел просто запросить ввод для «столбца», и он автоматически добавился бы к последней доступной «строке», к сожалению, я не придумал, как это сделать.

Вот что у меня есть на данный момент:

РЕДАКТИРОВАТЬ: теперь, когда весь код вставлен

 def main():
    board = [
        [None, None, None, None, None, None, None],
        [None, None, None, None, None, None, None],
        [None, None, None, None, None, None, None],
        [None, None, None, None, None, None, None],
        [None, None, None, None, None, None, None],
        [None, None, None, None, None, None, None],
    ]

    board_list = []
    while len(board[0]) > len(board_list):
        board_list.append(str(len(board_list)   1))

    header()

    active_player_index = 0
    players = ["Vasco", "PC"]
    symbols = ["O", "X"]
    player = players[active_player_index]

    while not find_winner(board):
        # show the board
        player = players[active_player_index]
        symbol = symbols[active_player_index]

        announce_turn(player)
        show_board(board)
        if not choose_location(board, symbol):
            print()
            print("You're an UBER IDIOT!")
            print("That spot was already used!")
            print()
            continue

        #   toggle active player
        active_player_index = (active_player_index   1) % len(player)

    footer()


def header():
    print()
    print("-----------------------------")
    print("----------WHALECUM-----------")
    print("-----------------------------")
    print("----------CONNECT 4----------")
    print("-----------------------------")


def footer():
    print()
    print("-----------------------------")
    print("-----------THE END-----------")
    print("-----------------------------")


def show_board(board):
    print()
    for row in board:
        print("| ", end='')
        for cell in row:
            symbol = cell if cell is not None else " "
            print(symbol, end=" | ")
        print()
    for index, r in enumerate(board[0], start=1):
        print(f"  {index} ", end="")
    print()


def announce_turn(player):
    print()
    print(f"It's {player} turn!")
    print()
    print("Pick your column...")
    print()
    print("Here's the Board:")
    print()


def choose_location(board, symbol, board_list):
    column = input("Choose a column: ")
    while column not in board_list:
        print(f"{column} is not an option, try again")
        column = input("Choose a column: ")
    column = int(column) - 1
    row = None

    while board[row][column] is None:
        row  = 1
    row = row - 1
    cell = board[row][column]
    if cell is not None:
        return False

    board[row][column] = symbol
    return True


def find_winner(board):
    sequences = get_winning_sequences(board)

    for cells in sequences:
        symbol1 = cells[0]
        if symbol1 and all(symbol1 == cell for cell in cells):
            return True

    return False


def get_winning_sequences(board):
    sequences = []

    # win by row
    rows = board
    sequences.extend(rows)

    # win by columns
    for col_idx in range(0, 3):
        col = [
            board[0][col_idx],
            board[1][col_idx],
            board[2][col_idx],
        ]
        sequences.append(col)

    # win by diagonals
    diagonals = [
        [board[0][0], board[1][1], board[2][2]],
        [board[0][2], board[1][1], board[2][0]],
    ]
    sequences.extend(diagonals)

    return sequences


if __name__ == '__main__':
    main()
  

Комментарии:

1. Это вся ваша программа? Как вы вызываете choose_location ? В какой строке находится сообщение об ошибке?

2. это не вся программа, теперь я вижу, что мне следовало добавить весь код, ошибки происходят из while board[row][column] is None:

3. Вы устанавливаете row значение None , а затем выполняете board[row] . Почему?

4. @VascoRodrigues Я бы предложил привести небольшой раздел, в котором ваш код терпит неудачу. Предоставление всего кода — это не способ сделать это.

Ответ №1:

Для дальнейшего использования ваши вопросы StackOverflow будут лучше, если публикуемый вами код будет работоспособным и продемонстрирует проблему или ситуацию, соответствующую вашему вопросу. Я начал с вашего кода и добавил это в конец main() , чтобы заставить его что-то делать:

 result = choose_location(board, '0', board_list)
print(result)
for r in board:
    print(r)
  

Затем я запустил его и увидел эту ошибку. Эту трассировку стека было бы неплохо включить в ваш вопрос:

 Traceback (most recent call last):
  File "x.py", line 51, in <module>
    main()
  File "x.py", line 19, in main
    result = choose_location(board, '0', board_list)
  File "x.py", line 33, in choose_location
    while board[row][column] is None:
TypeError: list indices must be integers or slices, not NoneType
  

Вы можете исправить проблемы с индексацией, настроив все по-другому. Инициализируйте строку нулем, а не None . И добавьте проверку на максимально возможный индекс строки.

 row = 0
n_rows = len(board)
while row < n_rows and board[row][column] is None:
    row  = 1
  

Кстати, я думаю, вы можете избавиться от board_list . Это кажется ненужным. Вы знаете, что допустимые столбцы должны быть в range(1, len(board[0] 1)) .

Ответ №2:

используйте эту функцию, чтобы получить наименьшую позицию для данного столбца

 # returns [row, col] of players piece, returns None if column is filled up
def get_row(col, board):
    if board[0][col] != None:# column is filled up
        return None
    for row in range(7):# find lowest unfilled position
        if (board[row][col] != None) or (row == 6):# place is filled or at bottom of board
            return [row-1, col]