App-Greple-wordle

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Perl extension App-Greple-wordle

1.00 2026-09-14T10:40:34Z

    - Make NYT the default dataset
    - Fetch NYT answers not included in the dataset with --compat
    - Update NYT answers until 2026-09-13
    - Show previous attempts together with the latest one (--history)
    - Show words and keymap in upper case
    - Use index modulo answer count for out-of-range index
    - Fix hint command before any guess and debug command
    - Do not use black color for hint words
    - Remove legacy word list modules
    - Require Perl 5.24

0.13 2025-11-11T09:15:57Z

    - Add --data option to support multiple word datasets
    - Add ORIGINAL and NYT dataset modules
    - Improve POD documentation
    - Add Data::Section::Simple dependency

MANIFEST  view on Meta::CPAN

README.md
cpanfile
lib/App/Greple/wordle.pm
lib/App/Greple/wordle/NYT.pm
lib/App/Greple/wordle/ORIGINAL.pm
lib/App/Greple/wordle/game.pm
minil.toml
t/00_compile.t
t/01_nyt_fetch.t
t/02_setup_fetch.t
t/03_guess_color.t
t/04_default_data.t
META.yml
MANIFEST

lib/App/Greple/wordle.pm  view on Meta::CPAN

    say $game->result;
}

sub check {
    my $word = lc s/\n//r;
    if (not $word_all{$word}) {
	command($word) or respond $app->wrong;
	$_ = '';
    } else {
	# show previous attempts above the line greple prints
	say for $app->history ? $game->guess_color(@{$game->attempts}) : ();
	$game->try($word);
	# greple matches case-insensitively, so show the word in upper case
	$_ = uc $_;
    }
}

