On Feb 22, 5:49 am, Mark Tarver <dr.mtar...@[EMAIL PROTECTED]
> wrote:
> Having got 3936 LOC through a 4000 LOC implementation, I thought I'd
> do some recreational
> hacking and do an old old program I've not looked at for some time -
> Eliza. You all know Eliza well enough for me not to have to spell it
> out. The challenge is to implement or dig up an Eliza program (you
> don't have to write it yourself) in your favourite FPL. Note that the
> script that drives Eliza's responses should not be counted towards the
> LOC count. Some constraints.
>
> 1. The script itself should be changeable by any novice. That is to
> say that it should not
> be a pile of hard-wired code written in the native language of
> the program or require
> deep programming skills.
>
> 2. The program should receive keyboard input from the user -
> including the usual punctuation
> and any characters he wants to enter without crashing.
>
> During the Harrop Wars on comp.lang.lisp a lot of stuff was thrown
> around about the desirability of pattern matching. The challenge is
> interesting because it involves a style of pattern-matching called
> 'segment pattern matching' that is not hard-wired into most FPLs and
> I'd like to see how well different FPLs cope with something outside
> the standard.
Here's a shorter Ruby version. Regular expressions are used
in the script.
Script =
[ /father|mother|brother|sister/i, "Tell me about your 0."],
[ /\b(am|i'm) (.*)/i, ["Why are you 2?","Have you always been 2?"]],
[ /\bI was (.*)/i, ["Why were you 1?","I can't believe you were
1."]],
[ /\bI will (.*)/i, "Do you think it's wise to 1?"],
[ /\bI (.*)/i, "Why do you 1?" ],
[ /\b(you|your|yours)\b/i, ["We're talking about you, not me.",
"Please don't be so personal."]],
[ /.*/, ["That's very interesting. Do go on.",
"Tell me more.",
"I'm not sure that I understand you fully.",
"Can you elaborate on that?" ]]
def change_person s
h = { 'I','you', 'my','your', 'myself','yourself',
'you are','I am', "you're","I am" }
s.scan(/you are|you're|\w+|\W+/).map{|s|
h[s] or h.invert[s] or s }.join.sub( / I$/, " me" )
end
while true
print "? "
break if (resp = gets.strip.sub(/[.!?,;]+$/, "")) == 'quit'
Script.each{|ary|
if (md = resp.match( ary[0] ).to_a) != []
t = Array( ary[1] )
# Replies are rotated for variety.
puts t.push(t.shift)[0].gsub(/\d/){change_person md[$&.to_i]}
break
end }
end


|