Vance A Heron
1/18/2005 1:44:00 AM
Thought for a while how to express 2 types of
nodes - questions and animals. Decided that
I would have a simple array, with each entry
being another array. If the entry was an "animal"
i.e. end node, it would just have a single
entry [ 'pig' ], if it was a question, it would
have the question, then indexes to the nodes for
'true' or 'false' [ 'does your animal oink', 3, 15]
Both my kids love playing it, although the first time
it asked my 13 y.o. "what is your animal", she said
she didn't want to tell ... it was a secret :)
Added sections to save and reload the state to
preserve the acquired 'knowledge'.
V
---
#! /usr/bin/env ruby
def getans(q)
begin
print "#{q} \?(y/n)"
linein = gets
end until linein =~ /^y/i || linein =~ /^n/i
return linein =~ /^y/i
end
qs = []
savndx = 0
savans = false
fname = ARGV.shift if ARGV
if fname
begin
ifile = File.open(fname)
qs = Marshal.load(ifile.read)
rescue
end
end
ndx = qs.length > 0 ? 1 : 0
qs[0] = [ 'elephant', nil, nil]
# walk q/a path till getting an animal q
while ndx >= 0
ndx = (qs.length - 1) if ndx >= qs.length
if (qs[ndx][1] != nil || qs[ndx][2] != nil) # classification q
savndx = ndx
resp = getans(qs[ndx][0])
savans = resp
ndx = resp ? qs[ndx][1] : qs[ndx][2]
next
else # animal question
animal = qs[ndx][0]
qsstr = 'Is your animal a'
qsstr += (qs[ndx][0] =~ /^[aeiou]/) ? 'n ' : ' '
qsstr += qs[ndx][0]
resp = getans(qsstr)
if resp # got it
puts "I win"
else # add question and animal
print 'What is your animal ?'
newanimal = gets
newanimal.chomp!
print "What questions distinguishes a #{newanimal} from a
#{animal} ? "
question = gets
question.chomp!
ans = getans "For a #{newanimal} how would you answer this"
na_ndx = qs.length + 1
if ans
qs << [question, na_ndx, ndx]
else
qs << [question, ndx, na_ndx]
end
qs[savndx][savans ? 1 : 2] = qs.length - 1 if savndx > 0
qs << [ newanimal, nil, nil]
end
end
puts
ndx = getans('Play again') ? 1 : -1
end
if fname
ofile = File.open(fname, "w+")
Marshal.dump(qs, ofile)
end