| IRC-Bot-Hangman documentation | Contained in the IRC-Bot-Hangman distribution. |
IRC::Bot::Hangman - An IRC hangman
use IRC::Bot::Hangman;
IRC::Bot::Hangman->new(
channels => [ '#hangman' ],
nick => 'hangman',
server => 'irc.blablablablah.bla',
word_list_name => 'too_easy',
games => 3,
)->run;
print "Finished\n";
<letter>? : guess a letter guess <letter> : guess a letter guess <word> : guess an entire word <hangman> help - help instructions <hangman> play : Start a new game or display current game <hangman> quiet : keep quiet between guesses <hangman> talk : Talk between guesses
This module provides a useless IRC bot which enables you to play hangman, the classic word game. It comes shipped with a list of ~2000 english words by default. The architecture is plugin based, words, commands and responses can be extended at will by adding new modules.
The main motivation was to provide a multi-player text based game for children to help them practising writing.
The plugins are managed by
IRC::Bot::Hangman::WordList IRC::Bot::Hangman::Command IRC::Bot::Hangman::Response
Get or set the word list as an array ref. A default word list of ~2000 english words is provided if no list is set.
Returns a default english words list from IRC::Bot::Hangman::WordList
Get or set the word list name. It must be an installed module in IRC::Bot::Hangman::WordList::xxx The default provided is 'default' = IRC::Bot::Hangman::WordList::Default
Get or set the number of games before ending. undef means infinity.
Get or set the hangman game. The default value is a Games::GuessWord instance with word_list() word list.
Reset the game
Reset the game unless it is the last game as counted by games()
Get set can_talk, used by tick to display reminders.
Returns a Games::GuessWord instance
Displays the word to guess
Returns a random time calculated: delay() * (1 + rand(4)) seconds
Get set base delay in seconds. Default is 30s.
Get/set input
Get/set response
Sets the response from a response type
Returns a msg of a given type
Guess a word : success or one chance less
Guess a letter : match or one chance less
Displays an end of game message : sucess or lost
These are the Bot::BasicBot overriden methods
This is the main method, everything said is analysed to provide a reply if appropriate
Displays help when called hangman help
Called every now and then to display a reminder
if the game is active and can_talk is on.
Pierre Denis <pierre@itrelease.net>
http://www.itrelease.net/
Copyright 2005 IT Release Ltd - All Rights Reserved.
This module is released under the same license as Perl itself.
| IRC-Bot-Hangman documentation | Contained in the IRC-Bot-Hangman distribution. |
package IRC::Bot::Hangman; use warnings::register; use strict; use base qw( Bot::BasicBot ); use Carp qw( carp ); use Games::GuessWord; use IRC::Bot::Hangman::WordList; use IRC::Bot::Hangman::Command; use IRC::Bot::Hangman::Response; our $VERSION = '0.1'; our $DEFAULT_WORD_LIST = 'default'; our $DEFAULT_DELAY = 30; # seconds
sub word_list { my $self = shift; if (@_) { my $list = shift; unless (ref $list eq 'ARRAY') { carp "word_list should be an array ref"; return; } $self->{word_list} = $list; return $self; } $self->{word_list} ||= $self->load_word_list(); }
sub load_word_list { my $self = shift; my $name = shift || $self->word_list_name; IRC::Bot::Hangman::WordList->load( $name ); }
sub word_list_name { my $self = shift; if (@_) { $self->{word_list_name} = shift; return $self; } $self->{word_list_name} ||= $DEFAULT_WORD_LIST; }
sub games { my $self = shift; if (@_) { my $games = shift; $self->{games} = $games; return $self; } $self->{games}; }
sub game { my $self = shift; if (@_) { my $game = shift; $self->{game} = $game; return $self; } $self->{game} ||= $self->load_game; }
sub new_game { my $self = shift; my $game = $self->game or return; $self->game( ref($game)->new( words => $self->word_list ) ); }
sub replay { my $self = shift; my $games = $self->games; if (defined $games) { $self->games($games - 1); if ($self->games <= 0) { $self->schedule_tick(0); return $self->get_a_msg('last_game'); } } $self->new_game(); $self->schedule_tick(5); return; }
sub can_talk { my $self = shift; if (@_) { $self->{can_talk} = shift; return $self; } $self->{can_talk}; }
sub load_game { my $self = shift; Games::GuessWord->new( words => $self->word_list ); }
sub msg_guess { my $self = shift; 'To guess: ' . $self->game->answer . ' - ' . $self->game->chances . " chances remaining"; }
sub get_delay { my $self = shift; my $delay = $self->delay; $delay *(1 + rand(4)); }
sub delay { my $self = shift; if (@_) { $self->{delay} = shift; return $self; } $self->{delay} ||= $DEFAULT_DELAY; }
sub input { my $self = shift; if (@_) { $self->{input} = shift; return $self; } $self->{input}; }
sub response { my $self = shift; if (@_) { $self->{response} = shift; return $self; } $self->{response}; }
sub set_response { my $self = shift; my $type = shift; my $msg = $self->get_a_msg( $type ) or carp "No message of type $type"; $self->response( $msg ); }
sub get_a_msg { my $self = shift; my $type = shift; IRC::Bot::Hangman::Response->get_a_msg( $type ); }
sub guess_word { my $self = shift; my $guess = shift; if ($guess eq $self->game->secret) { $self->game->guess($guess); return $self->get_a_msg('good_guess'); } else { $self->game->{chances}--; return $self->get_a_msg('bad_guess'); } }
sub guess_letter { my $self = shift; my $guess = shift; my @guesses = $self->game->guesses; my @msg; if (grep { $_ eq $guess } @guesses) { push @msg, $self->get_a_msg('already_guessed'); push @msg, 'Letters used: ' . join(', ', $self->game->guesses); } else { my $chances = $self->game->chances; $self->game->guess($guess); if ($chances == $self->game->chances) { push @msg, $self->get_a_msg('good_guess'); } else { push @msg, $self->get_a_msg('bad_guess'); } push @msg, $self->give_advice($guess); } @msg; }
sub conclusion { my $self = shift; my @msg; if ($self->game->won) { push @msg, $self->get_a_msg('won'); push @msg, "The word was: " . $self->game->secret; push @msg, "Your score: " . $self->game->score; push @msg, $self->replay(); } elsif ($self->game->lost) { push @msg, $self->get_a_msg('lost'); push @msg, "The word was: " . $self->game->secret; push @msg, "Your score: " . $self->game->score; push @msg, $self->replay(); } else { push @msg, $self->msg_guess; } @msg; }
sub give_advice { my $self = shift; my $guess = shift; my @guesses = $self->game->guesses; if ($guess =~ /[euioa]/ and grep(/[euioa]/, @guesses) >= 3 and @guesses < 6) { return $self->get_a_msg('lack_imagination'); } return; }
sub said { my $self = shift; my $args = shift; return if ($self->ignore_nick($args->{who})); my $nick = $self->nick; if ($args->{address} || '' eq $nick) { my $msg = $args->{body}; $msg =~ s/[\r\n\f]+$//; $self->input( $msg ); $self->response(''); IRC::Bot::Hangman::Command->run( $self ); return $self->response if $self->response; } return if ($self->game->won or $self->game->lost); my ($guess) = ($args->{body} =~ /^\s*([a-z])\s*\?\s*$/); ($guess) = ($args->{body} =~ /^\s*guess\s+([a-z]+)\s*$/) unless $guess; $guess or return; $self->schedule_tick($self->get_delay); $guess = lc $guess; my @msg; if (length $guess > 1) { push @msg, $self->guess_word($guess); } else { push @msg, $self->guess_letter($guess); } push @msg, $self->conclusion; join "\r\n", @msg; }
sub help { my $self = shift; my $help = $self->get_a_msg('help'); my $nick = $self->nick; $help =~ s/<hangman>/$nick/g; $help; }
sub tick { my $self = shift; return $self->get_delay if ($self->game->lost or $self->game->won); if ($self->can_talk) { my @msg = ($self->get_a_msg('play'), $self->msg_guess); $self->say( channel => $_, body => join "\r\n", @msg ) for (@{$self->{channels}}); } $self->get_delay; } 1;