3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-26 05:49:27 +01:00

Plugin/WordMorph: several improvements

- add 2880 variant words to wordlist
- morph generator skips words with same suffix
- default steps increased from 3 to 4
- default minimum word length increased from 4 to 5

Note that you can override default steps and word lengths via `start`.
This commit is contained in:
Pragmatic Software 2022-09-04 16:47:43 -07:00
parent 82edbd2a18
commit adaf4e2ed3
3 changed files with 33 additions and 23 deletions

BIN
data/wordmorph.db vendored

Binary file not shown.

View File

@ -77,7 +77,8 @@ sub wordmorph {
return "Unknown direction `$args[0]`; usage: wordmorph hint [from direction]; from direction can be `left` or `right`"; return "Unknown direction `$args[0]`; usage: wordmorph hint [from direction]; from direction can be `left` or `right`";
} }
my $end = $#{$self->{$channel}->{morph}}; my $morph = $self->{$channel}->{morph};
my $end = $#$morph;
if ($direction == LEFT) { if ($direction == LEFT) {
$self->{$channel}->{hintL}++; $self->{$channel}->{hintL}++;
@ -95,23 +96,23 @@ sub wordmorph {
my @hints; my @hints;
$hints[0] = $self->{$channel}->{morph}->[0]; $hints[0] = $morph->[0];
$hints[$end] = $self->{$channel}->{morph}->[$end]; $hints[$end] = $morph->[$end];
for (my $i = 1; $i < $self->{$channel}->{hintL}; $i++) { for (my $i = 1; $i < $self->{$channel}->{hintL}; $i++) {
my $word1 = $self->{$channel}->{morph}->[$i - 1]; my $word1 = $morph->[$i - 1];
my $word2 = $self->{$channel}->{morph}->[$i]; my $word2 = $morph->[$i];
$hints[$i] = $self->form_hint($word1, $word2); $hints[$i] = $self->form_hint($word1, $word2);
} }
my $blank_hint = '_' x length $self->{$channel}->{morph}->[0]; my $blank_hint = '_' x length $morph->[0];
for (my $i = $self->{$channel}->{hintL}; $i < $self->{$channel}->{hintR} + 1; $i++) { for (my $i = $self->{$channel}->{hintL}; $i < $self->{$channel}->{hintR} + 1; $i++) {
$hints[$i] = $blank_hint; $hints[$i] = $blank_hint;
} }
for (my $i = $end - 1; $i > $self->{$channel}->{hintR}; $i--) { for (my $i = $end - 1; $i > $self->{$channel}->{hintR}; $i--) {
my $word1 = $self->{$channel}->{morph}->[$i]; my $word1 = $morph->[$i];
my $word2 = $self->{$channel}->{morph}->[$i + 1]; my $word2 = $morph->[$i + 1];
$hints[$i] = $self->form_hint($word1, $word2); $hints[$i] = $self->form_hint($word1, $word2);
} }
@ -141,7 +142,7 @@ sub wordmorph {
return "Invalid arguments; Usage: wordmorph start [steps to solve [word length]]"; return "Invalid arguments; Usage: wordmorph start [steps to solve [word length]]";
} }
my $steps = 3; my $steps = 4;
my $length = undef; my $length = undef;
if (defined $args[0]) { if (defined $args[0]) {
@ -183,10 +184,7 @@ sub wordmorph {
} }
when ('custom') { when ('custom') {
if (@args != 2) { return "Usage: wordmorph custom <word1> <word2>" if @args != 2;
return "Usage: wordmorph custom <word1> <word2>";
}
return DB_UNAVAILABLE if not $self->{db}; return DB_UNAVAILABLE if not $self->{db};
my $morph = eval { makemorph($self->{db}, $args[0], $args[1]) } or return $@; my $morph = eval { makemorph($self->{db}, $args[0], $args[1]) } or return $@;
$self->{$channel}->{morph} = $morph; $self->{$channel}->{morph} = $morph;
@ -261,7 +259,7 @@ sub load_db {
my ($self) = @_; my ($self) = @_;
if (not -e $self->{db_path}) { if (not -e $self->{db_path}) {
die "Word morph database not available; run `wordmorph_gendb` to build it.\n"; die "Word morph database not available; run `/misc/wordmorph/wordmorph-mkdb` to create it.\n";
} }
return retrieve($self->{db_path}); return retrieve($self->{db_path});
@ -302,10 +300,26 @@ sub form_hint {
return $hint; return $hint;
} }
sub compare_suffix {
my ($word1, $word2) = @_;
my $length = 0;
for (my $i = length($word1) - 1; $i >= 0; --$i) {
if (substr($word1, $i, 1) eq substr($word2, $i, 1)) {
$length++;
} else {
last;
}
}
return $length;
}
sub make_morph_by_steps { sub make_morph_by_steps {
my ($self, $db, $steps, $length) = @_; my ($self, $db, $steps, $length) = @_;
$length //= int(rand(4)) + 4; $length //= int(rand(3)) + 5;
my @words = keys %{$db->{$length}}; my @words = keys %{$db->{$length}};
my $word = $words[rand $#words]; my $word = $words[rand $#words];
@ -326,6 +340,7 @@ sub make_morph_by_steps {
my $try = eval { my $try = eval {
my $left = $morph->[0]; my $left = $morph->[0];
die if compare_suffix($left, $word) >= 2;
[transform($left, $word, $db->{length $left})] [transform($left, $word, $db->{length $left})]
} or next; } or next;
@ -348,14 +363,9 @@ sub make_morph_by_steps {
sub makemorph { sub makemorph {
my ($db, $left, $right) = @_; my ($db, $left, $right) = @_;
die "The length of given words are not equal.\n" if length($left) != length($right); die "The length of given words are not equal.\n" if length($left) != length($right);
$left = lc $left;
$right = lc $right;
my $list = $db->{length $left}; my $list = $db->{length $left};
my $morph = eval { [transform($left, $right, $list)] } or die $@; my $morph = eval { [transform(lc $left, lc $right, $list)] } or die $@;
return $morph; return $morph;
} }

View File

@ -25,8 +25,8 @@ use PBot::Imports;
# These are set by the /misc/update_version script # These are set by the /misc/update_version script
use constant { use constant {
BUILD_NAME => "PBot", BUILD_NAME => "PBot",
BUILD_REVISION => 4580, BUILD_REVISION => 4581,
BUILD_DATE => "2022-08-31", BUILD_DATE => "2022-09-04",
}; };
sub initialize {} sub initialize {}