require 'matrix'
class Board
def initialize(pc_turn)
@board_matrix = Matrix.build(3,3){0}
@identity = Matrix.identity(3)
@permutation_matrix = Matrix.rows(@identity.to_a.reverse)
@row_vec = Matrix.row_vector([1,1,1])
@markers = { 1 => "X", 0 => " ", -1 => "O" }
@pc_turn = pc_turn
end
def move(x,y)
return false if @board_matrix[x,y] != 0
tmp = @board_matrix.to_a
tmp[x][y] = pc_turn ? -1 : 1
@board_matrix = Matrix[tmp]
@pc_turn != @pc_turn
true
end
def win
# fancy matrix stuff 1 player wins, 0 draw, -1 pc wins
[@identity.column_vectors.map{ |vec| (@row_vec * @board_matrix * vec)[0]}.max_by{ |n| n.abs },
@identity.column_vectors.map{ |vec| (@row_vec * @board_matrix.t * vec)[0]}.max_by{ |n| n.abs },
@board_matrix.tr, (@permutation_matrix * @board_matrix).tr].max_by{ |n| n.abs} / 3
end
def to_str()
"+---+---+---+\n"+
@board_matrix.to_a.map do |row|
"| %s | %s | %s |\n+---+---+---+\n" % row.map{ |val| @markers[val]}
end.join
end
end
cmVxdWlyZSAnbWF0cml4JwoKY2xhc3MgQm9hcmQKICBkZWYgaW5pdGlhbGl6ZShwY190dXJuKQogICAgQGJvYXJkX21hdHJpeCA9IE1hdHJpeC5idWlsZCgzLDMpezB9CiAgICBAaWRlbnRpdHkgPSBNYXRyaXguaWRlbnRpdHkoMykKICAgIEBwZXJtdXRhdGlvbl9tYXRyaXggPSBNYXRyaXgucm93cyhAaWRlbnRpdHkudG9fYS5yZXZlcnNlKQogICAgQHJvd192ZWMgPSBNYXRyaXgucm93X3ZlY3RvcihbMSwxLDFdKQogICAgQG1hcmtlcnMgPSB7IDEgPT4gIlgiLCAwID0+ICIgIiwgLTEgPT4gIk8iIH0KICAgIEBwY190dXJuID0gcGNfdHVybgogIGVuZAogIGRlZiBtb3ZlKHgseSkKICAgIHJldHVybiBmYWxzZSBpZiBAYm9hcmRfbWF0cml4W3gseV0gIT0gMAogICAgdG1wID0gQGJvYXJkX21hdHJpeC50b19hCiAgICB0bXBbeF1beV0gPSBwY190dXJuID8gLTEgOiAxCiAgICBAYm9hcmRfbWF0cml4ID0gTWF0cml4W3RtcF0KICAgIEBwY190dXJuICE9IEBwY190dXJuCiAgICB0cnVlCiAgZW5kCiAgZGVmIHdpbgogICAgIyBmYW5jeSBtYXRyaXggc3R1ZmYgMSBwbGF5ZXIgd2lucywgMCBkcmF3LCAtMSBwYyB3aW5zCiAgICBbQGlkZW50aXR5LmNvbHVtbl92ZWN0b3JzLm1hcHsgfHZlY3wgKEByb3dfdmVjICogQGJvYXJkX21hdHJpeCAqIHZlYylbMF19Lm1heF9ieXsgfG58IG4uYWJzIH0sCiAgICAgQGlkZW50aXR5LmNvbHVtbl92ZWN0b3JzLm1hcHsgfHZlY3wgKEByb3dfdmVjICogQGJvYXJkX21hdHJpeC50ICogdmVjKVswXX0ubWF4X2J5eyB8bnwgbi5hYnMgfSwKICAgICBAYm9hcmRfbWF0cml4LnRyLCAoQHBlcm11dGF0aW9uX21hdHJpeCAqIEBib2FyZF9tYXRyaXgpLnRyXS5tYXhfYnl7IHxufCBuLmFic30gLyAzCiAgZW5kCiAgZGVmIHRvX3N0cigpCiAgICAiKy0tLSstLS0rLS0tK1xuIisKICAgIEBib2FyZF9tYXRyaXgudG9fYS5tYXAgZG8gfHJvd3wKICAgICAgInwgJXMgfCAlcyB8ICVzIHxcbistLS0rLS0tKy0tLStcbiIgJSByb3cubWFweyB8dmFsfCAgQG1hcmtlcnNbdmFsXX0KICAgIGVuZC5qb2luCiAgZW5kCmVuZAo=