class AiPlayer
Constants
- ALPHA
- BETA
Public Class Methods
new(symbol)
click to toggle source
Calls superclass method
Player::new
# File lib/ai_player.rb, line 7 def initialize(symbol) super(symbol) end
Public Instance Methods
choose_move(board)
click to toggle source
# File lib/ai_player.rb, line 11 def choose_move(board) minimax(board, true, board.vacant_indices.size, ALPHA, BETA).first[1] end
minimax(board, is_max_player, depth, alpha, beta)
click to toggle source
# File lib/ai_player.rb, line 19 def minimax(board, is_max_player, depth, alpha, beta) best_score_so_far = initial_score(is_max_player) if round_is_over(board, depth) return score(board, depth) end board.vacant_indices.each do |i| new_board = board.make_move(i, current_players_symbol(is_max_player)) result = minimax(new_board, !is_max_player, depth - 1, alpha, beta) best_score_so_far = update_score(is_max_player, i, best_score_so_far, score_from(result)) alpha = update_alpha(is_max_player, best_score_so_far, alpha) beta = update_beta(is_max_player, best_score_so_far, beta) if alpha > beta break end end best_score_so_far end
ready?()
click to toggle source
# File lib/ai_player.rb, line 15 def ready? true end
Private Instance Methods
current_players_symbol(is_max_player)
click to toggle source
# File lib/ai_player.rb, line 105 def current_players_symbol(is_max_player) is_max_player == true ? game_symbol : PlayerSymbols::opponent(game_symbol) end
initial_score(is_max_player)
click to toggle source
# File lib/ai_player.rb, line 97 def initial_score(is_max_player) if is_max_player best_score_so_far = {ALPHA => nil} else best_score_so_far = {BETA => nil} end end
maximizing_player_won?(winners_symbol)
click to toggle source
# File lib/ai_player.rb, line 85 def maximizing_player_won?(winners_symbol) symbols_are_equal?(winners_symbol, game_symbol) end
minimizing_player_won?(winners_symbol)
click to toggle source
# File lib/ai_player.rb, line 89 def minimizing_player_won?(winners_symbol) symbols_are_equal?(winners_symbol, PlayerSymbols::opponent(game_symbol)) end
round_is_over(board, depth)
click to toggle source
# File lib/ai_player.rb, line 66 def round_is_over(board, depth) @winner = board.winning_symbol !@winner.nil? || depth == 0 end
score(board, depth)
click to toggle source
# File lib/ai_player.rb, line 71 def score(board, depth) if @winner.nil? return {0 => nil} end if maximizing_player_won?(@winner) return {(1 + depth) => nil} end if minimizing_player_won?(@winner) return {(-1 - depth) => nil} end end
score_from(score)
click to toggle source
# File lib/ai_player.rb, line 55 def score_from(score) score.first.first end
symbols_are_equal?(symbol1, symbol2)
click to toggle source
# File lib/ai_player.rb, line 93 def symbols_are_equal?(symbol1, symbol2) symbol1 == symbol2 end
update_alpha(is_max_player, best_score_so_far, alpha)
click to toggle source
# File lib/ai_player.rb, line 48 def update_alpha(is_max_player, best_score_so_far, alpha) if is_max_player && score_from(best_score_so_far) > alpha alpha = score_from(best_score_so_far) end alpha end
update_beta(is_max_player, best_score_so_far, beta)
click to toggle source
# File lib/ai_player.rb, line 59 def update_beta(is_max_player, best_score_so_far, beta) if !is_max_player && score_from(best_score_so_far) < beta beta = score_from(best_score_so_far) end beta end
update_score(is_max_player, move, score, result_score)
click to toggle source
# File lib/ai_player.rb, line 109 def update_score(is_max_player, move, score, result_score) if is_max_player && (result_score >= score_from(score)) return {result_score => move} elsif !is_max_player && (result_score < score_from(score)) return {result_score => move} end return score end