wordgrid 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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: