68 lines
1.3 KiB
Ruby
68 lines
1.3 KiB
Ruby
class Bot
|
|
|
|
attr_reader :best_choice
|
|
|
|
def initialize board, piece
|
|
@piece = piece
|
|
@opponent = switch piece
|
|
end
|
|
|
|
def move board
|
|
return "Game is done!" if board.is_full?
|
|
return "Someone won!" if board.any_winner?
|
|
# move = @board.get_free.sample
|
|
# @board.set " O ", move
|
|
minmax board, @piece
|
|
board.set @piece, @best_choice
|
|
end
|
|
|
|
|
|
def minmax board, cur_player
|
|
return score(board) if game_done?(board)
|
|
|
|
scores = {}
|
|
|
|
board.get_free.each do |space|
|
|
# Copy board so we don't mess up original
|
|
potential_board = board.dup
|
|
potential_board.set cur_player, space
|
|
|
|
|
|
scores[space] = minmax(potential_board, switch(cur_player))
|
|
potential_board.remove space
|
|
end
|
|
|
|
@best_choice, best_score = best_choice cur_player, scores
|
|
best_score
|
|
end
|
|
|
|
def switch cur
|
|
cur == " X " ? " O " : " X "
|
|
end
|
|
|
|
def game_done? board
|
|
board.any_winner? || board.is_full?
|
|
end
|
|
|
|
def best_choice piece, scores
|
|
if piece == @piece then
|
|
#p scores
|
|
scores.max_by { |_k, v| v}
|
|
else
|
|
scores.min_by { |_k, v| v}
|
|
end
|
|
end
|
|
|
|
def score board
|
|
#p @piece
|
|
#p @opponent
|
|
if board.is_winner? @piece
|
|
return 10
|
|
elsif board.is_winner? @opponent
|
|
return -10
|
|
end
|
|
0
|
|
end
|
|
|
|
end
|