2015-08-11 2 views
-1

Я пытаюсь следовать за книгой, которую я приобрел Программой Python для абсолютного новичка 3-го издания. Глава 6 Challenge 4, попросит сделать игру tic-tac-toe непревзойденной. Изменив функцию computer_move(). Я внесла поправки, чтобы сделать игру непревзойденной (когда игрок-человек занимает противоположные углы в первых двух ходах, это была дыра в стратегии). Но теперь я сломал часть, где компьютер идет первым. И я понятия не имею, почему.Ошибка в непревзойденной игре tic tac toe

Я получаю ошибку TypeError: list indices must be integers, not NoneType

# Tic-Tac-Toe 
# Plays the game of tic-tac-toe against a human opponent 

# global constants 
X = "X" 
O = "O" 
EMPTY = " " 
TIE = "TIE" 
NUM_SQUARES = 9 


def display_instruct(): 
    """Display game instructions.""" 
    print(
    """ 
    Welcome to the greatest intellectual challenge of all time: Tic-Tac-Toe. 
    This will be a showdown between your human brain and my silicon processor. 

    You will make your move known by entering a number, 0 - 8. The number 
    will correspond to the board position as illustrated: 

        0 | 1 | 2 
        --------- 
        3 | 4 | 5 
        --------- 
        6 | 7 | 8 

    Prepare yourself, human. The ultimate battle is about to begin. \n 
    """ 
    ) 

def ask_yes_no(question): 
    """Ask a yes or no question.""" 
    response = None 
    while response not in ("y", "n"): 
     response = input(question).lower() 
    return response 

def ask_number(question, low, high): 
    """Ask for a number within a range.""" 
    response = None 
    while response not in range(low, high): 
     response = int(input(question)) 
    return response 

def pieces(): 
    """Determine if player or computer goes first.""" 
    go_first = ask_yes_no("Do you require the first move? (y/n): ") 
    if go_first == "y": 
     print("\nThen take the first move. You will need it.") 
     human = X 
     computer = O 
    else: 
     print("\nYour bravery will be your undoing... I will go first.") 
     computer = X 
     human = O 
    return computer, human 

def new_board(): 
    """Create new game board.""" 
    board = [] 
    for square in range(NUM_SQUARES): 
     board.append(EMPTY) 
    return board 

def display_board(board): 
    """Display game board on screen.""" 
    print("\n\t", board[0], "|", board[1], "|", board[2]) 
    print("\t", "---------") 
    print("\t", board[3], "|", board[4], "|", board[5]) 
    print("\t", "---------") 
    print("\t", board[6], "|", board[7], "|", board[8], "\n") 

def legal_moves(board): 
    """Create list of legal moves.""" 
    moves = [] 
    for square in range(NUM_SQUARES): 
     if board[square] == EMPTY: 
      moves.append(square) 
    return moves 

def winner(board): 
    """Determine the game winner.""" 
    WAYS_TO_WIN = ((0, 1, 2), 
        (3, 4, 5), 
        (6, 7, 8), 
        (0, 3, 6), 
        (1, 4, 7), 
        (2, 5, 8), 
        (0, 4, 8), 
        (2, 4, 6)) 

    for row in WAYS_TO_WIN: 
     if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY: 
      winner = board[row[0]] 
      return winner 

    if EMPTY not in board: 
     return TIE 

    return None 

def human_move(board, human): 
    """Get human move.""" 
    legal = legal_moves(board) 
    move = None 
    while move not in legal: 
     move = ask_number("Where will you move? (0 - 8):", 0, NUM_SQUARES) 
     if move not in legal: 
      print("\nThat square is already occupied, foolish human. Choose another.\n") 
    print("Fine...") 
    return move 

def computer_move(board, computer, human): 
    """Make computer move.""" 
    # make a copy to work with since function will be changing list 
    board = board[:] 
    # the best positions to have, in order 
    BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7) 
    #INCLUDED FOR CHALLENGE 4 CHAPTER 6 TO MAKE THE GAME UNBEATABLE 
    SMART_HUMAN = ((2, 0), (6, 8)) 
    print("I shall take square number", end=" ") 

    # if computer can win, take that move 
    for move in legal_moves(board): 
     board[move] = computer 
     if winner(board) == computer: 
      print(move) 
      return move 
     # done checking this move, undo it 
     board[move] = EMPTY 

    # if human can win, block that move 
    for move in legal_moves(board): 
     board[move] = human 
     if winner(board) == human: 
      print(move) 
      return move 
     # done checkin this move, undo it 
     board[move] = EMPTY 

    # since no one can win on next move, pick best open square 
    for move in BEST_MOVES: 
     if move in legal_moves(board): 
      print(move) 
      return move 
    #EXTENDED FOR CHALLENGE 4 CHAPTER 6 TO MAKE THE GAME UNBEATABLE 
     elif move not in legal_moves(board): 
      for position in SMART_HUMAN: 
       for move in position: 
        board[move] = computer 
        if move in legal_moves(board): 
         print (move) 
         return move 



def next_turn(turn): 
    """Switch turns.""" 
    if turn == X: 
     return O 
    else: 
     return X 


