class RubyGo::Game

Attributes

board[R]
moves[R]

Public Class Methods

new(board: 19) click to toggle source
# File lib/ruby-go/game.rb, line 5
def initialize(board: 19)
  @board = Board.new(board)
  @moves = Moves.new
end

Public Instance Methods

black_pass() click to toggle source
# File lib/ruby-go/game.rb, line 35
def black_pass
  pass(:black)
end
captures() click to toggle source
# File lib/ruby-go/game.rb, line 56
def captures
  moves.capture_count
end
passes() click to toggle source
# File lib/ruby-go/game.rb, line 52
def passes
  moves.pass_count
end
place_black(x, y) click to toggle source
# File lib/ruby-go/game.rb, line 27
def place_black(x, y)
  play(Stone.new(x, y, :black))
end
place_white(x, y) click to toggle source
# File lib/ruby-go/game.rb, line 31
def place_white(x, y)
  play(Stone.new(x, y, :white))
end
save(name="my_go_game") click to toggle source
# File lib/ruby-go/game.rb, line 12
def save(name="my_go_game")
  tree = SGF::Parser.new.parse(to_sgf)
  tree.save(name + '.sgf')
end
to_sgf() click to toggle source
# File lib/ruby-go/game.rb, line 17
def to_sgf
  sgf = "(;GM[1]FF[4]CA[UTF-8]AP[jphager2]SZ[#{board.size}]PW[White]PB[Black]"

  moves.each do |move|
    sgf << move.played.to_sgf
  end

  sgf << ')'
end
undo() click to toggle source
# File lib/ruby-go/game.rb, line 43
def undo
  move = moves.pop

  board.remove(move.played)
  move.captures.each do |stone|
    board.place(stone)
  end
end
white_pass() click to toggle source
# File lib/ruby-go/game.rb, line 39
def white_pass
  pass(:white)
end

Private Instance Methods

capture_stone(stone) click to toggle source
# File lib/ruby-go/game.rb, line 127
def capture_stone(stone)
  moves.capture(stone)
  board.remove(stone)
end
check_illegal_ko!(stone) click to toggle source
# File lib/ruby-go/game.rb, line 97
def check_illegal_ko!(stone)
  last_move = moves.prev

  return unless last_move

  if last_move.captures == [stone] && moves.current.captures.one?
    undo
    raise IllegalMove,
      "You cannot capture the ko, play a ko threat first"
  end
end
check_illegal_placement!(stone) click to toggle source
# File lib/ruby-go/game.rb, line 77
def check_illegal_placement!(stone)
  coord = stone.to_coord

  if coord.any? { |i| i < 0 || i >= board.size }
    raise(
      Game::IllegalMove,
      "You cannot place a stone off the board."
    )
  end

  intersection = board.at(*coord)

  unless intersection.empty?
    raise(
      Game::IllegalMove,
      "You cannot place a stone on top of another stone."
    )
  end
end
check_illegal_suicide!(stone) click to toggle source
# File lib/ruby-go/game.rb, line 109
def check_illegal_suicide!(stone)
  if board.liberties(stone).zero?
    undo
    raise IllegalMove, "You cannot play a suicide."
  end
end
pass(color) click to toggle source
# File lib/ruby-go/game.rb, line 62
def pass(color)
  moves.pass(NullStone.new(color))
end
play(stone) click to toggle source
# File lib/ruby-go/game.rb, line 66
def play(stone)
  check_illegal_placement!(stone)

  board.place(stone)
  moves.play(stone)
  record_captures!(stone)

  check_illegal_suicide!(stone)
  check_illegal_ko!(stone)
end
record_captures!(stone) click to toggle source
# File lib/ruby-go/game.rb, line 116
def record_captures!(stone)
  stones_around = board.around(*stone.to_coord).reject(&:empty?)

  captures = stones_around
               .reject {| stn| stn.color == stone.color }
               .select { |stn| @board.liberties(stn).zero? }

  captures.map {|stone| @board.group_of(stone)}
    .flatten.uniq.each {|stone| capture_stone(stone)}
end