Posts Tagged ‘perl’

The Bot Who Came In Out of the Cold

Sunday, April 19th, 2009

I’ve now sunk a number of hours into it and added some functionality, none of which really works yet. But in the interest of keeping things going, here’s where things stand now. Explore doesn’t quite work, and there are still weird undef matches in the dialogue. But I pulled out all of Expect.pm and went to Smart::Comments.


#!/usr/bin/perl

# mudbot by Shannon Prickett
# connect a pandorabots.com chatbot with a particular TinyMUCK, Pegasus.

package mudbot;

use Smart::Comments;
use Modern::Perl;
use Net::Telnet;
use Net::AIML;
use DB_File;

use vars qw{$being_quiet %global_exit $mud_connection $mud_conversation $mud_host $mud_name
$mud_pass $mud_port $mud_sent $pid $robot %room_name };
use subs qw{setup};

$mud_host = 'ginka.armageddon.org';
$mud_port = '4242';
$mud_name = 'Somebot';
$mud_pass = 'YRMEME';
$being_quiet = 0;
$pid = $$;

tie %room_name, 'DB_File', 'mapfile' or
die "can't tie to mapfile: $!\n";

$robot = Net::AIML->new( botid => 'GETFROMPANDORABOTS' );

$mud_connection = new Net::Telnet( Host => $mud_host, Port => $mud_port )
or die "Can't connect to $mud_host $mud_port: $!";

setup( $mud_connection );

