class Rubykon::GroupTracker

Attributes

groups[R]
stone_to_group[R]

Public Class Methods

new(groups = {}, stone_to_group = {}) click to toggle source
# File lib/rubykon/group_tracker.rb, line 6
def initialize(groups = {}, stone_to_group = {})
  @groups         = groups
  @stone_to_group = stone_to_group
end

Public Instance Methods

assign(identifier, color, board) click to toggle source
# File lib/rubykon/group_tracker.rb, line 11
def assign(identifier, color, board)
  neighbours_by_color = color_to_neighbour(board, identifier)
  join_group_of_friendly_stones(neighbours_by_color[color], identifier)
  create_own_group(identifier) unless group_id_of(identifier)
  add_liberties(neighbours_by_color[Board::EMPTY], identifier)
  take_liberties_of_enemies(neighbours_by_color[Game.other_color(color)], identifier, board, color)
end
dup() click to toggle source
# File lib/rubykon/group_tracker.rb, line 39
def dup
  self.class.new(dup_groups, @stone_to_group.dup)
end
group(id) click to toggle source
# File lib/rubykon/group_tracker.rb, line 31
def group(id)
  @groups[id]
end
group_id_of(identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 23
def group_id_of(identifier)
  @stone_to_group[identifier]
end
group_of(identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 27
def group_of(identifier)
  group(group_id_of(identifier))
end
liberty_count_at(identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 19
def liberty_count_at(identifier)
  group_of(identifier).liberty_count
end
stone_joins_group(stone_identifier, group_identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 35
def stone_joins_group(stone_identifier, group_identifier)
  @stone_to_group[stone_identifier] = group_identifier
end

Private Instance Methods

add_liberties(liberties, identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 116
def add_liberties(liberties, identifier)
  liberties.each do |liberty_identifier|
    group_of(identifier).add_liberty(liberty_identifier)
  end
end
collect_captured_groups(caught, enemy_group) click to toggle source
# File lib/rubykon/group_tracker.rb, line 71
def collect_captured_groups(caught, enemy_group)
  if enemy_group.caught? && !caught.include?(enemy_group)
    caught << enemy_group
  end
  caught
end
color_to_neighbour(board, identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 44
def color_to_neighbour(board, identifier)
  neighbors = board.neighbours_of(identifier)
  hash = neighbors.inject({}) do |hash, (n_identifier, color)|
    (hash[color] ||= []) << n_identifier
    hash
  end
  hash.default = []
  hash
end
create_own_group(identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 129
def create_own_group(identifier)
  # we can use the identifier of the stone, as it should not be taken
  # (it may have been taken before, but for that stone to be played the
  # other group would have had to be captured before)
  @groups[identifier] = Group.new(identifier)
  @stone_to_group[identifier] = identifier
end
delete_group(enemy_group) click to toggle source
# File lib/rubykon/group_tracker.rb, line 100
def delete_group(enemy_group)
  @groups.delete(enemy_group.identifier)
end
dup_groups() click to toggle source
# File lib/rubykon/group_tracker.rb, line 137
def dup_groups
  @groups.inject({}) do |dupped, (key, group)|
    dupped[key] = group.dup
    dupped
  end
end
join_group_of_friendly_stones(friendly_stones, identifier) click to toggle source
# File lib/rubykon/group_tracker.rb, line 122
def join_group_of_friendly_stones(friendly_stones, identifier)
  friendly_stones.each do |f_identifier, _color|
    friendly_group = group_of(f_identifier)
    friendly_group.connect identifier, group_of(identifier), self
  end
end
neighboring_groups_of(enemy_group) click to toggle source
# File lib/rubykon/group_tracker.rb, line 110
def neighboring_groups_of(enemy_group)
  enemy_group.liberties.map do |identifier, _|
    group_of(identifier)
  end.compact.uniq
end
regain_liberties_from_capture(enemy_group) click to toggle source
# File lib/rubykon/group_tracker.rb, line 104
def regain_liberties_from_capture(enemy_group)
  neighboring_groups_of(enemy_group).each do |neighbor_group|
    neighbor_group.gain_liberties_from_capture_of(enemy_group, self)
  end
end
remove(enemy_group, board) click to toggle source
# File lib/rubykon/group_tracker.rb, line 85
def remove(enemy_group, board)
  regain_liberties_from_capture(enemy_group)
  delete_group(enemy_group)
  remove_captured_stones(board, enemy_group)
end
remove_captured_stones(board, enemy_group) click to toggle source
# File lib/rubykon/group_tracker.rb, line 91
def remove_captured_stones(board, enemy_group)
  captured_stones = enemy_group.stones
  captured_stones.each do |identifier|
    @stone_to_group.delete identifier
    board[identifier] = Board::EMPTY
  end
  captured_stones
end
remove_caught_groups(board, capturer_color, caught) click to toggle source
# File lib/rubykon/group_tracker.rb, line 78
def remove_caught_groups(board, capturer_color, caught)
  captures = caught.inject([]) do |captures, enemy_group|
    captures + remove(enemy_group, board)
  end
  captures
end
remove_liberties(enemy_identifier, enemy_group, identifier, my_group) click to toggle source
# File lib/rubykon/group_tracker.rb, line 64
def remove_liberties(enemy_identifier, enemy_group, identifier, my_group)
  enemy_group.remove_liberty(identifier)
  # this needs to be the identifier and not the group, as groups
  # might get merged
  my_group.add_enemy_group_at(enemy_identifier)
end
take_liberties_of_enemies(enemy_neighbours, identifier, board, capturer_color) click to toggle source
# File lib/rubykon/group_tracker.rb, line 54
def take_liberties_of_enemies(enemy_neighbours, identifier, board, capturer_color)
  my_group = group_of(identifier)
  captures = enemy_neighbours.inject([]) do |caught, enemy_identifier|
    enemy_group = group_of(enemy_identifier)
    remove_liberties(enemy_identifier, enemy_group, identifier, my_group)
    collect_captured_groups(caught, enemy_group)
  end
  remove_caught_groups(board, capturer_color, captures)
end