237 lines
10 KiB
Python
237 lines
10 KiB
Python
# eliza.py -- Rogerian psychotherapist for Crossfire
|
|
#
|
|
# Here is what the original author had to say:
|
|
# ------------------------------------------------------------------
|
|
# a cheezy little Eliza knock-off by Joe Strout <joe@strout.net>
|
|
# with some updates by Jeff Epler <jepler@inetnebr.com>
|
|
# hacked into a module and updated by Jez Higgins <jez@jezuk.co.uk>
|
|
# 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 <kevinz5000@gmail.com>
|
|
|
|
import Crossfire
|
|
import random
|
|
import re
|
|
import string
|
|
|
|
class eliza:
|
|
def __init__(self):
|
|
self.keys = list(map(lambda x: re.compile(x[0], re.IGNORECASE), gPats))
|
|
self.values = list(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 = str.lower().split()
|
|
keys = dict.keys()
|
|
for i in range(0, len(words)):
|
|
if words[i] in keys:
|
|
words[i] = dict[words[i]]
|
|
return " ".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 = resp.find('%')
|
|
while pos > -1:
|
|
num = int(resp[pos + 1:pos + 2])
|
|
resp = resp[:pos] \
|
|
+ self.translate(match.group(num),
|
|
gReflections) + resp[pos + 2:]
|
|
pos = resp.find('%')
|
|
|
|
# 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'(Hi)|(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()
|