class AI
Constants
- IN_PROGRESS_SCORE
Attributes
current_player[RW]
Public Class Methods
new(game_rules)
click to toggle source
# File lib/ai.rb, line 5 def initialize(game_rules) @game_rules = game_rules end
Public Instance Methods
find_best_move(board, opponent_piece, game_piece)
click to toggle source
# File lib/ai.rb, line 11 def find_best_move(board, opponent_piece, game_piece) possible_moves = {} current_player = game_piece depth = 1 return 4 if empty?(board) open_spaces_on(board).each do |move| cloned_board = board.clone make_move(cloned_board, move, current_player) score = rank(cloned_board, depth, opponent_piece, game_piece) track_best(move, score, possible_moves) new_score = score_available_moves(board, depth + 1, next_player(current_player, opponent_piece, game_piece), score, opponent_piece, game_piece) if new_score > score score = new_score end board = reset(board, move) end best_move(possible_moves) end
open_spaces_on(board)
click to toggle source
# File lib/ai.rb, line 32 def open_spaces_on(board) board.size.times.select {|i| board[i] == nil} end
Private Instance Methods
best_move(possible_moves)
click to toggle source
# File lib/ai.rb, line 60 def best_move(possible_moves) best_score = possible_moves.values.max possible_moves.key(best_score) end
empty?(board)
click to toggle source
# File lib/ai.rb, line 38 def empty?(board) board.count(nil) == 9 end
make_move(board, move, current_player)
click to toggle source
# File lib/ai.rb, line 74 def make_move(board, move, current_player) board[move] = current_player board end
next_player(current_player, opponent_piece, game_piece)
click to toggle source
# File lib/ai.rb, line 65 def next_player(current_player, opponent_piece, game_piece) current_player == opponent_piece ? game_piece : opponent_piece end
rank(board, depth, opponent_piece, game_piece)
click to toggle source
# File lib/ai.rb, line 79 def rank(board, depth, opponent_piece, game_piece) if @game_rules.game_over?(board) return TIE - depth if @game_rules.tie?(board) return WIN - depth if @game_rules.winner(board) == game_piece return LOSS - depth if @game_rules.winner(board) == opponent_piece else return IN_PROGRESS_SCORE end end
reset(board, move)
click to toggle source
# File lib/ai.rb, line 69 def reset(board, move) board[move] = nil board end
score_available_moves(board, depth, current_player, score, opponent_piece, game_piece)
click to toggle source
# File lib/ai.rb, line 42 def score_available_moves(board, depth, current_player, score, opponent_piece, game_piece) return score if @game_rules.game_over?(board) open_spaces_on(board).each do |move| make_move(board, move, current_player) if current_player == opponent_piece score = score_available_moves(board, depth + 1, next_player(current_player, opponent_piece, game_piece), score, opponent_piece, game_piece) * -1 else score = score_available_moves(board, depth + 1, next_player(current_player, opponent_piece, game_piece), score, opponent_piece, game_piece) end board = reset(board, move) end return score end
track_best(move, score, possible_moves)
click to toggle source
# File lib/ai.rb, line 56 def track_best(move, score, possible_moves) possible_moves[move] = score end