mirror of
				https://github.com/pragma-/pbot.git
				synced 2025-11-04 00:27:23 +01:00 
			
		
		
		
	Plugin/Wordle: colorize ouput and add wordlists
This commit is contained in:
		
							parent
							
								
									c62b4d1c35
								
							
						
					
					
						commit
						bde06990fe
					
				
							
								
								
									
										63737
									
								
								data/wordle/american
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63737
									
								
								data/wordle/american
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										429393
									
								
								data/wordle/american-insane
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										429393
									
								
								data/wordle/american-insane
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										63363
									
								
								data/wordle/british
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63363
									
								
								data/wordle/british
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										63698
									
								
								data/wordle/canadian
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63698
									
								
								data/wordle/canadian
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										200095
									
								
								data/wordle/french
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200095
									
								
								data/wordle/french
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										150689
									
								
								data/wordle/german
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150689
									
								
								data/wordle/german
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										101975
									
								
								data/wordle/italian
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101975
									
								
								data/wordle/italian
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										68589
									
								
								data/wordle/spanish
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68589
									
								
								data/wordle/spanish
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -17,6 +17,8 @@ sub initialize($self, %conf) {
 | 
			
		||||
        help => 'Wordle game! Guess target word by submitting words for clues about which letters belong to the word!',
 | 
			
		||||
        subref => sub { $self->wordle(@_) },
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    $self->{datadir} = $self->{pbot}->{registry}->get_value('general', 'data_dir');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub unload($self) {
 | 
			
		||||
@ -24,17 +26,42 @@ sub unload($self) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use constant {
 | 
			
		||||
    USAGE => 'Usage: wordle start [word length] | custom <word> <channel> | guess <word> | letters | show | giveup',
 | 
			
		||||
    USAGE     => 'Usage: wordle start [length [wordlist]] | custom <word> <channel> [wordlist] | guess <word> | letters | show | giveup',
 | 
			
		||||
    NO_WORDLE => 'There is no Wordle yet. Use `wordle start` to begin a game.',
 | 
			
		||||
 | 
			
		||||
    DEFAULT_LENGTH => 5,
 | 
			
		||||
    MIN_LENGTH => 3,
 | 
			
		||||
    MAX_LENGTH => 10,
 | 
			
		||||
    WORDLIST => '/usr/share/dict/words',
 | 
			
		||||
    MIN_LENGTH     => 3,
 | 
			
		||||
    MAX_LENGTH     => 22,
 | 
			
		||||
 | 
			
		||||
    LETTER_CORRECT => 1,
 | 
			
		||||
    LETTER_PRESENT => 2,
 | 
			
		||||
    LETTER_INVALID => 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
my %wordlists = (
 | 
			
		||||
    default   => '/wordle/american',
 | 
			
		||||
    american  => '/wordle/american',
 | 
			
		||||
    insane    => '/wordle/american-insane',
 | 
			
		||||
    british   => '/wordle/british',
 | 
			
		||||
    canadian  => '/wordle/canadian',
 | 
			
		||||
    french    => '/wordle/french',
 | 
			
		||||
    german    => '/wordle/german',
 | 
			
		||||
    italian   => '/wordle/italian',
 | 
			
		||||
    spanish   => '/wordle/spanish',
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
my %color = (
 | 
			
		||||
    correct   => "\x0301,03",
 | 
			
		||||
    correct_a => "\x0303,03",
 | 
			
		||||
 | 
			
		||||
    present   => "\x0301,07",
 | 
			
		||||
    present_a => "\x0307,07",
 | 
			
		||||
 | 
			
		||||
    invalid   => "\x0301,15",
 | 
			
		||||
 | 
			
		||||
    reset     => "\x0F",
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
sub wordle($self, $context) {
 | 
			
		||||
    my @args = $self->{pbot}->{interpreter}->split_line($context->{arguments});
 | 
			
		||||
 | 
			
		||||
@ -52,7 +79,7 @@ sub wordle($self, $context) {
 | 
			
		||||
                return NO_WORDLE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $self->show_wordle($channel);
 | 
			
		||||
            return $self->show_wordle($channel, 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        when ('giveup') {
 | 
			
		||||
@ -67,8 +94,8 @@ sub wordle($self, $context) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        when ('start') {
 | 
			
		||||
            if (@args > 1) {
 | 
			
		||||
                return "Invalid arguments; Usage: wordle start [word length]";
 | 
			
		||||
            if (@args > 2) {
 | 
			
		||||
                return "Invalid arguments; Usage: wordle start [word length [wordlist]]";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (defined $self->{$channel}->{wordle} && $self->{$channel}->{correct} == 0) {
 | 
			
		||||
@ -85,17 +112,24 @@ sub wordle($self, $context) {
 | 
			
		||||
                $length = $args[0];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $self->make_wordle($channel, $length);
 | 
			
		||||
            my $wordlist = $args[1] // 'default';
 | 
			
		||||
 | 
			
		||||
            if (not exists $wordlists{$wordlist}) {
 | 
			
		||||
                return 'Invalid wordlist; options are: ' . (join ', ', sort keys %wordlists);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $self->make_wordle($channel, $length, undef, $wordlist);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        when ('custom') {
 | 
			
		||||
            if (@args != 2) {
 | 
			
		||||
                return "Usage: wordle custom <word> <channel>";
 | 
			
		||||
            if (@args < 2 || @args > 3) {
 | 
			
		||||
                return "Usage: wordle custom <word> <channel> [wordlist]";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            my $custom_word    = $args[0];
 | 
			
		||||
            my $custom_channel = $args[1];
 | 
			
		||||
            my $length         = length $custom_word;
 | 
			
		||||
            my $custom_word     = $args[0];
 | 
			
		||||
            my $custom_channel  = $args[1];
 | 
			
		||||
            my $custom_wordlist = $args[2];
 | 
			
		||||
            my $length          = length $custom_word;
 | 
			
		||||
 | 
			
		||||
            if ($custom_word !~ /[a-z]/) {
 | 
			
		||||
                return "Word must be all lowercase and cannot contain numbers or symbols.";
 | 
			
		||||
@ -113,9 +147,15 @@ sub wordle($self, $context) {
 | 
			
		||||
                return "There is already a Wordle underway! Use `wordle show` to see the current progress or `wordle giveup` to end it.";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            my $result = $self->make_wordle($custom_channel, $length, uc $custom_word);
 | 
			
		||||
            my $wordlist = $custom_wordlist // 'default';
 | 
			
		||||
 | 
			
		||||
            if ($result !~ /^Wordle:/) {
 | 
			
		||||
            if (not exists $wordlists{$wordlist}) {
 | 
			
		||||
                return 'Invalid wordlist; options are: ' . (join ', ', sort keys %wordlists);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            my $result = $self->make_wordle($custom_channel, $length, uc $custom_word, $wordlist);
 | 
			
		||||
 | 
			
		||||
            if ($result !~ /Guess/) {
 | 
			
		||||
                return $result;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -129,7 +169,7 @@ sub wordle($self, $context) {
 | 
			
		||||
                command    => 'wordle',
 | 
			
		||||
                keyword    => 'wordle',
 | 
			
		||||
                checkflood => 1,
 | 
			
		||||
                message    => "$context->{nick} started a custom $result",
 | 
			
		||||
                message    => "$result (started by $context->{nick})",
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            $self->{pbot}->{interpreter}->add_message_to_output_queue($custom_channel, $message, 0);
 | 
			
		||||
@ -162,19 +202,7 @@ sub wordle($self, $context) {
 | 
			
		||||
                return NO_WORDLE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            my $result = 'Good/unknown letters: ';
 | 
			
		||||
 | 
			
		||||
            foreach my $letter (sort keys $self->{$channel}->{letters}->%*) {
 | 
			
		||||
                if ($self->{$channel}->{letters}->{$letter} == LETTER_CORRECT) {
 | 
			
		||||
                    $result .= "*$letter* ";
 | 
			
		||||
                } elsif ($self->{$channel}->{letters}->{$letter} == LETTER_PRESENT) {
 | 
			
		||||
                    $result .= "?$letter? ";
 | 
			
		||||
                } elsif ($self->{$channel}->{letters}->{$letter} == 0) {
 | 
			
		||||
                    $result .= "$letter ";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $result;
 | 
			
		||||
	    return $self->show_letters($channel);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default {
 | 
			
		||||
@ -183,12 +211,15 @@ sub wordle($self, $context) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub load_words($self, $length) {
 | 
			
		||||
    if (not -e WORDLIST) {
 | 
			
		||||
        die "Wordle database `" . WORDLIST . "` not available. Set WORDLIST to a valid location of a wordlist file.\n";
 | 
			
		||||
sub load_words($self, $length, $wordlist = 'default') {
 | 
			
		||||
    print "datadir: $self->{datadir}; wordlist = $wordlist; path = $wordlists{$wordlist}\n";
 | 
			
		||||
    $wordlist = $self->{datadir} . $wordlists{$wordlist};
 | 
			
		||||
 | 
			
		||||
    if (not -e $wordlist) {
 | 
			
		||||
        die "Wordle database `" . $wordlist . "` not available. Set WORDLIST to a valid location of a wordlist file.\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    open my $fh, '<', WORDLIST or die "Failed to open Wordle database.";
 | 
			
		||||
    open my $fh, '<', $wordlist or die "Failed to open Wordle database.";
 | 
			
		||||
 | 
			
		||||
    my %words;
 | 
			
		||||
 | 
			
		||||
@ -205,9 +236,9 @@ sub load_words($self, $length) {
 | 
			
		||||
    return \%words;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub make_wordle($self, $channel, $length, $word = undef) {
 | 
			
		||||
sub make_wordle($self, $channel, $length, $word = undef, $wordlist = 'default') {
 | 
			
		||||
    eval {
 | 
			
		||||
        $self->{$channel}->{words} = $self->load_words($length);
 | 
			
		||||
        $self->{$channel}->{words} = $self->load_words($length, $wordlist);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if ($@) {
 | 
			
		||||
@ -227,7 +258,7 @@ sub make_wordle($self, $channel, $length, $word = undef) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $self->{$channel}->{wordle}      = \@wordle;
 | 
			
		||||
    $self->{$channel}->{guesses}     = [];
 | 
			
		||||
    $self->{$channel}->{guess}       = '';
 | 
			
		||||
    $self->{$channel}->{correct}     = 0;
 | 
			
		||||
    $self->{$channel}->{guess_count} = 0;
 | 
			
		||||
    $self->{$channel}->{letters}     = {};
 | 
			
		||||
@ -236,13 +267,37 @@ sub make_wordle($self, $channel, $length, $word = undef) {
 | 
			
		||||
        $self->{$channel}->{letters}->{$letter} = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    push $self->{$channel}->{guesses}->@*, '? ' x $self->{$channel}->{wordle}->@*;
 | 
			
		||||
    $self->{$channel}->{guess}  = $color{invalid};
 | 
			
		||||
    $self->{$channel}->{guess} .= ' ? ' x $self->{$channel}->{wordle}->@*;
 | 
			
		||||
    $self->{$channel}->{guess} .= $color{reset};
 | 
			
		||||
 | 
			
		||||
    return "Wordle: " . $self->show_wordle($channel) . " (Guess the word! Legend: X not in word; ?X? wrong position; *X* correct position)";
 | 
			
		||||
    return $self->show_wordle($channel) . " Guess the word! Legend: $color{invalid}X $color{reset} not in word; $color{present}X$color{present_a}?$color{reset} wrong position; $color{correct}X$color{correct_a}*$color{reset} correct position";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub show_wordle($self, $channel) {
 | 
			
		||||
    return join ' -> ', $self->{$channel}->{guesses}->@*;
 | 
			
		||||
sub show_letters($self, $channel) {
 | 
			
		||||
            my $result = 'Letters: ';
 | 
			
		||||
 | 
			
		||||
            foreach my $letter (sort keys $self->{$channel}->{letters}->%*) {
 | 
			
		||||
                if ($self->{$channel}->{letters}->{$letter} == LETTER_CORRECT) {
 | 
			
		||||
                    $result .= "$color{correct}$letter$color{correct_a}*";
 | 
			
		||||
                    $result .= "$color{reset} ";
 | 
			
		||||
                } elsif ($self->{$channel}->{letters}->{$letter} == LETTER_PRESENT) {
 | 
			
		||||
                    $result .= "$color{present}$letter$color{present_a}?";
 | 
			
		||||
                    $result .= "$color{reset} ";
 | 
			
		||||
                } elsif ($self->{$channel}->{letters}->{$letter} == 0) {
 | 
			
		||||
                    $result .= "$letter ";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $result . "$color{reset}";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub show_wordle($self, $channel, $with_letters = 0) {
 | 
			
		||||
	if ($with_letters) {
 | 
			
		||||
		return $self->{$channel}->{guess} . "$color{reset} " . $self->show_letters($channel);
 | 
			
		||||
	} else {
 | 
			
		||||
		return $self->{$channel}->{guess} . "$color{reset}";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub guess_wordle($self, $channel, $guess) {
 | 
			
		||||
@ -258,11 +313,6 @@ sub guess_wordle($self, $channel, $guess) {
 | 
			
		||||
 | 
			
		||||
    $self->{$channel}->{guess_count}++;
 | 
			
		||||
 | 
			
		||||
    if ($self->{$channel}->{guess_count} == 1) {
 | 
			
		||||
        # remove initial "? ? ? ? ?"
 | 
			
		||||
        shift $self->{$channel}->{guesses}->@*;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    my @guess  = split //, $guess;
 | 
			
		||||
    my @wordle = $self->{$channel}->{wordle}->@*;
 | 
			
		||||
 | 
			
		||||
@ -280,13 +330,13 @@ sub guess_wordle($self, $channel, $guess) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    my @result;
 | 
			
		||||
    my $result = '';
 | 
			
		||||
    my $correct = 0;
 | 
			
		||||
 | 
			
		||||
    for (my $i = 0; $i < @wordle; $i++) {
 | 
			
		||||
        if ($guess[$i] eq $wordle[$i]) {
 | 
			
		||||
            $correct++;
 | 
			
		||||
            push @result, "*$guess[$i]*";
 | 
			
		||||
            $result .= "$color{correct} $guess[$i]$color{correct_a}*";
 | 
			
		||||
            $self->{$channel}->{letters}->{$guess[$i]} = LETTER_CORRECT;
 | 
			
		||||
        } else {
 | 
			
		||||
            my $present = 0;
 | 
			
		||||
@ -303,10 +353,10 @@ sub guess_wordle($self, $channel, $guess) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($present) {
 | 
			
		||||
                push @result, "?$guess[$i]?";
 | 
			
		||||
                $result .= "$color{present} $guess[$i]$color{present_a}?";
 | 
			
		||||
                $self->{$channel}->{letters}->{$guess[$i]} = LETTER_PRESENT;
 | 
			
		||||
            } else {
 | 
			
		||||
                push @result, "$guess[$i]";
 | 
			
		||||
                $result .= "$color{invalid} $guess[$i] ";
 | 
			
		||||
 | 
			
		||||
                if ($self->{$channel}->{letters}->{$guess[$i]} == 0) {
 | 
			
		||||
                    $self->{$channel}->{letters}->{$guess[$i]} = LETTER_INVALID;
 | 
			
		||||
@ -315,16 +365,14 @@ sub guess_wordle($self, $channel, $guess) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    push $self->{$channel}->{guesses}->@*, join ' ', @result;
 | 
			
		||||
    $self->{$channel}->{guess} = $result;
 | 
			
		||||
 | 
			
		||||
    if ($correct == length $guess) {
 | 
			
		||||
        $self->{$channel}->{correct} = 1;
 | 
			
		||||
 | 
			
		||||
        my $guesses = $self->{$channel}->{guess_count};
 | 
			
		||||
 | 
			
		||||
        return "Correct in $guesses guess" . ($guesses != 1 ? 'es! ' : '! ') . $self->show_wordle($channel);
 | 
			
		||||
        return $self->show_wordle($channel) . " Correct in $guesses guess" . ($guesses != 1 ? 'es! ' : '! ');
 | 
			
		||||
    } else {
 | 
			
		||||
        return $self->show_wordle($channel);
 | 
			
		||||
        return $self->show_wordle($channel, 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,8 @@ use PBot::Imports;
 | 
			
		||||
# These are set by the /misc/update_version script
 | 
			
		||||
use constant {
 | 
			
		||||
    BUILD_NAME     => "PBot",
 | 
			
		||||
    BUILD_REVISION => 4717,
 | 
			
		||||
    BUILD_DATE     => "2024-03-15",
 | 
			
		||||
    BUILD_REVISION => 4718,
 | 
			
		||||
    BUILD_DATE     => "2024-03-16",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
sub initialize {}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user