* Ruby Quiz <james / grayproductions.net> [0123 14:23]:
Thanks, had fun with that. Sounded easy at first read but had
me stumped several times last night.
Got a slightly hacky version, but hopefully shortish version.
Largely based on Exception abuse :)
Tricky bit was figuring out the tree updating - knocking together
a quick tree and getting the traversal right helped a lot there.
The updating bit wrote itself after that.
I'm sure there's a more rubyish way of switching the node from
'animal mode' to 'question mode', but it seems to avoid a lot of
book-keeping and linked-list-esque linking and unlinking of references,
so it'll do...
It's fairly short so here you go:
--------------------------------8<-----------------------------------
#!/usr/bin/env ruby
class TreeNode
attr_accessor :yes, :no, :question, :animal
def initialize(animal=nil)
@animal = animal
@question = @no = @yes = nil
end
def walk
begin
return (prompt(question) ? yes.walk : no.walk)
rescue NoMethodError
# yes, no or question was nil. Make a guess.
if ( prompt "I think I am a #{animal}. Am I?")
puts "Yay! Let's start again."
else
update_tree
end
end
end
def update_tree
puts "OK, I give up. What am i?"
new_animal = gets.chomp.intern
puts "Give me a question which is true for #{new_animal} and false for #{animal}"
new_question = gets.chomp
# become a decision branch and connect our forks
@no = TreeNode.new(animal)
@yes = TreeNode.new(new_animal)
@animal = nil
@question = new_question
puts "Duly noted. Let's try again:"
end
def prompt(str)
# no question to ask, so punt
raise NoMethodError unless str
puts "#{str} ( q/Q to quit) :"
response = gets
exit if response =~ /q.*/i
return true if response =~ /y.*/i
false
end
end
top = TreeNode.new(:elephant)
loop { top.walk }
--------------------------------8<-----------------------------------
--
'Good news, everyone! I've taught the toaster to feel love!'
-- Prof. Farnsworth
Rasputin :: Jack of All Trades - Master of Nuns