Class: XO::Grid

Inherits:
Object
  • Object
show all
Defined in:
lib/xo/grid.rb

Overview

A data structure for storing X‘s and O’s in a 3x3 grid.

The grid is structured as follows:

     column
    1   2   3
row
 1    |   |
   ---+---+---
 2    |   |
   ---+---+---
 3    |   |

Direct Known Subclasses

AI::GeometricGrid

Constant Summary collapse

X =
:x
O =
:o
EMPTY =
:e
ROWS =
3
COLS =
3
N =
ROWS * COLS

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(g = '') ⇒ Grid

Returns a new instance of Grid.



39
40
41
# File 'lib/xo/grid.rb', line 39

def initialize(g = '')
  @grid = from_string(g)
end

Class Method Details

.contains?(r, c) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/xo/grid.rb', line 27

def self.contains?(r, c)
  r.between?(1, ROWS) && c.between?(1, COLS)
end

.is_token?(k) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/xo/grid.rb', line 31

def self.is_token?(k)
  k == X || k == O
end

.other_token(k) ⇒ Object



35
36
37
# File 'lib/xo/grid.rb', line 35

def self.other_token(k)
  k == X ? O : (k == O ? X : k)
end

Instance Method Details

#[](r, c) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/xo/grid.rb', line 63

def [](r, c)
  if self.class.contains?(r, c)
    grid[idx(r, c)]
  else
    raise IndexError, "position (#{r}, #{c}) is off the grid"
  end
end

#[]=(r, c, k) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/xo/grid.rb', line 55

def []=(r, c, k)
  if self.class.contains?(r, c)
    grid[idx(r, c)] = normalize(k)
  else
    raise IndexError, "position (#{r}, #{c}) is off the grid"
  end
end

#clearObject



75
76
77
# File 'lib/xo/grid.rb', line 75

def clear
  grid.fill(EMPTY)
end

#eachObject

Iterates over all the positions of this grid from left to right and top to bottom.

Examples:

g = Grid.new
g.each do |r, c, k|
  puts "(#{r}, #{c}) -> #{k}"
end


86
87
88
89
90
91
92
# File 'lib/xo/grid.rb', line 86

def each
  (1..ROWS).each do |r|
    (1..COLS).each do |c|
      yield(r, c, self[r, c])
    end
  end
end

#each_openObject

Iterates over all the open positions of this grid from left to right and top to bottom.

Examples:

g = Grid.new

g[1, 1] = g[2, 1] = Grid::X
g[2, 2] = g[3, 1] = Grid::O

g.each_open do |r, c|
  puts "(#{r}, #{c}) is open"
end


105
106
107
# File 'lib/xo/grid.rb', line 105

def each_open
  self.each { |r, c, _| yield(r, c) if open?(r, c) }
end

#empty?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/xo/grid.rb', line 47

def empty?
  grid.all? { |k| !self.class.is_token?(k) }
end

#full?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/xo/grid.rb', line 51

def full?
  grid.all? { |k| self.class.is_token?(k) }
end

#initialize_copy(orig) ⇒ Object



43
44
45
# File 'lib/xo/grid.rb', line 43

def initialize_copy(orig)
  @grid = orig.instance_variable_get(:@grid).dup
end

#inspectObject

Returns a string representation of this grid which can be useful for debugging.



110
111
112
# File 'lib/xo/grid.rb', line 110

def inspect
  grid.map { |k| t(k) }.join
end

#open?(r, c) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/xo/grid.rb', line 71

def open?(r, c)
  !self.class.is_token?(self[r, c])
end

#to_sObject

Returns a string representation of this grid which can be useful for display.



115
116
117
118
119
120
121
122
123
# File 'lib/xo/grid.rb', line 115

def to_s
  g = grid.map { |k| t(k) }

  [" #{g[0]} | #{g[1]} | #{g[2]} ",
   "---+---+---",
   " #{g[3]} | #{g[4]} | #{g[5]} ",
   "---+---+---",
   " #{g[6]} | #{g[7]} | #{g[8]} "].join("\n")
end