class RubyTictactoe::AI
Constants
- LOSE
- NEG_INF
- POS_INF
- TIE
- WIN
Attributes
current_player[R]
Public Class Methods
new(player)
click to toggle source
# File lib/ai.rb, line 10 def initialize(player) @current_player = player end
Public Instance Methods
computer_move(board, player)
click to toggle source
# File lib/ai.rb, line 14 def computer_move(board, player) test_board = board.dup test_board.all_cells = board.all_cells.dup get_best_move(test_board, player) end
get_best_move(board, player)
click to toggle source
# File lib/ai.rb, line 20 def get_best_move(board, player) ranked_moves = rank_possible_moves(board, player) move = ranked_moves.max_by {|cell, score| score} move.first end
Private Instance Methods
alphabeta(board, player, depth, alpha, beta)
click to toggle source
# File lib/ai.rb, line 59 def alphabeta(board, player, depth, alpha, beta) board.open_cells.each_key do |cell| player.opponent.add_marker(board, cell) score = (apply_minimax(board, player.opponent, cell, depth += 1, alpha, beta) / depth.to_f) alpha = player.get_alpha(alpha, score) beta = player.get_beta(beta, score) board.remove_marker(cell) break if alpha >= beta end player.return_best_score(alpha, beta) end
apply_minimax(board, player, cell, depth, alpha, beta)
click to toggle source
# File lib/ai.rb, line 48 def apply_minimax(board, player, cell, depth, alpha, beta) return get_score(board, player) if board.game_over? if (player == current_player) maximizing_player = MaximizingPlayer.new(player) alphabeta(board, maximizing_player, depth, alpha, beta) else minimizing_player = MinimizingPlayer.new(player) alphabeta(board, minimizing_player, depth, alpha, beta) end end
get_move_score(board, player, cell)
click to toggle source
# File lib/ai.rb, line 35 def get_move_score(board, player, cell) player.add_marker(board, cell) best_score = apply_minimax(board, player, cell, depth=0, NEG_INF, POS_INF) board.remove_marker(cell) best_score end
get_score(board, player)
click to toggle source
# File lib/ai.rb, line 42 def get_score(board, player) return WIN if board.winner?(player.marker) && (player == current_player) return LOSE if board.winner?(player.marker) TIE end
rank_possible_moves(board, player)
click to toggle source
# File lib/ai.rb, line 28 def rank_possible_moves(board, player) possible_moves = board.open_cells possible_moves.each_key do |cell| possible_moves[cell] = get_move_score(board, player, cell) end end