class UnbeatableAiPlayer
Attributes
move_signature[R]
Public Class Methods
new(move_signature)
click to toggle source
# File lib/negamax_ttt/players/unbeatable_ai_player.rb, line 4 def initialize(move_signature) @move_signature = move_signature end
Public Instance Methods
get_move(rules)
click to toggle source
# File lib/negamax_ttt/players/unbeatable_ai_player.rb, line 8 def get_move(rules) opponent = get_opponent(rules.board) return 1 if opponent == :no_opponent_move top_score = -100.0 move_index = nil rules.board.open_spaces.each do |space| rules.board.place_move(space, move_signature) score = negamax(rules, false, opponent, 100, -100, 1) if score > top_score top_score = score move_index = space end rules.board.place_move(space, nil) end move_index end
get_opponent(board)
click to toggle source
# File lib/negamax_ttt/players/unbeatable_ai_player.rb, line 52 def get_opponent(board) opponent = board.board.values.select { |val| val != move_signature }.compact.sample || :no_opponent_move end
negamax(rules, my_turn, opponent, alpha, beta, depth)
click to toggle source
# File lib/negamax_ttt/players/unbeatable_ai_player.rb, line 28 def negamax(rules, my_turn, opponent, alpha, beta, depth) return score_board(rules, opponent) / depth if rules.game_over?(move_signature, opponent) rules.board.open_spaces.each do |space| my_turn ? rules.board.place_move(space, move_signature) : rules.board.place_move(space, opponent) score = -negamax(rules, !my_turn, opponent, -beta, -alpha, depth + 1) if score < alpha alpha = score end rules.board.place_move(space, nil) break if alpha <= beta end return alpha end
score_board(rules, opponent)
click to toggle source
# File lib/negamax_ttt/players/unbeatable_ai_player.rb, line 44 def score_board(rules, opponent) if rules.player_wins?(move_signature) || rules.player_wins?(opponent) 10.0 else 0.0 end end