class AI
Attributes
best_move[RW]
Public Class Methods
create(game, type, computer)
click to toggle source
# File lib/ttt-cli/ai.rb, line 6 def self.create(game, type, computer) type.new(game, computer) end
new(game, computer)
click to toggle source
# File lib/ttt-cli/ai.rb, line 10 def initialize(game, computer) @game = game @board = game.board @computer = computer @enemy = @game.first_player @best_move = nil end
Public Instance Methods
move_generate()
click to toggle source
Метод для генерации хода AI
# File lib/ttt-cli/ai.rb, line 19 def move_generate; end
Private Instance Methods
is_first_move?()
click to toggle source
# File lib/ttt-cli/ai.rb, line 23 def is_first_move? @board.empty_cells.size == 9 || @board.empty_cells.size == 8 end
minimax(board, player, depth = 0, moves = {})
click to toggle source
основная минимакс-функция возвращает значение, если найдено конечное состояние(+10, 0, -10) проходит по всем пустым клеткам на поле вызывает минимакс функцию для каждой из них (рекурсия) оценивает полученные значения и возвращает наилучшее из них
# File lib/ttt-cli/ai.rb, line 34 def minimax(board, player, depth = 0, moves = {}) # копия доски new_board = board.dup # индексы свободных клеток empty_indices = new_board.empty_cells # проверка на терминальное состояние return 10 - depth if @game.won?(@computer) return -10 + depth if @game.won?(@enemy) return 0 if @game.draw? empty_indices.each do |index| new_board.fill_cell(index, player.token) next_player = opponent(player) moves[index] = minimax(new_board, next_player, depth + 1) new_board.reset_cell(index) end # возвращаем наилучшее значение minimax_score(moves, player) end
minimax_score(moves, player)
click to toggle source
метод для оценки полученных значений возвращает наилучшее значение
# File lib/ttt-cli/ai.rb, line 58 def minimax_score(moves, player) if player.token == @computer.token @best_move, best_score = moves.max_by { |_, v| v } else @best_move, best_score = moves.min_by { |_, v| v } end best_score end
opponent(player)
click to toggle source
метод для выбора оппонента для текущего игрока
# File lib/ttt-cli/ai.rb, line 69 def opponent(player) if player.token == @computer.token @enemy else @computer end end