def congrat_winner(the_winner, computer, human): 
    """Congratulate the winner.""" 
    if the_winner != TIE: 
     print(the_winner, "won!\n") 
    else: 
     print("It's a tie!\n") 

    if the_winner == computer: 
     print("As I predicted, human, I am triumphant once more. \n" \ 
       "Proof that computers are superior to humans in all regards.") 

    elif the_winner == human: 
     print("No, no! It cannot be! Somehow you tricked me, human. \n" \ 
       "But never again! I, the computer, so swear it!") 

    elif the_winner == TIE: 
     print("You were most lucky, human, and somehow managed to tie me. \n" \ 
       "Celebrate today... for this is the best you will ever achieve.") 

def main(): 
    display_instruct() 
    computer, human = pieces() 
    turn = X 
    board = new_board() 
    display_board(board) 

    while not winner(board): 
     if turn == human: 
      move = human_move(board, human) 
      board[move] = human 
     else: 
      move = computer_move(board, computer, human) 
      board[move] = computer 
     display_board(board) 
     turn = next_turn(turn) 

    the_winner = winner(board) 
    congrat_winner(the_winner, computer, human) 

# start the program 
main() 
input("\n\nPress the enter key to quit.") 

Я не слишком уверен, где он производит NoneType из, я работал над этим уже несколько дней, и я не могу видеть Ошибка. Это вызывает ошибку в основной функции, но я не исправил ее, и я не должен был этого делать.

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

Любая помощь была бы действительно оценена!


Edit: Полная ошибка я получаю:

I shall take square number Traceback (most recent call last): 
File "\chapter_6_challenge_4_computer_move_amended.py", line 217, in <module> 
main() 
File "\chapter_6_challenge_4_computer_move_amended.py", line 208, in main 
board[move] = computer 
TypeError: list indices must be integers, not NoneType 
+0

Посмотрите на указанной линии ошибка (которую вы должны укажите в своем вопросе - я не уверен, почему вы это пропустили), посмотрите, что он пытается использовать в качестве индекса «list», посмотрите, откуда эта переменная, посмотрите, как она назначается, выяснить если есть какой-либо способ, он может быть назначен «Нет» (есть), всегда назначает целое число вместо «Нет». – TigerhawkT3

+0

У вас есть предыдущая рабочая версия кода безопасно в системе управления версиями, не так ли? Таким образом, вы должны иметь возможность сравнить то, что сработало с тем, чего нет.Что-то, что вы изменили, нарушило код, поэтому просмотр изменений должен помочь вам определить, что произошло. (Если у вас нет кода под управлением версиями, изучите урок, убедитесь, что у вас есть код под управлением версиями, чтобы вы могли вернуться к известному состоянию или сравнить свой текущий код с более ранними версиями.) –

+0

@ JonathanLeffler - Я не думаю, что большинство людей используют контроль версий до тех пор, пока их компания не проведет его с железным кулаком. – TigerhawkT3

ответ

0

Спасибо за всю помощь в этом, он заставил меня вернуться и пересмотреть мой подход, и вот ответ.

Я создал две ошибки для себя, обе решены из удаления вложенного кортежа SMART_HUMAN. Я был слишком умным и запутался, вложив в игру счетчик, в результате чего игрок проиграл ошибку, у меня также были ненужные строки. Полностью удалив вложенный кортеж SMART_HUMAN и просто добавив инструкцию elif для воспроизведения позиции 1 для противодействия счетчику.

Вот функция теперь, заключительный оператор for является рабочим решением. Там, наверное, лучшее решение, если оно было больше, более сложная игра, но для простой это работает: P

def computer_move(board, computer, human): 
"""Make computer move.""" 
# make a copy to work with since function will be changing list 
board = board[:] 
# the best positions to have, in order 
BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7) 

print("I shall take square number", end=" ") 

# if computer can win, take that move 
for move in legal_moves(board): 
    board[move] = computer 
    if winner(board) == computer: 
     print(move) 
     return move 
    # done checking this move, undo it 
    board[move] = EMPTY 

# if human can win, block that move 
for move in legal_moves(board): 
    board[move] = human 
    if winner(board) == human: 
     print(move) 
     return move 
    # done checkin this move, undo it 
    board[move] = EMPTY 

# since no one can win on next move, pick best open square 
for move in BEST_MOVES: 
    if move in legal_moves(board): 
     print(move) 
     return move 
#EXTENDED FOR CHALLENGE 4 CHAPTER 6 TO MAKE THE GAME UNBEATABLE 
    elif move not in legal_moves(board): 
     if BEST_MOVES[5] in legal_moves(board): 
      print (BEST_MOVES[5]) 
      return BEST_MOVES[5] 

Моя игра теперь непобедим :)

0

Проблема заключается здесь:

move = computer_move(board, computer, human) 

Если None возвращается (это означает, что компьютер не нашел каких-либо шагов), программа выходит с ошибкой в ​​следующей строке, потому что вам нужно предоставить целое число при извлечении элемента из списка, но вместо этого указывается None.

Существует либо ошибка в функции computer_move(), либо, что более вероятно, просто недостающая проверка для None - в последнем случае, когда компьютер не возвращает ход, вы должны закончить игру, объявив ничью.

+0

Я не думал о прекращении игры, когда ничья была единственным результатом. Я думаю, что попробую этот подход, спасибо! – Trumble

+0

Добро пожаловать. Кстати, можем ли мы теперь предположить, что ваш вопрос был достаточно отвечен? – plamut