sub command {
    my $word = shift;
    my @cmd = split ' ', $word or return;
    my @word = @word_all;

lib/App/Greple/wordle/NYT.pm  view on Meta::CPAN

gouts gouty goved goves gowan gowds gowfs gowks gowls gowns goxes goyim goyle 
graal grabs grace grade grads graff graft grail grain graip grama grame gramp 
grams grana grand grano grans grant grape graph grapy grasp grass grata grate 
grats grave gravs gravy grays graze great grebe grebo grece greed greek green 
grees greet grege grego grein grens greps grese greve grews greys grice gride 
grids grief griff grift grigs grike grill grime grimy grind grins griot gripe 
grips gript gripy grise grist grisy grith grits grize groan groat grody grogs 
groin groks groma groms grone groof groom grope gross grosz grots grouf group 
grout grove grovy growl grown grows grrls grrrl grubs grued gruel grues grufe 
gruff grume grump grund grunt gryce gryde gryke grype grypt guaco guana guano 
guans guard guars guava gubba gucks gucky gudes guess guest guffs gugas guggl 
guide guido guids guild guile guilt guimp guiro guise gulab gulag gular gulas 
gulch gules gulet gulfs gulfy gulls gully gulph gulps gulpy gumbo gumma gummi 
gummy gumps gunas gundi gundy gunge gungy gunks gunky gunny guppy guqin gurdy 
gurge gurks gurls gurly gurns gurry gursh gurus gushy gusla gusle gusli gussy 
gusto gusts gusty gutsy gutta gutty guyed guyle guyot guyse gwine gyals gyans 
gybed gybes gyeld gymps gynae gynie gynny gynos gyoza gypes gypos gyppo gyppy 
gypsy gyral gyred gyres gyron gyros gyrus gytes gyved gyver gyves haafs haars 
haats habit hable habus hacek hacks hacky hadal haded hades hadji hadst haems 
haere haets haffs hafiz hafta hafts haggs haham hahas haick haika haiks haiku 
hails haily hains haint hairs hairy haith hajes hajis hajji hakam hakas hakea 

lib/App/Greple/wordle/NYT.pm  view on Meta::CPAN

quake gofer haunt whole savvy omega assay frill banjo daunt lumpy rigid stork 
groan coral imbue nasal minty south nomad kefir knell level matte lousy issue 
rowdy llama extol ratty union spore mirth annex tower split graft elate petal 
least might fetch blend drift bulge tenor chirp trick pouty chair throb nadir 
noisy along lefty teeth knife later defer coven quill mouth blunt drape dally 
fritz gooey civil geese spoil width spasm relay plane amuse nylon annoy hardy 
lever stack wound beard forum spoof catty gross haven ideal limbo detox stunt 
drill tuber gauge plump fetid holly glare lathe abhor motel rabid awoke venue 
short guise peril arise fugue tabby gizmo deuce tinge lurid clung wield clamp 
opine maker grave vowel thick bunny dough plead hovel remit colic gruff muggy 
leach cacti haste tulip among waist flute gravy snide erase guess truck miser 
swing dodgy segue grass rugby myrrh white quilt conch glint spool prism speed 
batch abbot fruit decor siren fable proof sitar posse filly oomph pecan blast 
eight manic quark trial gumbo avoid chasm racer fiery sumac waxen sully cubic 
clink baron cliff strut freak dusky cruel flaky jumbo allot spiny cigar weigh 
chide swoop gavel bleat embed cello scene vegan surge mooch bloom skull roost 
squad mogul hoist stank awake guava attic buyer shred lance dizzy hydra fluke 
slime linen theft sheep gunky vogue lobby hasty shoal teddy smell eaten ankle 
grade drama clasp amply rehab oasis slick basil serif brood wiser befit ivory 
afoot chump comet swamp fizzy sober singe sandy envoy sworn dense inlet laden 
carom prude alley elfin cycle begun cubit belle toady stand weave clump snore 

lib/App/Greple/wordle/ORIGINAL.pm  view on Meta::CPAN

forgo forte forth forty forum found foyer frail frame frank fraud freak freed 
freer fresh friar fried frill frisk fritz frock frond front frost froth frown 
froze fruit fudge fugue fully fungi funky funny furor furry fussy fuzzy gaffe 
gaily gamer gamma gamut gassy gaudy gauge gaunt gauze gavel gawky gayer gayly 
gazer gecko geeky geese genie genre ghost ghoul giant giddy gipsy girly girth 
given giver glade gland glare glass glaze gleam glean glide glint gloat globe 
gloom glory gloss glove glyph gnash gnome godly going golem golly gonad goner 
goody gooey goofy goose gorge gouge gourd grace grade graft grail grain grand 
grant grape graph grasp grass grate grave gravy graze great greed green greet 
grief grill grime grimy grind gripe groan groin groom grope gross group grout 
grove growl grown gruel gruff grunt guard guava guess guest guide guild guile 
guilt guise gulch gully gumbo gummy guppy gusto gusty gypsy habit hairy halve 
handy happy hardy harem harpy harry harsh haste hasty hatch hater haunt haute 
haven havoc hazel heady heard heart heath heave heavy hedge hefty heist helix 
hello hence heron hilly hinge hippo hippy hitch hoard hobby hoist holly homer 
honey honor horde horny horse hotel hotly hound house hovel hover howdy human 
humid humor humph humus hunch hunky hurry husky hussy hutch hydro hyena hymen 
hyper icily icing ideal idiom idiot idler idyll igloo iliac image imbue impel 
imply inane inbox incur index inept inert infer ingot inlay inlet inner input 
inter intro ionic irate irony islet issue itchy ivory jaunt jazzy jelly jerky 
jetty jewel jiffy joint joist joker jolly joust judge juice juicy jumbo jumpy 

lib/App/Greple/wordle/ORIGINAL.pm  view on Meta::CPAN

resin whole hunch pixel polar hotel sword cleat mango rumba puffy filly billy 
leash clout dance ovate facet chili paint liner curio salty audio snake fable 
cloak navel spurt pesto balmy flash unwed early churn weedy stump lease witty 
wimpy spoof saner blend salsa thick warty manic blare squib spoon probe crepe 
knack force debut order haste teeth agent widen icily slice ingot clash juror 
blood abode throw unity pivot slept troop spare sewer parse morph cacti tacky 
spool demon moody annex begin fuzzy patch water lumpy admin omega limit tabby 
macho aisle skiff basis plank verge botch crawl lousy slain cubic raise wrack 
guide foist cameo under actor revue fraud harpy scoop climb refer olden clerk 
debar tally ethic cairn tulle ghoul hilly crude apart scale older plain sperm 
briny abbot rerun quest crisp bound befit drawn suite itchy cheer bagel guess 
broad axiom chard caput leant harsh curse proud swing opine taste lupus gumbo 
miner green chasm lipid topic armor brush crane mural abled habit bossy maker 
dusky dizzy lithe brook jazzy fifty sense giant surly legal fatal flunk began 
prune small slant scoff torus ninny covey viper taken moral vogue owing token 
entry booth voter chide elfin ebony neigh minim melon kneed decoy voila ankle 
arrow mushy tribe cease eager birth graph odder terra weird tried clack color 
rough weigh uncut ladle strip craft minus dicey titan lucid vicar dress ditch 
gypsy pasta taffy flame swoop aloof sight broke teary chart sixty wordy sheer 
leper nosey bulge savor clamp funky foamy toxic brand plumb dingy butte drill 
tripe bicep tenor krill worse drama hyena think ratio cobra basil scrum bused 

lib/App/Greple/wordle/game.pm  view on Meta::CPAN

    my $answer = shift;
    my %a = map { $_ => 1 } my @a = $answer =~ /./g;
    map {
	my @b = /./g;
	join '', pairwise {
	    $a eq $b ? 'G' : $a{$b} ? 'Y' : 'K'
	} @a, @b;
    } @_;
}