TALKLOOP: while (1) {
### TALKLOOP start

my $atme = 0;
my $prematch = '';
my $postmatch = '';
my $who_said;

my ($stub_said, $what_said) =
$mud_connection->waitfor( Match => '/ says, ".*"/',
Errmode => 'return', );

next TALKLOOP unless defined $what_said;

$stub_said =~ qr{ START \d+ .+ \b(\w+)\b }msx;
$who_said = $1;

$what_said =~ s{says, \"(.*)\"}{$1}g;

### Got: $who_said
### Got: $what_said

if ($what_said =~ qr{$mud_name}msxi){
### saw my name
$atme = 1;
}

$what_said =~ s{$mud_name}{}g;

if ( ($atme) && ($what_said =~ qr{QUIT}) ) {
$mud_connection->print("QUIT");
exit;
}

if ( ($atme) && ($what_said =~ qr{be quiet}) ) {
if ($being_quiet) {
$mud_connection->print("say Maximum verbosity achieved.");
$being_quiet = 0;
} else
{
$mud_connection->print("say Shutting up now.");
$being_quiet = 1;
}
}

if ( ($atme) && ($what_said =~ qr{search for '(.*)'}msxi) ) {
my $terms = $1;
my @terms = split $terms;
my $querystring = join '+', @terms;
$mud_connection->print("say Found http://lmgtfy.com/q=$querystring");
}

if ( ($atme) && ($what_said =~ qr{explore}) ) {
$mud_connection->print("say OK, going to poke around now.");
sleep 3;
$mud_connection->print('home');
goto EXPLORELOOP;
}

if ($being_quiet) {
next TALKLOOP;
}

my $response = $robot->tell($what_said);
if ($atme) {
print "response: $response\n";
speak( $response );
}
else {
if ( !$being_quiet && (rand() > .75) ) {
print "jumping in with $response\n";
speak( $response );
}
}
}

EXPLORELOOP: while (1) {
### exploring

my ($name, $desc);

$mud_connection->print('look');
my $startmark = $mud_connection->getline( );
$name = $mud_connection->getline( );
while (my $line = $mud_connection->getline( Errmode => 'return', )) {
$desc .= $line;
}

$mud_connection->waitfor( Match => '/END$pid/', Errmode => 'return');
chomp $name;
chomp $desc;

### got: $name
### got: $desc

$room_name{$name} = $desc;

sleep 10;

$mud_connection->print('out');
}

sub setup {
my $mc = shift;

$mc->dump_log('/home/binder/src/mb/logfile');

$mc->waitfor('/connect\s+guest\s+guest/');
$mc->print("connect $mud_name $mud_pass");

$mc->waitfor('/Vote to ban the MisInformation SuperHighway/');
$mc->print('@desc me=Just a Perl toy of Binder\'s.');

$mc->print("OUTPUTPREFIX START$pid");
$mc->print("OUTPUTSUFFIX END$pid");

$mc->waitfor('/Description set/');
$mc->print("home\nout\nvillage");
}

sub speak {
my $response = shift;
my @lines = split /\n/, $response;
for my $line (@lines) {
$mud_connection->print("say $line");
}
}

Another Sixty Minutes Down

Friday, April 17th, 2009

And the bot is now both more and less annoying. Updated code below.


#!/usr/bin/perl

# mudbot by Shannon Prickett 
# connect a pandorabots.com chatbot with a particular TinyMUCK, Pegasus.

package mudbot;
use Modern::Perl;
use Net::Telnet;
use Net::AIML;
use Expect;

use vars qw{$mud_connection $mud_conversation $mud_host $mud_name $mud_pass $mud_port $mud_sent $robot};

$mud_host = 'ginka.armageddon.org';
$mud_port = '4242';
$mud_name = 'Somebot';
$mud_pass = 'YRMEME';

$robot = Net::AIML->new( botid => 'GETTHISNUMBERFROMPANDORABOTS' ); 

$mud_connection = new Net::Telnet( Host => $mud_host, Port => $mud_port )
    or die "Can't connect to $mud_host $mud_port: $!";

$mud_conversation = Expect->exp_init($mud_connection);

$mud_conversation->log_group(1);
$mud_conversation->log_user(1);
$mud_conversation->log_stdout(1);
$mud_conversation->log_file("/home/binder/src/mb/logfile", 'w');

$mud_conversation->expect(30,   '-re', qr{connect       # pretty standard MUCK greeting
                                    \s+
                                    guest
                                    \s+
                                    guest}msx,
                                sub {
                                    my $fh = shift;
                                    $fh->send("connect $mud_name $mud_pass\n");
                                    });

$mud_conversation->expect(30, 'Vote to ban the MisInformation SuperHighway',
                            sub {
                                my $fh = shift;
                                $fh->send("\@desc me=Just a Perl toy of Binder's.\n");
                                });

$mud_conversation->expect(30, 'Description set',
                            sub {
                                my $fh = shift;
                                $fh->send("home\nout\nvillage\n");
                                });

TALKLOOP: while (1) {
    print "TALKLOOP start\n";

    my $being_quiet = 0;
    my $atme = 0;
    my $prematch = '';
    my $postmatch = '';

    my $index = $mud_conversation->expect( 60, '-re', qr{ says, "} );  

    $prematch = $mud_conversation->before();
    $postmatch = $mud_conversation->after();
    $mud_conversation->clear_accum();

    next TALKLOOP unless $prematch;

    $postmatch =~ s{\"}{};
    print "$prematch said $postmatch\n";

    if ($postmatch =~ qr{$mud_name}){
        print "saw my name\n";
        $postmatch =~ s{$mud_name}{Persephone}g;
        $atme = 1;
    }

    if ( ($atme) && ($postmatch =~ qr{QUIT}) ) {
        $mud_conversation->send("QUIT\n");
        exit;
    }

    if ( ($atme) && ($postmatch =~ qr{be quiet}) ) {
        if ($being_quiet) {
            $mud_conversation->send("say Maximum verbosity achieved.\n");
            $being_quiet = 0;
        } else
        {
            $mud_conversation->send("say Shutting up now.\n");
            $being_quiet = 1;
        }
    }

    if ($being_quiet) {
        next TALKLOOP;
    }

    if ($atme) {
        my $response = $robot->tell($postmatch);
        print "response: $response\n";
        $mud_conversation->send("say $response\n");
    }
    else {
        if ( !$being_quiet && (rand() > .75) ) {
            print "jumping in\n";
            my $response = $robot->tell($postmatch);
            print "response: $response\n";
            $mud_conversation->send("say $response\n");
        }
    }
}
continue {
    $mud_conversation->clear_accum();
}

The Sixty Minute MUDbot.

Thursday, April 16th, 2009

I decided to scratch an itch and practice a little bit of the Manifesto of the Cult of Done tonight.  So I wrote a clunky and fragile Perl wrapper which ties a chatbot to a MUCK.  Here’s the code.

#!/usr/bin/perl

# mudbot by Shannon Prickett 
# connect a pandorabots.com chatbot with a particular TinyMUCK, Pegasus.

package mudbot;
use Modern::Perl;
use Net::Telnet;
use Net::AIML;
use Expect;

use vars qw{$mud_connection $mud_conversation $mud_host $mud_name $mud_pass $mud_port $mud_sent $robot};

$mud_host = 'ginka.armageddon.org';
$mud_port = '4242';
$mud_name = 'Somebot';
$mud_pass = 'YRMEME';

$robot = Net::AIML->new( botid => 'GETTHISNUMBERFROMPANDORABOTS' ); 

$mud_connection = new Net::Telnet( Host => $mud_host, Port => $mud_port )
    or die "Can't connect to $mud_host $mud_port: $!";

$mud_conversation = Expect->exp_init($mud_connection);

$mud_conversation->log_group(1);
$mud_conversation->log_user(1);
$mud_conversation->log_stdout(1);
$mud_conversation->log_file("/home/binder/src/mb/logfile", 'w');

$mud_conversation->expect(30,   '-re', qr{connect       # pretty standard MUCK greeting
                                    \s+
                                    guest
                                    \s+
                                    guest}msx,
                                sub {
                                    my $fh = shift;
                                    $fh->send("connect $mud_name $mud_pass\n");
                                    });

$mud_conversation->expect(30, 'Vote to ban the MisInformation SuperHighway',
                            sub {
                                my $fh = shift;
                                $fh->send("\@desc me=Just a Perl toy of Binder's.\n");
                                });

$mud_conversation->expect(30, 'Description set',
                            sub {
                                my $fh = shift;
                                $fh->send("home\nout\nvillage\n");
                                });

while (1) {
    my $command;
    $mud_conversation->expect(3,
                             '-re',
                             qr{ Somebot }msx,
                             sub {  my $fh = shift;
                                    $command = $mud_conversation->after();
                                    $command =~ tr{\,\"\.\!}{}d;
                                    print "matched: $command\n";
                                    if ($command =~ qr{QUIT}) {
                                        $fh->send("QUIT\n");
                                        exit;
                                    } else
                                    {
                                        if (length($command)>3) {
                                            my $response = $robot->tell($command);
                                            $fh->send("say $response\n");
                                        }
                                    }
                                }
                            );
}

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...