#!/usr/bin/pugs use v6; use Net::IRC; # Parse @*ARGS my $nick = @*ARGS[0] // "blechbot"; my $server = @*ARGS[1] // "localhost"; my $max_bad = @*ARGS[2] // 6; my ($host, $port) = split ":", $server; $port //= 6667; debug "hangmanbot started. Summary of configuration:"; debug " Will connect as... $nick"; debug " to... $host:$port"; debug " using a maximum number of bad guesses of... $max_bad."; debug "To change any of these parameters, restart $*PROGRAM_NAME"; debug "and supply appropriate arguments:"; debug " $*PROGRAM_NAME nick host[:port] max_bad_guesses"; # Copied from examples/games/hangman.p6. sub get_committer_list(Str $dict_file) returns List { my @committers; my $dict = open($dict_file) err die "Couldn't open \"$dict_file\": $!\n"; # Skip the intro text 1 while =$dict ~~ rx:Perl5/\S/; for =$dict -> $name { # Capture the real name part if $name ~~ rx:Perl5/^(.+?)(?:\s\s|$)/ { my $realname = $0; # Remove nickname $realname ~~ s:Perl5/\s*".*"\s*/ /; #/#--vim next unless $realname ~~ rx:Perl5/\S/; @committers.push($realname); } } return @committers; } debug "Reading AUTHORS... "; my @devs = get_committer_list("AUTHORS"); debug "done."; # Create new bot "object" my $bot = new_bot(nick => $nick, host => $host, port => $port); $bot(); $bot(); $bot("INVITE", &on_invite); $bot("PRIVMSG", &on_privmsg); $bot(); sub on_invite($event) { my ($from, $chan) = $event; debug "Got an invitation from \"$from\" to join channel \"$chan\"."; $bot($chan); } sub on_privmsg($event) { state $game; given $event { my $reply_to = substr($event, 0, 1) eq "#" ?? $event :: $event; debug "Got ?-request from \"$event\": $_" if m:Perl5/^\?/; when rx:P5/^\?quit\s*(.*)$/ { $bot($0); } when rx:P5/^\?raw\s+(.+)$/ { $bot($0); } when rx:P5/^\?uptime$/ { my $start_time = INIT { time }; $bot(to => $reply_to, text => "Running for {time() - $start_time} seconds."); } when rx:P5/^\?help$/ { $bot(to => $reply_to, text => "Available commands: ?quit [reason], ?uptime, ?game, ?show, ?guess letter"); } when rx:P5/^\?game$/ { $game = { dev => @devs.pick, guesses => [], bad_guesses => 0, }; show_game($reply_to, $game); } when rx:P5/^\?show/ { if $game { show_game($reply_to, $game); } else { $bot(to => $reply_to, text => "There's no game running currently. You can start one using \"?game\"."); } } when rx:P5/^\?guess ([a-zA-Z])/ { if $game { my $guess = lc $0; my %guesses; # No ยป.++ yet. %guesses{$_}++ for $game; if %guesses{$guess} { $bot(to => $reply_to, text => "You've already guessed \"$guess\"!"); } else { %guesses{$guess}++; $game = [ %guesses.keys.sort ]; if $game ~~ m:Perl5:i/[$guess]/ { if complete($game) { $bot(to => $reply_to, text => "Congratulations! The developer was $game."); undef $game; } else { $bot(to => $reply_to, text => "Yeah, \"$guess\" is in the name."); show_game($reply_to, $game); } } else { $game++; if $game < $max_bad { $bot(to => $reply_to, text => "Sorry, \"$guess\" is not in the name."); } else { $bot(to => $reply_to, text => "Sorry, you exceedded the maximum number of tries. The developer was $game."); undef $game; } } } } else { $bot(to => $reply_to, text => "There's no game running currently. You can start one using \"?game\"."); } } } } # Shows the developer, with not already guesssed chars blanked. sub show_game(Str $to, Hash $game) { my $name = $game; my $guesses = join "", $game; $name ~~ s:Perl5:g:i/[^$guesses\- ]/_/; if $guesses { $bot(to => $to, text => "Guess! $name (You've already guessed $guesses)"); } else { $bot(to => $to, text => "Guess! $name"); } } # Returns true if the game is finished. sub complete(Hash $game) returns Bool { my $name = $game; my $guesses = join "", $game; $name ~~ s:Perl5:g:i/[^$guesses\- ]/_/; return not($name ~~ m:Perl5/_/); }