Created
April 24, 2012 01:11
-
-
Save davidrobles/2475231 to your computer and use it in GitHub Desktop.
Ruby Tic-Tac-Toe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TicTacToe | |
WINS = ['000000111', '000111000', '111000000', | |
'001001001', '010010010', '100100100', | |
'100010001', '001010100'].map! {|x| x.to_i(2) } | |
attr_writer :crosses, :noughts | |
def initialize | |
reset | |
end | |
def check_win(bitboard) | |
WINS.any? {|win| win & bitboard == win } | |
end | |
def reset | |
@crosses = 0 | |
@noughts = 0 | |
end | |
def legal_bitboard | |
~(@crosses | @noughts) | |
end | |
def legal_moves | |
legal = legal_bitboard | |
9.times.find_all {|move| legal & (1 << move) > 0} | |
end | |
def bit_moves | |
legal_moves.map {|move| (1 << move)} | |
end | |
def to_s | |
str = "Legal moves: {legal_moves.inspect}\n" | |
str += "Game over: {over?}\n\n" | |
9.times do |i| | |
if @crosses & (1 << i) > 0 | |
str += ' X ' | |
elsif @noughts & (1 << i) > 0 | |
str += ' 0 ' | |
else | |
str += ' - ' | |
end | |
str += "\n" if i % 3 == 2 | |
end | |
str + "\n" | |
end | |
def set_cur_board(board) | |
if cur_player == 0 | |
@crosses = board | |
else | |
@noughts = board | |
end | |
end | |
def cur_board | |
cur_player == 0 ? @crosses : @noughts | |
end | |
# Game | |
def copy | |
tic = TicTacToe.new | |
tic.crosses = @crosses | |
tic.noughts = @noughts | |
tic | |
end | |
def cur_player | |
(bit_moves.length + 1) % 2 | |
end | |
def make_move(move) | |
bit_ms = bit_moves | |
raise 'Illegal move' if move < 0 or move >= bit_ms.length | |
set_cur_board(cur_board | bit_ms[move]) | |
end | |
def num_moves | |
bit_moves.length | |
end | |
def over? | |
check_win(@crosses) or check_win(@noughts) or bit_moves.empty? | |
end | |
def outcomes | |
if check_win(@crosses) | |
[:WIN, :LOSS] | |
elsif check_win(@noughts) | |
[:LOSS, :WIN] | |
else | |
[:NF, :NF] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment