131 lines
2.2 KiB
Ruby
131 lines
2.2 KiB
Ruby
|
# coding: utf-8
|
||
|
|
||
|
DEF = " "
|
||
|
PLAYS = [DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF]
|
||
|
SCENARIOS = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]
|
||
|
COM = "COM"
|
||
|
COM_VAL = " O "
|
||
|
PLAYER = "PLAYER"
|
||
|
GAME_DONE = false
|
||
|
PLAYER_VAL = " X "
|
||
|
|
||
|
|
||
|
class Array
|
||
|
def same_values?
|
||
|
self.uniq.length == 1
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def check_win board, player
|
||
|
cur_play = player == PLAYER ? PLAYER_VAL : COM_VAL
|
||
|
|
||
|
SCENARIOS.each do |s|
|
||
|
tmp = s.map {|i| board[i]}
|
||
|
# p board
|
||
|
if (not tmp.include? " ") and tmp.same_values? and tmp[0] == cur_play then
|
||
|
# p tmp
|
||
|
# p SCENARIOS
|
||
|
return true
|
||
|
else
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
def check_full board
|
||
|
if not board.include? " " then
|
||
|
return true
|
||
|
else
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
def draw_board board
|
||
|
return "
|
||
|
|#{board[0]}|#{board[1]}|#{board[2]}|
|
||
|
-------------
|
||
|
|#{board[3]}|#{board[4]}|#{board[5]}|
|
||
|
-------------
|
||
|
|#{board[6]}|#{board[7]}|#{board[8]}|
|
||
|
-------------"
|
||
|
end
|
||
|
|
||
|
def set player, idx
|
||
|
if player == PLAYER
|
||
|
PLAYS[idx] = PLAYER_VAL
|
||
|
elsif
|
||
|
PLAYS[idx] = COM_VAL
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
def ai_turn board, player, depth=0
|
||
|
if (check_win board, player == PLAYER ? COM : PLAYER) then
|
||
|
return -10 + depth
|
||
|
end
|
||
|
|
||
|
if check_full board then
|
||
|
return 0
|
||
|
end
|
||
|
|
||
|
max_seen = -(Float::INFINITY)
|
||
|
index = 0
|
||
|
value = player == PLAYER ? PLAYER_VAL : COM_VAL
|
||
|
|
||
|
(0...9).each do |x|
|
||
|
if board[x] == DEF then
|
||
|
new_board = board.dup
|
||
|
new_board[x] = value
|
||
|
lol = player == PLAYER ? COM : PLAYER
|
||
|
move_eval = -(ai_turn new_board, lol, depth+1)
|
||
|
|
||
|
if move_eval > max_seen then
|
||
|
# p [move_eval, x]
|
||
|
max_seen = move_eval
|
||
|
index = x
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
if depth == 0 then
|
||
|
set COM, index
|
||
|
end
|
||
|
return max_seen
|
||
|
end
|
||
|
|
||
|
|
||
|
def play_game
|
||
|
while true do
|
||
|
# system "clear"
|
||
|
|
||
|
# if (check_win PLAYS, PLAYER) == true then
|
||
|
# print "We have a winner!\n"
|
||
|
# break
|
||
|
# end
|
||
|
# if check_full board then
|
||
|
# print "Game over!\n"
|
||
|
# break
|
||
|
# end
|
||
|
|
||
|
print draw_board PLAYS
|
||
|
puts "\nPick one between 0-8"
|
||
|
choice = gets
|
||
|
|
||
|
if PLAYS[choice.to_i] != " " then
|
||
|
print "Space is already taken"
|
||
|
else
|
||
|
set PLAYER, choice.to_i
|
||
|
ai_turn PLAYS, COM
|
||
|
end
|
||
|
|
||
|
end
|
||
|
end
|
||
|
|
||
|
play_game
|