wordgrid 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/wordgrid.rb +110 -0
- metadata +45 -0
data/lib/wordgrid.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'matrix'
|
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
|
33
|
+
|
34
|
+
class Wordgrid
|
35
|
+
|
36
|
+
def initialize(initial_grid=Matrix[])
|
37
|
+
self.grid = initial_grid
|
38
|
+
@cell_stack = []
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :grid
|
42
|
+
|
43
|
+
def grid=(new_grid)
|
44
|
+
# make sure each cell is a single letter character
|
45
|
+
bad_cell = new_grid.find_index{|cell| cell.match(/^[^A-Za-z]$/) }
|
46
|
+
if bad_cell
|
47
|
+
raise ArgumentError "Bad cell at " + bad_cell.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
unless new_grid.square?
|
51
|
+
raise ArgumentError "grid must be a square." # do I really care about this?
|
52
|
+
end
|
53
|
+
|
54
|
+
@grid = new_grid
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_word?(word)
|
58
|
+
@letters = word.split('')
|
59
|
+
first_cells = @grid.find_cells_for_letter(@letters[0])
|
60
|
+
|
61
|
+
@cell_stack = []
|
62
|
+
first_cells.each do |cell|
|
63
|
+
@cell_stack.push(cell)
|
64
|
+
if find_next_letter_in_neighborhood() == true
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
@cell_stack = []
|
68
|
+
end
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
|
72
|
+
=begin
|
73
|
+
1. start with a cell
|
74
|
+
2. look at all the neighbors of the cell for the next letter.
|
75
|
+
if we don't find it, move back up to try a different path (if there were other matches a cell up)
|
76
|
+
if we do find it
|
77
|
+
if we're at the end of the string, stop, and return true
|
78
|
+
if we aren't at the end of the string, goto 2 for the cell we found
|
79
|
+
|
80
|
+
along the way, build a stack of the path. So for the following grid:
|
81
|
+
A B C
|
82
|
+
D E F
|
83
|
+
G H I
|
84
|
+
a final stack for "BEAD" should be: [0,1], [1,1], [0,0], [1,0]
|
85
|
+
|
86
|
+
=end
|
87
|
+
def find_next_letter_in_neighborhood
|
88
|
+
if (@cell_stack.size == @letters.size)
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
neighbors = @grid.neighbor_cells(@cell_stack[-1])
|
92
|
+
current_letter = @letters[@cell_stack.size]
|
93
|
+
neighbors.each do |neighbor|
|
94
|
+
# don't retraverse nodes on the path we've taken thus far.
|
95
|
+
if @cell_stack.find { |cell| cell == neighbor }
|
96
|
+
next
|
97
|
+
end
|
98
|
+
|
99
|
+
neighbor_letter = @grid.element(neighbor[0], neighbor[1])
|
100
|
+
if neighbor_letter == current_letter
|
101
|
+
@cell_stack.push(neighbor)
|
102
|
+
if find_next_letter_in_neighborhood == true
|
103
|
+
return true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
@cell_stack.pop
|
108
|
+
return false
|
109
|
+
end
|
110
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wordgrid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Hansen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-02 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Visualizing and solving games like boggle, scramble with friends, etc
|
15
|
+
email: jonathansen@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/wordgrid.rb
|
21
|
+
homepage: https://github.com/jonathansen/wordgrid
|
22
|
+
licenses: []
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 1.8.22
|
42
|
+
signing_key:
|
43
|
+
specification_version: 3
|
44
|
+
summary: Wordgrid
|
45
|
+
test_files: []
|