--------------060403060801050107090001
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Not to toot my own horn, but this was an easy one. I spent more time
polishing and commenting than I did on actual coding. Viva la Ruby!
--
Glenn Parker | glenn.parker-AT-comcast.net | <http://www.tetrafoil.com/>
--------------060403060801050107090001
Content-Type: text/plain;
name
nimal.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename
nimal.rb"
#!/usr/bin/env ruby -w
STDOUT.sync rue
# $qtree is the root of a tree where non-leaf nodes are 3-element arrays.
# The first element of a non-leaf node is a question. The second
# and third elements are nodes. The second element corresponds
# to a "yes" answer for the question, and the third element corresponds
# to a "no" answer for the question. A leaf node is a 1-element array
# that contains an animal name. The initial node for $qtree is a leaf
# node for the animal "human".
$qtree "human" ]
# $current_node, $parent_node, and $parent_branch maintain our current
# position while navigating down the tree. Except when $parent_node
# is nil, $parent_node[$parent_branch] $current_node.
$current_node parent_node parent_branch il
def main
$log ile.open("animal-log.txt", "a+")
# Replay all previous sessions from the logfile to initialize $qtree.
read_from($log) until $log.eof
# Play interactively.
read_from(STDIN)
$log.close
end
def read_from(i)
$istream
$replay $istream ! TDIN)
loop do
prompt "Would you like to play a game? "
if get_answer.downcase[0] ?y
prompt "Please think of an animal...\n\n"
play
else
prompt "Good bye.\n"
break
end
end
end
# Print a prompt unless we are in replay mode.
def prompt(str)
print str unless $replay
end
# Get an answer and log it unless we are in replay mode.
def get_answer
input istream.gets.chomp
$log.puts(input) unless $replay
input
end
# Play a round of the game
def play
# Reset pointers to top of $qtree.
$parent_node parent_branch il
$current_node qtree
# Keep guessing until we're done.
while guess; end
end
def guess
question current_node.length 1 ?
"Is your animal \"" + $current_node[0] + "\"? " :
$current_node[0]
prompt question
answer et_answer.downcase[0]
if $current_node.length 1
if answer ?y
prompt "I win!\n\n"
else
learn
end
return false
else
$parent_node current_node
$parent_branch answer ?y) ? 1 : 2
$current_node parent_node[$parent_branch]
return true
end
end
def learn
last_animal current_node[0]
prompt "I give up. What is your animal? "
animal et_answer
prompt "What question distinguishes \"#{last_animal}\" from \"#{animal}\"?\n"
question et_answer
# Adjust the punctuation at the end of the question.
question.sub!(/\??\s*$/, '? ')
prompt "What is the answer to this question for \"#{animal}\"? "
yes get_answer.downcase[0] ?y)
prompt "Thank you.\n\n"
# Build a new node refering to $current_node,
# then insert it into the location of $current_node.
node es ?
[ question, [animal], $current_node ] :
[ question, $current_node, [animal] ]
if $parent_node nil
$qtree ode
else
$parent_node[$parent_branch] ode
end
end
main
--------------060403060801050107090001--