Unfortunately, I've only done 1 extra credit thing (wildcard characters). I couldn't think of a good way of doing the snaking text without adding many more lines, so I didn't.
class Array
def positions(value)
positions = []
each_index { |i| positions << i if self[i] == value }
positions
end
end
class WordSearch
def initialize(wordSearch,*words)
@wordSearch = wordSearch
@rows = @wordSearch.split(/\s+/).delete_if { |row| row == "" }
@letters = @wordSearch.gsub(/\s+/,"").split(//)
@words = *words
@letterPositions = []
@rowLength = @rows[0].length
@numberOfRows = @rows.length
end
def solve
@words.each { |word|
@letters.positions(word[0].chr).each { |letterPos|
tooCloseToRight = (@rowLength - (letterPos % @rowLength)) < word.length
tooCloseToLeft = letterPos % @rowLength < word.length
tooCloseToTop = (letterPos / @rowLength) < word.length
tooCloseToBottom = (@numberOfRows - (letterPos / @rowLength).to_i) < word.length
search(word,letterPos,1) unless tooCloseToRight # to the right
search(word,letterPos,-1) unless tooCloseToLeft # to the left
search(word,letterPos,-(@rowLength - 1)) unless tooCloseToTop or tooCloseToRight # top right diagonal
search(word,letterPos,-(@rowLength)) unless tooCloseToTop # above
search(word,letterPos,-(@rowLength + 1)) unless tooCloseToTop or tooCloseToLeft # top left diagonal
search(word,letterPos,@rowLength + 1) unless tooCloseToBottom or tooCloseToRight # bottom right diagonal
search(word,letterPos,@rowLength) unless tooCloseToBottom # below
search(word,letterPos,@rowLength - 1) unless tooCloseToBottom or tooCloseToLeft # bottom left diagonal
}
}
end
def search(word,pos,direction)
positions = []
for i in (0...word.length)
positions << (pos + direction*i) if word[i].chr == @letters[pos + direction*i] or word[i].chr == "*" or @letters[pos + direction*i] == "*"
end
@letterPositions << positions if positions.length == word.length
end
def printWordSearch
@letterPositions.flatten!
@letters.each_index { |i|
character = @letterPositions.include?(i) ? @letters[i] : "+"
print character
if (i + 1) % @rows[0].length == 0
print "#{i/@rows[0].length + 1}".rjust(6)
puts
end
}
end
end
wordSearch = []
loop do
row = gets.chomp
wordSearch << row
break if row == ""
end
wordSearch.delete_at(-1)
words = gets.chomp.upcase.split(/\s*,\s*/)
w = WordSearch.new(wordSearch.join("\n"),words)
w.solve
w.printWordSearch
···
_________________________________________________________________
Find Singles In Your Area This Christmas With Match.com! msnuk.match.com