Class: Rubykon::Board

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rubykon/board.rb

Constant Summary collapse

BLACK =
:black
WHITE =
:white
EMPTY =
nil
COLOR_TO_CHARACTER =
{BLACK => ' X', WHITE => ' O', EMPTY => ' .'}
CHARACTER_TO_COLOR =
COLOR_TO_CHARACTER.invert
LEGACY_CONVERSION =
{'X' => ' X', 'O' => ' O', '-' => ' .'}
CHARS_PER_GLYPH =
2
MAKE_IT_OUT_OF_BOUNDS =
1000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size, board = create_board(size)) ⇒ Board

weird constructor for dup



14
15
16
17
# File 'lib/rubykon/board.rb', line 14

def initialize(size, board = create_board(size))
  @size  = size
  @board = board
end

Instance Attribute Details

#boardObject (readonly)

Returns the value of attribute board.



11
12
13
# File 'lib/rubykon/board.rb', line 11

def board
  @board
end

#sizeObject (readonly)

Returns the value of attribute size.



11
12
13
# File 'lib/rubykon/board.rb', line 11

def size
  @size
end

Class Method Details

.convert(old_board_string) ⇒ Object



132
133
134
# File 'lib/rubykon/board.rb', line 132

def self.convert(old_board_string)
  old_board_string.gsub /[XO-]/, LEGACY_CONVERSION
end

.each_move_from(string) ⇒ Object



122
123
124
125
126
127
128
129
130
# File 'lib/rubykon/board.rb', line 122

def self.each_move_from(string)
  glyphs = string.tr("\n", '').chars.each_slice(CHARS_PER_GLYPH).map(&:join)
  relevant_glyphs = glyphs.select do |glyph|
    CHARACTER_TO_COLOR.has_key?(glyph)
  end
  relevant_glyphs.each_with_index do |glyph, index|
    yield index, CHARACTER_TO_COLOR.fetch(glyph)
  end
end

.from(string) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/rubykon/board.rb', line 114

def self.from(string)
  new_board = new(string.index("\n") / CHARS_PER_GLYPH)
  each_move_from(string) do |index, color|
    new_board[index] = color
  end
  new_board
end

Instance Method Details

#==(other_board) ⇒ Object



83
84
85
# File 'lib/rubykon/board.rb', line 83

def ==(other_board)
  board == other_board.board
end

#[](identifier) ⇒ Object



29
30
31
# File 'lib/rubykon/board.rb', line 29

def [](identifier)
  @board[identifier]
end

#[]=(identifier, color) ⇒ Object



33
34
35
# File 'lib/rubykon/board.rb', line 33

def []=(identifier, color)
  @board[identifier] = color
end

#cutting_point_countObject



25
26
27
# File 'lib/rubykon/board.rb', line 25

def cutting_point_count
  @board.size
end

#diagonal_colors_of(identifier) ⇒ Object



62
63
64
65
66
67
# File 'lib/rubykon/board.rb', line 62

def diagonal_colors_of(identifier)
  diagonal_coordinates(identifier).inject([]) do |res, n_identifier|
    res << self[n_identifier] if on_board?(n_identifier)
    res
  end
end

#dupObject



96
97
98
# File 'lib/rubykon/board.rb', line 96

def dup
  self.class.new @size, @board.dup
end

#eachObject



19
20
21
22
23
# File 'lib/rubykon/board.rb', line 19

def each
  @board.each_with_index do |color, identifier|
    yield identifier, color
  end
end

#identifier_for(x, y) ⇒ Object



102
103
104
105
106
# File 'lib/rubykon/board.rb', line 102

def identifier_for(x, y)
  return nil if x.nil? || y.nil?
  x = MAKE_IT_OUT_OF_BOUNDS if x > @size || x < 1
  (y - 1) * @size + (x - 1)
end

#neighbour_colors_of(identifier) ⇒ Object



58
59
60
# File 'lib/rubykon/board.rb', line 58

def neighbour_colors_of(identifier)
  neighbours_of(identifier).map {|identifier, color| color}
end

#neighbours_of(identifier) ⇒ Object

this method is rather raw and explicit, it gets called a lot



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rubykon/board.rb', line 38

def neighbours_of(identifier)
  x                        = identifier % size
  y                        = identifier / size
  right                    = identifier + 1
  below                    = identifier + @size
  left                     = identifier - 1
  above                    = identifier - @size
  board_edge               = @size - 1
  not_on_x_edge            = x > 0 && x < board_edge
  not_on_y_edge            = y > 0 && y < board_edge

  if not_on_x_edge && not_on_y_edge
    [[right, @board[right]], [below, @board[below]],
     [left, @board[left]], [above, @board[above]]]
  else
    handle_edge_cases(x, y, above, below, left, right, board_edge,
                      not_on_x_edge, not_on_y_edge)
  end
end

#on_board?(identifier) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/rubykon/board.rb', line 74

def on_board?(identifier)
  identifier >= 0 && identifier < @board.size
end

#on_edge?(identifier) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
72
# File 'lib/rubykon/board.rb', line 69

def on_edge?(identifier)
  x, y = x_y_from identifier
  x == 1 || x == size || y == 1 || y == size
end

#to_sObject



87
88
89
90
91
92
93
94
# File 'lib/rubykon/board.rb', line 87

def to_s
  @board.each_slice(@size).map do |row|
    row_chars = row.map do |color|
      COLOR_TO_CHARACTER.fetch(color)
    end
    row_chars.join
  end.join("\n") << "\n"
end

#x_y_from(identifier) ⇒ Object



108
109
110
111
112
# File 'lib/rubykon/board.rb', line 108

def x_y_from(identifier)
  x = (identifier % (@size)) + 1
  y = (identifier / (@size)) + 1
  [x, y]
end