my %guess_color = (
    G => '555/#6aaa64',
    Y => '555/#c9b458',
    K => '555/#787c7e',
    );

sub guess_color {
    my $obj = shift;
    my @result = _result(map lc, $obj->answer, @_);
    map {
	my @c = shift(@result) =~ /./g;
	my @w = /./g;
	join '', pairwise { colorize($guess_color{$a}, uc $b) } @c, @w;
    } @_;
}

######################################################################
# hint
######################################################################

my %hint_color = (
    G => 'G',
    Y => 'Y',

t/03_guess_color.t  view on Meta::CPAN

# build expected string from a word and its G/Y/K result
sub expect {
    my($word, $result) = @_;
    my @c = $result =~ /./g;
    my $i = 0;
    join '', map { colorize($color{$c[$i++]}, uc $_) } $word =~ /./g;
}

my $game = App::Greple::wordle::game->new(answer => 'cigar');

is_deeply [ $game->guess_color('rebus') ], [ expect('rebus', 'YKKKK') ],
    'letter in the answer is yellow, others are gray';

is_deeply [ $game->guess_color('crack') ], [ expect('crack', 'GYYYK') ],
    'right position is green, repeated letter is yellow';

is_deeply [ $game->guess_color('cigar') ], [ expect('cigar', 'GGGGG') ],
    'correct answer is all green';

is_deeply [ $game->guess_color('rebus', 'cigar') ],
    [ expect('rebus', 'YKKKK'), expect('cigar', 'GGGGG') ],
    'multiple words';

is_deeply [ $game->guess_color('REBUS') ], [ expect('REBUS', 'YKKKK') ],
    'upper case word';

# keymap and word list are shown in upper case
sub plain { (my $s = shift) =~ s/\e\[[\d;]*[mK]//g; $s }
$game->try('rebus');
is plain($game->keymap), join('', 'A' .. 'Z'), 'keymap is upper case';
is_deeply [ map { plain($_) } $game->hint_color('cigar', 'rebus') ],
    [ 'CIGAR', 'REBUS' ], 'hint words are upper case';

done_testing;



( run in 3.407 seconds using v1.01-cache-2.11-cpan-5e09290becf )