¤ Added the # command. ¤ Fixed bug in reply matching.
The # command now is used for executing Perl codes at the end of the reply-getting process. Some examples of that:
Quote:
+ how long have you been online - I have been online for... # $reply .= " " . $bot->{uptime} . " minutes.";
+ what is 2 plus 2 - This reply isn't sent. # $reply = "2 + 2 = 4";
+ perl random - Red is - Blue is - Green is # $reply .= " my favorite color.";
In the first example, the bot started the reply with - and then added to it. In the second, the bot set the reply to "2 + 2 = 4", ignoring the - command. In the third example, the bot would pick a random reply and then add " my favorite color" to the end of it.
As for the bug with reply matching, replies containing wildcards would have a hard time matching, so I fixed that.
Anyway, the file is attached. _________________ Current Site (2008) http://www.cuvou.com/
Interesting. But I think # is a bad choice since it is so often used as a comment character. Why not & which has more of an execute feel?
& was already taken as a "conversation holder", i.e.
Quote:
+ knock knock - Who's there? & who? & Ha! ! That's a good one!
And also, # is only a comment character in Perl and few others. In C++ and JavaScript, for example, // is used for comments.
And // is used for comments here, too (actually it only requires one /, because the module takes the first character as the command, and skips the "/" command. But two //'s looks better, and more familiar to C++ and JavaScript coders).
But in other places, # is used for codes. Like, on some version of the YaBB forum (or something similar), when posting, the "Code" button is an image with a # sign on it. _________________ Current Site (2008) http://www.cuvou.com/
Well, considering your module is written in Perl and not C++, it seems to me you'd want to stick with a commenting style that people are familiar with.
I'm a C and Perl programmer, but when I read your example, since I knew the module was written in Perl, I initially skipped over the # lines assuming they were comments. I'm guessing you're just going to confuse people, imho.
Version 1.2 - "sort_replies" method added--sorts the replies (normal triggers will be checked before wildcards, resulting in better matching!)
After loading the replies, call $alpha->sort_replies to sort them. If you don't sort the replies, the module will sort them by itself when you request a reply anyway.
The reply sorting results in better matching. For example, if you had replies like this:
Code:
+ are you a bot<br />- Hey! How did you know I am a bot?<br /><br />+ are you *<br />- Yes.<br />- No.<br />- Maybe.<br />- Only when I'm drunk.
Hashes/hashrefs are sorted in a relatively random order, so even though "are you a bot" came before "are you *", it would sometimes sort the wildcard one before the normal. So then if you asked "Are you a bot?", your bot might have replied "Only when I'm drunk."
So this sorts all "normal" replies before those with wildcards.
The module Alpha.pm is attached--extract it to your lib, replacing the existing Alpha.pm (for Leviathan, extract it replacing ./lib/Chatbot/Alpha.pm)
sort_replies code If you wanted to see the main changes:
Code:
sub sort_replies {<br /> my $self = shift;<br /><br /> # Fail if replies hadn't been loaded.<br /> return 0 unless exists $self->{_replies};<br /><br /> # Delete the replies array (if it exists).<br /> if (exists $self->{_array}) {<br /> delete $self->{_array};<br /> }<br /><br /> # Two arrays for sorting the trigger types.<br /> my @trigNorm = ();<br /> my @trigWild = ();<br /><br /> $self->debug ("Sorting the replies...");<br /><br /> # Go through each reply.<br /> foreach my $key (keys %{$self->{_replies}}) {<br /> $self->debug ("Sorting key $key");<br /> # If it's a wildcard...<br /> if ($key =~ /\*/) {<br /> # Save to wildcard array.<br /> $self->debug ("Key $key is a wildcard!");<br /> push (@trigWild, $key);<br /> }<br /> else {<br /> # Save to normal array.<br /> $self->debug ("Key $key is normal!");<br /> push (@trigNorm, $key);<br /> }<br /> }<br /><br /> # Order the array.<br /> $self->{_array} = [<br /> @trigNorm,<br /> @trigWild,<br /> ];<br /><br /> # Return true.<br /> return 1;<br />}
The other code change was in the reply getting sub, instead of searching through keys %{$self->{_replies}}, it searches through the array @{$self->{_array}}. There was also code added to that sub to call the sort_replies sub if you failed to do so. _________________ Current Site (2008) http://www.cuvou.com/
If you're familiar with AIML, you'll know what topics are.
Here's the test reply file (with topic-related parts highlighted):
Quote:
// Test Replies
// A topic test. > topic apologize
+ * - Nope, not until you apologize.
+ sorry - See? That wasn't so hard, was it? -- I'll forgive you.{topic=random}
// End the topic < topic
// A standard reply to "hello", with multiple responses. + hello - Hello there! - What's up? - This is random, eh?
// A simple one-reply response to "what's up" + what's up - Not much, you?
// A test using + say * - Um.... ""
// This reply is referred to below. + identify yourself - I am Alpha.
// Refers the asker back to the reply above. + who are you @ identify yourself
// Conditionals Test + am i your master * if master = 1::Yes, you are my master. - No, you are not my master.
// Perl Evaluation Test + what is 2 plus 2 # $reply = "2 + 2 = 4";
// A Conversation Holder: Knock Knock! + knock knock - Who's there? & who? & Ha! ! That's a good one!
// A Conversation Holder: Rambling! + are you crazy - I was crazy once. & They locked me away... & In a room with padded walls. & There were rats there... & Did I mention I was crazy once?
// A topic entry test. +*rude*you - You're very rude! Fine, I'm not talking until you apologize.{topic=apologize}
The default topic is '' (undefined). Unless you specify a topic with the "> topic" command, all your replies will be under the default topic.
To set a topic, insert {topic=name} - the only reserved name is "random" - this sets the topic back to the default, undefined. It's probably better to use a topic of "random" instead of just leaving it blank, or undefined.
Replies within a certain topic are NOT available from other topics (i.e. if you're in the default topic, and say "sorry", it won't know how to reply to it because the trigger "sorry" is in a different topic).
Here's some example output from running test.pl with the test reply file:
Code:
You> hello<br />Alpha> Hello there!<br /><br /> You> sorry<br />Alpha> I'm afraid I don't know how to reply to that!<br /><br /> You>*rude*you<br />Alpha> You're very rude! Fine, I'm not talking until you apologize.<br /><br /> You> no<br />Alpha> Nope, not until you apologize.<br /><br /> You> hello<br />Alpha> Nope, not until you apologize.<br /><br /> You> sorry<br />Alpha> See? That wasn't so hard, was it? -- I'll forgive you.<br /><br /> You> hello<br />Alpha> Hello there!
For a useful example of this:
In your bot, you can check if the client is a new user, and if so, force their $msg to be like... "reg new user", and then get a reply, and you can do an introductions thing (like SmarterChild has!)
Code:
+ reg new user<br />- Hey! You're a new face. What's your name?{topic=reg_name}<br /><br />> topic reg_name<br />+ *<br />- So, your name is <star1> huh? Cool! How old are you?{topic=reg_age}<br />< topic<br /><br />> topic reg_age<br />+ *<br />- I see. You're <star1> years old. Where do you live?{topic=reg_location}<br />< topic<br /><br />// etc. etc.
Anyway, the module distribution is attached. The next release of Leviathan should feature some improved Alpha responses.
EDIT // I fixed a bug. Alpha now internally sorts replies under topics, not topics under replies (if you had two replies that had the same trigger, then regardless what topic they were in, they would overwrite eachother -- this fixes it).
I attached just the PM file to the fix.
Also, I have the Leviathan data for creating a "new users profile" (kinda like SmarterChild has, where it interviews new users to learn basic info about them) thing, if anybody's interested I might upload it here too. _________________ Current Site (2008) http://www.cuvou.com/
I've just corrected a relatively major bug in the module:
The substitution from * to (.*?) wasn't a global replacement, so if you had a reply trigger with more than one *, it would only convert the first one to a wildcard and the others would be literal *'s.
So for example, reply triggers like these would not have worked:
Code:
+ *aol*<br />- Don't ever mention AOL again.<br /><br />+ * told me to im * and say *<br />- Really, you were told to say "<star3>" to <star2> because <star1> told you to?
But that's fixed now (the first example is a "find anywhere" thing, just put two *'s touching either side of the trigger).
I attached it, Chatbot::Alpha 1.4 _________________ Current Site (2008) http://www.cuvou.com/