wordgrid 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/wordgrid.rb +117 -31
  2. metadata +1 -1
data/lib/wordgrid.rb CHANGED
@@ -1,45 +1,38 @@
1
1
  require 'matrix'
2
2
 
3
- class Matrix
4
- def find_cells_for_letter(letter)
5
- cells = []
6
- each_with_index do |e, row, column|
7
- if (e == letter)
8
- cell = [row, column]
9
- cells.push(cell)
10
- end
11
- end
12
- return cells
13
- end
14
-
15
- # why doesn't matrix natively support this?!?
16
- def neighbor_cells(root_cell)
17
- row = root_cell[0]
18
- column = root_cell[1]
19
- cells = []
20
-
21
- cells.push([row-1, column-1]) if row-1 >= 0 and column-1 >= 0 #NW
22
- cells.push([row-1, column]) if row-1 >= 0 #N
23
- cells.push([row-1, column+1]) if row-1 >= 0 and column+1 < column_size #NE
24
- cells.push([row, column-1]) if column-1 >=0 #W
25
- cells.push([row, column+1]) if column+1 < column_size #E
26
- cells.push([row+1, column-1]) if row+1 < row_size and column-1 >= 0 #SW
27
- cells.push([row+1, column]) if row+1 < row_size #S
28
- cells.push([row+1, column+1]) if row+1 < row_size and column+1 < column_size #SE
29
-
30
- return cells
31
- end
32
- end
3
+ =begin
4
+ Wordgrid is useful for sucking the life out of games like Boggle or
5
+ Scramble with Friends. Given a matrix of letters, it provides a method
6
+ named has_word? which looks in the matrix for a requested word.
33
7
 
8
+ Paired with a driver script that iterates over a dictionary and checks
9
+ every single word to see if it matches, then you are provided with the
10
+ full list of words in the game. That would make the game a miserable
11
+ bore, but it was fun to write.
12
+ =end
34
13
  class Wordgrid
35
14
 
15
+ # Wordgrid.new can optionally be called with a Matrix object.
36
16
  def initialize(initial_grid=Matrix[])
37
17
  self.grid = initial_grid
38
18
  @cell_stack = []
39
19
  end
40
-
20
+
21
+ # Wordgrid.grid is the underlying matrix of letters.
41
22
  attr_reader :grid
42
23
 
24
+ =begin
25
+ grid takes a Matrix object and validates that it is acceptable.
26
+
27
+ * *Args* :
28
+ - +new_grid+ -> the proposed new Matrix object.
29
+ * *Returns* :
30
+ - the Matrix object itself.
31
+ * *Raises* : +ArgumentError+ in the following circumstances:
32
+ - any of the cells consist of something other than single letters
33
+ - the grid is not a square
34
+ =end
35
+
43
36
  def grid=(new_grid)
44
37
  # make sure each cell is a single letter character
45
38
  bad_cell = new_grid.find_index{|cell| cell.match(/^[^A-Za-z]$/) }
@@ -54,6 +47,24 @@ class Wordgrid
54
47
  @grid = new_grid
55
48
  end
56
49
 
50
+ =begin
51
+ has_word? is Wordgrid's raison d'être. It take a word and returns
52
+ true/false based on whether the word can be found in the grid.
53
+
54
+ has_word? makes sure not to re-trace its steps when looking for a word.
55
+ So, for example, it will find "BEAD" in the following grid, but it will
56
+ not find "BEADED":
57
+ A B C
58
+ D E F
59
+ G H I
60
+
61
+ * *Args* :
62
+ - +word+ -> the word to search the grid for
63
+ * *Returns* :
64
+ - +true+, if the word has been found, and +false+ otherwise
65
+ * *Raises* :
66
+ - Nothing
67
+ =end
57
68
  def has_word?(word)
58
69
  @letters = word.split('')
59
70
  first_cells = @grid.find_cells_for_letter(@letters[0])
@@ -70,6 +81,10 @@ class Wordgrid
70
81
  end
71
82
 
72
83
  =begin
84
+ find_next_letter_in_neighborhood calls itself recursively to look for
85
+ each letter in the word. One it finds the word, it stop the recursive
86
+ chain returning true. It follows the following plan:
87
+
73
88
  1. start with a cell
74
89
  2. look at all the neighbors of the cell for the next letter.
75
90
  if we don't find it, move back up to try a different path (if there were other matches a cell up)
@@ -107,4 +122,75 @@ a final stack for "BEAD" should be: [0,1], [1,1], [0,0], [1,0]
107
122
  @cell_stack.pop
108
123
  return false
109
124
  end
125
+ private :find_next_letter_in_neighborhood
110
126
  end
127
+
128
+ # Adding two helper functions to the standard Matrix class which are
129
+ # needed by the Wordgrid class.
130
+ class Matrix
131
+
132
+ =begin
133
+ Adds a method to the Matrix class which returns an array of cells
134
+ which match the string passed in. A cell is just an array with the
135
+ row and column.
136
+
137
+ * *Args* :
138
+ - +letter+ -> the character to search the matrix for.
139
+ * *Returns* :
140
+ - the cells which match the letter passed in. An array of two-value arrays.
141
+ * *Raises* :
142
+ - Nothing
143
+ =end
144
+
145
+ def find_cells_for_letter(letter)
146
+ cells = []
147
+ each_with_index do |e, row, column|
148
+ if (e == letter)
149
+ cell = [row, column]
150
+ cells.push(cell)
151
+ end
152
+ end
153
+ return cells
154
+ end
155
+
156
+ =begin
157
+ Adds a method to the Matrix class which will find all the cells which
158
+ border the cell requested
159
+
160
+ Neighbors are defined by the cells northwest, north, northeast, west,
161
+ east, southwest, south, and southeast of the original cell. If the
162
+ original cell is on the edge of the matrix, it does not wrap. In
163
+ other words, for the following matrix:
164
+ A B C
165
+ D E F
166
+ G H I
167
+ the cell containing the letter E has the neighbors A,B,C,D,F,G,H,I.
168
+ However, the cell containing the letter A only has the neighbors
169
+ B,D,E.
170
+
171
+ * *Args* :
172
+ - +root_cell+ -> a two-element array (row, cell) identifying the cell whose neighbors we are seeking.
173
+ * *Returns* :
174
+ - an array of cells (each cell is a two-element array, containing row and cell) neighboring the original cell.
175
+ * *Raises* :
176
+ - Nothing
177
+ =end
178
+
179
+ def neighbor_cells(root_cell)
180
+ row = root_cell[0]
181
+ column = root_cell[1]
182
+ cells = []
183
+
184
+ cells.push([row-1, column-1]) if row-1 >= 0 and column-1 >= 0 #NW
185
+ cells.push([row-1, column]) if row-1 >= 0 #N
186
+ cells.push([row-1, column+1]) if row-1 >= 0 and column+1 < column_size #NE
187
+ cells.push([row, column-1]) if column-1 >=0 #W
188
+ cells.push([row, column+1]) if column+1 < column_size #E
189
+ cells.push([row+1, column-1]) if row+1 < row_size and column-1 >= 0 #SW
190
+ cells.push([row+1, column]) if row+1 < row_size #S
191
+ cells.push([row+1, column+1]) if row+1 < row_size and column+1 < column_size #SE
192
+
193
+ return cells
194
+ end
195
+ end
196
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wordgrid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: