#ruby #algorithm #tic-tac-toe #minimax
#ruby #алгоритм #крестики-нолики #минимакс
Вопрос:
Я застрял на реализации минимаксного алгоритма для игры в крестики-нолики. Я продолжаю получать одну и ту же ошибку каждый раз (неопределенный метод `<‘ для nil:NilClass (NoMethodError)), но, похоже, не могу ее исправить.
Моя реализация заключается в следующем:
def minimax(current_board, current_player)
if user_won?(current_board)
return -10
elsif computer_won?(current_board)
return 10
elsif tie?(current_board)
return 0
end
available_squares = empty_squares(current_board)
moves = []
available_squares.each do |available_square|
move = {}
current_board[available_square] = COMPUTER_MARKER if current_player == 'computer'
current_board[available_square] = PLAYER_MARKER if current_player == 'player'
score = minimax(current_board, alternate_player(current_player))
current_board[available_square] = INITIAL_MARKER
move[available_square] = score
moves.push(move)
end
best_move = nil
best_score = current_player == 'computer' ? -Float::INFINITY : Float:: INFINITY
if current_player == 'computer'
for hsh in moves
hsh.each do |move, score|
if score > best_score
best_move = move
best_score = score
end
end
end
else
for hsh in moves
hsh.each do |move, score|
if score < best_score
best_move = move
best_score = score
end
end
end
end
best_move
end
Я застрял на этом в течение нескольких дней, поэтому буду признателен за любую помощь.
Вот остальная часть моего кода: https://github.com/YBirader/launch_school/blob/master/RB101/lesson_6/ttt.rb
Комментарии:
1. Похоже, что оценка определяется внутри цикла, available_squares . каждый — поэтому, если available_squares пуст, этот код никогда не будет запущен, и оценка не будет определена. Это могло бы вызвать эту ошибку.
2. оценка используется только внутри блока. Он добавляется к хэшу перемещения, который затем деструктивно добавляется к массиву перемещений, так что это не должно быть проблемой. Я добавил остальную часть своего кода, если это поможет.
Ответ №1:
Переменная score
должна быть определена вне цикла. Затем строка
if score > best_score
будет работать.
Комментарии:
1. Я пробовал это, но это все равно не работает. Я получаю ту же ошибку. Кроме того, каждый блок получает доступ к ключу оценки хэш-элементов ходов, поэтому мне не нужно определять оценку перед циклом for.
2. Чтобы проверить, является ли это проблемой, попробуйте добавить ‘score = 0’ перед ‘available_squares.each’.
Ответ №2:
Я только что прошел и отладил это.
Оказывается, что минимаксный метод иногда возвращает nil, который затем помещается в хэш ходов в строке 94, поскольку он не может сравнить nil с любым числом, >
или <
это выдает ошибку, и мы не можем продолжить.
Вам просто нужно добавить резервный вариант к 0, когда результат равен нулю, измените строку 91 на это:
minimax(current_board, alternate_player(current_player)) || 0
Вам также не нужно определять score
вне цикла, поскольку эта переменная используется только для добавления ее в хэш в строке 94. Что я пропустил ранее, так это то, что оценка снова определяется в each
цикле.
Комментарии:
1. Но это ошибка, если минимакс возвращает 0?
2. да. Хотя он устраняет ошибку, функция минимакса больше не работает, т.Е. логика теперь неправильная.