diff --git a/python/dialog/eliza.py b/python/dialog/eliza.py new file mode 100644 index 000000000..ed94d795c --- /dev/null +++ b/python/dialog/eliza.py @@ -0,0 +1,237 @@ +# eliza.py -- Rogerian psychotherapist for Crossfire +# +# Here is what the original author had to say: +# ------------------------------------------------------------------ +# a cheezy little Eliza knock-off by Joe Strout +# with some updates by Jeff Epler +# hacked into a module and updated by Jez Higgins +# last revised: 28 February 2005 +# ------------------------------------------------------------------ +# The author has released this script under the terms of the MIT License. +# WWW: http://www.jezuk.co.uk/cgi-bin/view/software/eliza +# +# Adpated to Crossfire by Kevin Zheng + +import Crossfire +import random +import re +import string + +class eliza: + def __init__(self): + self.keys = map(lambda x: re.compile(x[0], re.IGNORECASE), + gPats) + self.values = map(lambda x: x[1], gPats) + + # ---------------------------------------------------------------------- + # translate: take a string, replace any words found in dict.keys() + # with the corresponding dict.values() + # ---------------------------------------------------------------------- + def translate(self, str, dict): + words = string.split(string.lower(str)) + keys = dict.keys() + for i in range(0, len(words)): + if words[i] in keys: + words[i] = dict[words[i]] + return string.join(words) + + # ---------------------------------------------------------------------- + # respond: take a string, a set of regexps, and a corresponding + # set of response lists; find a match, and return a randomly + # chosen response from the corresponding list. + # ---------------------------------------------------------------------- + def respond(self, str): + # find a match among keys + for i in range(0, len(self.keys)): + match = self.keys[i].match(str) + if match: + # found a match ... stuff with corresponding value + # chosen randomly from among the available options + resp = random.choice(self.values[i]) + + # got a response... stuff in reflected text where indicated + pos = string.find(resp, '%') + while pos > -1: + num = string.atoi(resp[pos + 1:pos + 2]) + resp = resp[:pos] \ + + self.translate(match.group(num), + gReflections) + resp[pos + 2:] + pos = string.find(resp, '%') + + # fix munged punctuation at the end + if resp[-2:] == '?.': + resp = resp[:-2] + '.' + if resp[-2:] == '??': + resp = resp[:-2] + '?' + return resp + + +# ---------------------------------------------------------------------- +# gReflections, a translation table used to convert things you say +# into things the computer says back, e.g. "I am" --> "you are" +# ---------------------------------------------------------------------- + +gReflections = { + 'am': 'are', + 'was': 'were', + 'i': 'you', + "i'd": 'you would', + "i've": 'you have', + "i'll": 'you will', + 'my': 'your', + 'are': 'am', + "you've": 'I have', + "you'll": 'I will', + 'your': 'my', + 'yours': 'mine', + 'you': 'me', + 'me': 'you', + } + +# ---------------------------------------------------------------------- +# gPats, the main response table. Each element of the list is a +# two-element list; the first is a regexp, and the second is a +# list of possible responses, with group-macros labelled as +# %1, %2, etc. +# ---------------------------------------------------------------------- + +gPats = [ + [r'I need (.*)', ['Why do you need %1?', + 'Would it really help you to get %1?', 'Are you sure you need %1?' + ]], + [r'Why don\'?t you ([^\?]*)\??', ["Do you really think I don't %1?" + , 'Perhaps eventually I will %1.', 'Do you really want me to %1?' + ]], + [r'Why can\'?t I ([^\?]*)\??', + ['Do you think you should be able to %1?', + 'If you could %1, what would you do?', + "I don't know -- why can't you %1?", 'Have you really tried?']], + [r'I can\'?t (.*)', ["How do you know you can't %1?", + 'Perhaps you could %1 if you tried.', + 'What would it take for you to %1?']], + [r'I am (.*)', ['Did you come to me because you are %1?', + 'How long have you been %1?', 'How do you feel about being %1?']], + [r'I\'?m (.*)', ['How does being %1 make you feel?', + 'Do you enjoy being %1?', "Why do you tell me you're %1?", + "Why do you think you're %1?"]], + [r'Are you ([^\?]*)\??', ['Why does it matter whether I am %1?', + 'Would you prefer it if I were not %1?', + 'Perhaps you believe I am %1.', 'I may be %1 -- what do you think?' + ]], + [r'What (.*)', ['Why do you ask?', + 'How would an answer to that help you?', 'What do you think?']], + [r'How (.*)', ['How do you suppose?', + 'Perhaps you can answer your own question.', + "What is it you're really asking?"]], + [r'Because (.*)', ['Is that the real reason?', + 'What other reasons come to mind?', + 'Does that reason apply to anything else?', + 'If %1, what else must be true?']], + [r'(.*) sorry (.*)', + ['There are many times when no apology is needed.', + 'What feelings do you have when you apologize?']], + [r'Hello(.*)', ["Hello... I'm glad you could drop by today.", + 'Hi there... how are you today?', + 'Greetings, how are you?', + 'Hello, how are you feeling today?']], + [r'I think (.*)', ['Do you doubt %1?', 'Do you really think so?', + "But you're not sure %1?"]], + [r'(.*) friend (.*)', ['Tell me more about your friends.', + 'When you think of a friend, what comes to mind?', + "Why don't you tell me about a childhood friend?"]], + [r'Yes', ['You seem quite sure.', 'OK, but can you elaborate a bit?' + ]], + [r'(.*) computer(.*)', ['Are you really talking about me?', + 'Does it seem strange to talk to a computer?', + 'How do computers make you feel?', + 'Do you feel threatened by computers?']], + [r'Is it (.*)', ['Do you think it is %1?', + "Perhaps it's %1 -- what do you think?", + 'If it were %1, what would you do?', 'It could well be that %1.' + ]], + [r'It is (.*)', ['You seem very certain.', + "If I told you that it probably isn't %1, what would you feel?"]], + [r'Can you ([^\?]*)\??', ["What makes you think I can't %1?", + 'If I could %1, then what?', 'Why do you ask if I can %1?']], + [r'Can I ([^\?]*)\??', ["Perhaps you don't want to %1.", + 'Do you want to be able to %1?', 'If you could %1, would you?']], + [r'You are (.*)', ['Why do you think I am %1?', + "Does it please you to think that I'm %1?", + 'Perhaps you would like me to be %1.', + "Perhaps you're really talking about yourself?"]], + [r'You\'?re (.*)', ['Why do you say I am %1?', + 'Why do you think I am %1?', 'Are we talking about you, or me?']], + [r'I don\'?t (.*)', ["Don't you really %1?", "Why don't you %1?", + 'Do you want to %1?']], + [r'I feel (.*)', ['Good, tell me more about these feelings.', + 'Do you often feel %1?', 'When do you usually feel %1?', + 'When you feel %1, what do you do?']], + [r'I have (.*)', ["Why do you tell me that you've %1?", + 'Have you really %1?', + 'Now that you have %1, what will you do next?']], + [r'I would (.*)', ['Could you explain why you would %1?', + 'Why would you %1?', 'Who else knows that you would %1?']], + [r'Is there (.*)', ['Do you think there is %1?', + "It's likely that there is %1.", 'Would you like there to be %1?' + ]], + [r'My (.*)', ['I see, your %1.', 'Why do you say that your %1?', + 'When your %1, how do you feel?']], + [r'You (.*)', ['We should be discussing you, not me.', + 'Why do you say that about me?', 'Why do you care whether I %1?' + ]], + [r'Why (.*)', ["Why don't you tell me the reason why %1?", + 'Why do you think %1?']], + [r'I want (.*)', ['What would it mean to you if you got %1?', + 'Why do you want %1?', 'What would you do if you got %1?', + 'If you got %1, then what would you do?']], + [r'(.*) mother(.*)', ['Tell me more about your mother.', + 'What was your relationship with your mother like?', + 'How do you feel about your mother?', + 'How does this relate to your feelings today?', + 'Good family relations are important.']], + [r'(.*) father(.*)', ['Tell me more about your father.', + 'How did your father make you feel?', + 'How do you feel about your father?', + 'Does your relationship with your father relate to your feelings today?' + , 'Do you have trouble showing affection with your family?']], + [r'(.*) child(.*)', ['Did you have close friends as a child?', + 'What is your favorite childhood memory?', + 'Do you remember any dreams or nightmares from childhood?', + 'Did the other children sometimes tease you?', + 'How do you think your childhood experiences relate to your feelings today?' + ]], + [r'(.*)\?', ['Why do you ask that?', + 'Please consider whether you can answer your own question.', + 'Perhaps the answer lies within yourself?', + "Why don't you tell me?"]], + [r'bye', ['Thank you for talking with me.', 'Good-bye.', + 'Thank you, that will be $150. Have a good day!']], + [r'(.*)', [ + 'Please tell me more.', + "Let's change focus a bit... Tell me about your family.", + 'Can you elaborate on that?', + 'Why do you say that %1?', + 'I see.', + 'Very interesting.', + '%1.', + 'I see. And what does that tell you?', + 'How does that make you feel?', + 'How do you feel when you say that?', + ]], + ] + +# Crossfire interface to Eliza. +def crossfire_interface(): + whoami = Crossfire.WhoAmI() + message = Crossfire.WhatIsMessage() + + while message[-1] in '!.': + message = message[:-1] + + # Respond to player's message. + therapist = eliza() + whoami.Say(therapist.respond(message)) + +# Run the Crossfire interface. +if Crossfire.WhatIsEvent().Subtype == Crossfire.EventType.SAY: + crossfire_interface()