Word Guess
by sloprun seed
2026-08-14
0 reported it broke · the ▶ count is distinct visitors who ran it, counted once each, anonymously
Five letters, six tries, and a counter that tells you exactly how much you still don't know: the page opens mid-round with an opening guess already scored on the board, and beside it sits the honest number — how many of the 815 built-in answers are still consistent with the colours you can see. Watch it collapse (815 → 41 → 6 → 1) and the game stops feeling like luck and starts feeling like search. Try Suggest a guess: it scores every word by how far it would cut the remaining candidates on average, tells you what it expects to be left with, and played straight through it cracks all 815 answers in five guesses or fewer, averaging a shade over three. Word lists, scorer and solver all run offline inside this one file, and the end-of-round grid is just there to look at — no share button, no clipboard, nothing to post.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Word Guess — sloprun.dev</title>
<style>
/* ── sloprun design tokens (verbatim from demos/tokens.css) ───────────────── */
:root {
--bg: #F6F6F3; /* neutral paper, not cream */
--surface: #FFFFFF;
--ink: #1A1D21;
--muted: #5A6068;
--line: #E3E2DC;
--accent: #C05600; /* phosphor amber, darkened for light bg */
--accent-soft: #FFF3E6;
--run: #1A7F37; /* earned green */
--run-soft: #E7F4EA;
--danger: #C93C37;
--radius: 10px;
--font-sans: system-ui, -apple-system, "Segoe UI", sans-serif;
--font-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #14161A; --surface: #1C1F26; --ink: #E8E6E1; --muted: #9AA0A8;
--line: #2A2E36; --accent: #FFB454; --accent-soft: #2A2118;
--run: #3FB950; --run-soft: #16281B; --danger: #F47067;
}
}
:root[data-theme="dark"] {
--bg: #14161A; --surface: #1C1F26; --ink: #E8E6E1; --muted: #9AA0A8;
--line: #2A2E36; --accent: #FFB454; --accent-soft: #2A2118;
--run: #3FB950; --run-soft: #16281B; --danger: #F47067;
}
body { background: var(--bg); color: var(--ink); font-family: var(--font-sans); }
/* ── end tokens ───────────────────────────────────────────────────────────── */
/* demo-local additions (alpha shadows + tile inks; tokens are opaque hex) */
:root {
--shadow: 0 1px 2px rgba(26,29,33,.06);
--lift: 0 8px 24px rgba(26,29,33,.10);
--ok-fg: #FFFFFF;
--near-fg: #FFFFFF;
--off-bg: #6F6D66;
--off-fg: #FFFFFF;
--off-key: #6F6D66;
--empty: #FFFFFF;
--ring: rgba(192,86,0,.30);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--shadow: 0 1px 2px rgba(0,0,0,.35);
--lift: 0 8px 24px rgba(0,0,0,.45);
--ok-fg: #0C1A10;
--near-fg: #2A1B05;
--off-bg: #343943;
--off-fg: #9AA0A8;
--off-key: #2E323B;
--empty: #1C1F26;
--ring: rgba(255,180,84,.35);
}
}
:root[data-theme="dark"] {
--shadow: 0 1px 2px rgba(0,0,0,.35);
--lift: 0 8px 24px rgba(0,0,0,.45);
--ok-fg: #0C1A10;
--near-fg: #2A1B05;
--off-bg: #343943;
--off-fg: #9AA0A8;
--off-key: #2E323B;
--empty: #1C1F26;
--ring: rgba(255,180,84,.35);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body { min-height: 100%; overflow-x: hidden; }
.wrap {
max-width: 782px; margin: 0 auto; padding: 22px 16px 26px;
display: flex; flex-direction: column; gap: 16px;
}
/* ── header ───────────────────────────────────────────────────────────────── */
h1 {
margin: 0 0 6px; font-family: var(--font-mono);
font-size: clamp(26px, 6vw, 36px); letter-spacing: -.03em; line-height: 1; font-weight: 700;
}
.lede { margin: 0; max-width: 64ch; color: var(--muted); font-size: 14.5px; line-height: 1.55; }
.lede b { font-weight: 600; }
.lede .g { color: var(--run); font-family: var(--font-mono); font-weight: 600; }
.lede .a { color: var(--accent); font-family: var(--font-mono); font-weight: 600; }
/* ── layout ───────────────────────────────────────────────────────────────── */
.stage {
display: grid; gap: 16px; align-items: start;
grid-template-columns: minmax(0, 1fr) 260px;
grid-template-areas: "play panel";
}
.playcol { grid-area: play; min-width: 0; display: flex; flex-direction: column; gap: 10px; align-items: center; }
.panel { grid-area: panel; display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 760px) {
.stage { grid-template-columns: minmax(0,1fr); grid-template-areas: "play" "panel"; }
.panel { width: 100%; max-width: 420px; margin: 0 auto; }
}
/* ── board ────────────────────────────────────────────────────────────────── */
.board {
display: grid; grid-template-rows: repeat(6, 1fr);
gap: clamp(4px, 1.2vw, 6px);
width: 100%; max-width: min(330px, 78vw);
}
@media (max-width: 400px) { .board { max-width: 100%; } }
.row { display: grid; grid-template-columns: repeat(5, 1fr); gap: clamp(4px, 1.2vw, 6px); }
.tile {
position: relative; aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center;
border: 1.5px solid var(--line); border-radius: 8px; background: var(--empty);
font-family: var(--font-mono); font-weight: 700; letter-spacing: -.02em;
font-size: clamp(19px, 5.6vw, 27px); text-transform: uppercase; line-height: 1;
transition: border-color 90ms ease, transform 90ms ease;
will-change: transform;
}
.tile.filled { border-color: var(--muted); }
.tile.pop { animation: pop 110ms ease-out; }
@keyframes pop { 0% { transform: scale(1); } 45% { transform: scale(1.08); } 100% { transform: scale(1); } }
.tile.flip { animation: flip 380ms ease-in-out; }
@keyframes flip { 0% { transform: rotateX(0deg); } 50% { transform: rotateX(90deg); } 100% { transform: rotateX(0deg); } }
.tile[data-s="2"] { background: var(--run); border-color: var(--run); color: var(--ok-fg); }
.tile[data-s="1"] { background: var(--accent); border-color: var(--accent); color: var(--near-fg); }
.tile[data-s="0"] { background: var(--off-bg); border-color: var(--off-bg); color: var(--off-fg); }
.row.bad { animation: shake 380ms ease; }
@keyframes shake {
10%,90% { transform: translateX(-2px); } 20%,80% { transform: translateX(4px); }
30%,50%,70% { transform: translateX(-6px); } 40%,60% { transform: translateX(6px); }
}
.tile.hop { animation: hop 460ms ease; }
@keyframes hop {
0% { transform: translateY(0); } 22% { transform: translateY(-12px); }
44% { transform: translateY(0); } 60% { transform: translateY(-5px); } 100% { transform: translateY(0); }
}
/* ── toast ────────────────────────────────────────────────────────────────── */
.toast {
margin: 0; min-height: 20px; font-family: var(--font-mono); font-size: 11.5px;
letter-spacing: .05em; color: var(--muted); text-align: center; line-height: 1.6;
}
.toast.warn { color: var(--danger); }
.toast.win { color: var(--run); }
.toast b { color: var(--ink); }
/* ── keyboard ─────────────────────────────────────────────────────────────── */
.kb { width: 100%; max-width: min(430px, 100%); display: flex; flex-direction: column; gap: clamp(4px, 1.3vw, 6px); }
.krow { display: flex; gap: clamp(3px, 1.1vw, 6px); justify-content: center; }
.key {
flex: 1 1 0; min-width: 0; height: clamp(40px, 10.5vw, 50px);
display: flex; align-items: center; justify-content: center;
font-family: var(--font-mono); font-size: clamp(11px, 3vw, 14px); font-weight: 600;
text-transform: uppercase; letter-spacing: .02em;
background: var(--surface); color: var(--ink);
border: 1px solid var(--line); border-radius: 7px; box-shadow: var(--shadow);
cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
transition: background 120ms ease, color 120ms ease, border-color 120ms ease, transform 70ms ease;
padding: 0;
}
.key.wide { flex: 1.6 1 0; font-size: clamp(9px, 2.3vw, 11px); letter-spacing: .08em; }
.key:hover { border-color: var(--muted); }
.key:active { transform: translateY(1px); }
.key[data-s="2"] { background: var(--run); border-color: var(--run); color: var(--ok-fg); }
.key[data-s="1"] { background: var(--accent); border-color: var(--accent); color: var(--near-fg); }
.key[data-s="0"] { background: var(--off-key); border-color: var(--off-key); color: var(--off-fg); }
.spacer { flex: .5 1 0; }
/* ── panel boxes ──────────────────────────────────────────────────────────── */
.box {
background: var(--surface); border: 1px solid var(--line);
border-radius: var(--radius); padding: 11px 12px 12px; box-shadow: var(--shadow);
}
.box .h {
font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .14em;
text-transform: uppercase; color: var(--muted); margin-bottom: 8px;
}
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.stat { min-width: 0; }
.stat.wide { grid-column: 1 / -1; }
.sk {
display: block; font-family: var(--font-mono); font-size: 9px; letter-spacing: .12em;
text-transform: uppercase; color: var(--muted);
}
.sv {
display: block; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
font-size: 19px; font-weight: 700; letter-spacing: -.02em; margin-top: 1px; line-height: 1.2;
}
.sv.small { font-size: 13px; font-weight: 600; letter-spacing: .01em; }
.sv.ok { color: var(--run); }
.sv.warn { color: var(--danger); }
.sv.amber { color: var(--accent); }
.trail {
font-family: var(--font-mono); font-variant-numeric: tabular-nums;
font-size: 12.5px; line-height: 1.9; color: var(--ink); word-break: break-word;
}
.trail .arw { color: var(--muted); margin: 0 4px; }
.trail .n0 { color: var(--muted); }
.trail .cur { color: var(--accent); font-weight: 700; }
.note { margin: 8px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.55; }
.note b { color: var(--ink); font-family: var(--font-mono); font-weight: 600; }
/* ── buttons ──────────────────────────────────────────────────────────────── */
.acts { display: flex; gap: 8px; }
.btn {
flex: 1 1 0; appearance: none; cursor: pointer; font-family: var(--font-sans);
font-size: 13px; font-weight: 600; color: var(--ink); background: var(--surface);
border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px; box-shadow: var(--shadow);
transition: background 120ms ease, border-color 120ms ease, transform 70ms ease;
white-space: nowrap;
}
.btn:hover:not(:disabled) { border-color: var(--muted); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn.primary { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.hintline {
margin: 9px 0 0; font-family: var(--font-mono); font-size: 12px; line-height: 1.6;
color: var(--muted); min-height: 19px;
}
.hintline b { color: var(--accent); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
/* ── result grid ──────────────────────────────────────────────────────────── */
.grid { display: flex; flex-direction: column; gap: 3px; margin-bottom: 9px; }
.grow { display: flex; gap: 3px; }
.gcell { width: 15px; height: 15px; border-radius: 3px; background: var(--off-bg); }
.gcell[data-s="2"] { background: var(--run); }
.gcell[data-s="1"] { background: var(--accent); }
.gline {
font-family: var(--font-mono); font-variant-numeric: tabular-nums;
font-size: 12px; font-weight: 700; letter-spacing: .02em;
}
.gline.ok { color: var(--run); }
.gline.miss { color: var(--danger); }
.reveal { font-family: var(--font-mono); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--ink); }
.tally { display: flex; gap: 14px; flex-wrap: wrap; }
.tally div { min-width: 0; }
.hint {
margin: 0; font-family: var(--font-mono); font-size: 10.5px; color: var(--muted);
letter-spacing: .04em; text-align: center; line-height: 1.7;
}
.hint .sep { opacity: .45; margin: 0 5px; }
footer {
font-family: var(--font-mono); font-size: 11px; color: var(--muted);
letter-spacing: .05em; padding-top: 2px;
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.board:focus-visible { outline-offset: 6px; }
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
transition-duration: .001ms !important;
animation-duration: .001ms !important;
animation-iteration-count: 1 !important;
}
}
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>Word Guess</h1>
<p class="lede">Find the five-letter word in six tries. <span class="g">Green</span> means right letter in the right spot; <span class="a">amber</span> means right letter, wrong spot; grey means the letter isn't in the word at all. <b>An opening guess is already on the board</b> — take it from there.</p>
</header>
<div class="stage">
<div class="playcol">
<div class="board" id="board" tabindex="0" role="group" aria-label="Guess board, six rows of five letters" aria-describedby="kbhelp"></div>
<p class="toast" id="toast" role="status" aria-live="polite"></p>
<div class="kb" id="kb" role="group" aria-label="On-screen keyboard"></div>
<p class="hint" id="kbhelp">
<span>type letters</span><span class="sep">·</span><span>enter to submit</span><span class="sep">·</span><span>backspace to delete</span>
</p>
</div>
<div class="panel">
<div class="box">
<div class="h">This round</div>
<div class="stats">
<div class="stat"><span class="sk">Guess</span><span class="sv" id="stGuess">1 / 6</span></div>
<div class="stat"><span class="sk">Candidates</span><span class="sv" id="stPool">815</span></div>
<div class="stat"><span class="sk">Ruled out</span><span class="sv" id="stOut">0 letters</span></div>
<div class="stat"><span class="sk">Status</span><span class="sv small" id="stState">in play</span></div>
</div>
<div class="acts" style="margin-top:11px">
<button class="btn primary" id="newBtn" type="button">New word</button>
<button class="btn" id="giveBtn" type="button">Give up</button>
</div>
</div>
<div class="box">
<div class="h">Narrowing</div>
<div class="trail" id="trail"></div>
<p class="note">Counted live against the built-in list of <b>815</b> possible answers — every word still consistent with the colours on the board.</p>
</div>
<div class="box">
<div class="h">Solver</div>
<div class="acts">
<button class="btn" id="hintBtn" type="button">Suggest a guess</button>
</div>
<p class="hintline" id="hintOut">Scores every word by how far it would cut the candidate list, on average.</p>
</div>
<div class="box" id="resultBox" hidden>
<div class="h">Your grid</div>
<div class="grid" id="grid" aria-hidden="true"></div>
<div class="gline" id="gline"></div>
<p class="note" id="gnote"></p>
</div>
<div class="box">
<div class="h">This session</div>
<div class="stats tallywrap">
<div class="stat"><span class="sk">Played</span><span class="sv" id="tPlayed">0</span></div>
<div class="stat"><span class="sk">Solved</span><span class="sv" id="tSolved">0</span></div>
<div class="stat"><span class="sk">Streak</span><span class="sv" id="tStreak">0</span></div>
<div class="stat"><span class="sk">Avg guesses</span><span class="sv" id="tAvg">—</span></div>
</div>
</div>
</div>
</div>
<footer>demo · sloprun.dev</footer>
</div>
<div class="sr-only" role="status" aria-live="polite" id="live"></div>
<script>
(function () {
"use strict";
/* ── word data ──────────────────────────────────────────────────────────── */
var ANS_PACK =
"aboutaboveactoracuteadmitadoptadultafteragainagentagreeaheadalarmalbumalertalikealiveallowalonealongalteramong"
+ "angerangleangryankleapartappleapplyarenaarguearisearrayarrowasideassetavoidawakeawardawareawfulbaconbadgebadly"
+ "bakerbasicbasisbatchbeachbeardbeastbeganbeginbeingbellybelowbenchberrybirthblackbladeblameblankblastblendbless"
+ "blindblinkblockbloodbloomblownbluesboardbonusboostboundbrainbrakebrandbravebreadbreakbreedbrickbridebriefbring"
+ "broadbrokebrownbrushbuddybuildbuiltbunchburstbuyercabincablecandycarrycatchcauseceasechainchairchalkcharmchart"
+ "chasecheapcheatcheckcheekcheerchesschestchiefchildchillchirpchoirchokechordchorechosechunkcidercigarclaimclamp"
+ "clashclaspclasscleanclearclerkclickcliffclimbclingcloakclockclonecloseclothcloudclowncoachcoastcocoacolorcomet"
+ "comiccoralcouchcoughcouldcountcourtcovercraftcranecrashcrawlcrazycreamcreekcrispcrosscrowdcrowncruelcrushcrust"
+ "curlycurvecycledailydancedealtdebutdecaydelaydensedepthdiarydirtydoingdonordoubtdoughdozendraftdraindramadrank"
+ "drawndreamdressdrieddriftdrilldrinkdrivedronedrovedrowndustyeagereagleearlyeartheateneightelboweldereliteemail"
+ "emberemptyenjoyenterentryequalequiperroressayeventeveryexactexcelexistextrafairyfaithfalsefancyfatalfaultfavor"
+ "feastfencefeverfieldfifthfiftyfightfinalfirstflairflakeflameflashfleetfleshfloatfloodfloorflownfluidflutefocus"
+ "folksforceforthfortyforumfoundframefraudfreshfriedfrontfrostfruitfullyfunnygaugeghostgiantgivenglareglassglide"
+ "globegloryglovegoinggoosegracegradegraingrandgrantgrapegraphgraspgrassgravegreatgreengreetgriefgrillgrindgroan"
+ "groomgrossgroupgrownguardguessguestguideguildguilthabithairyhandyhappyharshhastehatchhauntheardheartheavyhedge"
+ "hellohencehobbyhoneyhonorhorsehotelhoundhousehoverhumanhumidhumorhurryidealimageindexinputissuejellyjeweljoint"
+ "judgejuicejuicykneelknifeknockknownlabellaborlargelaserlaterlaughlayerleafylearnleaseleashleastleaveledgelegal"
+ "lemonlevellightlimitlinenliverlobbylocallodgelogiclooseloserloverlowerloyalluckylunarlunchlyingmagicmajormaker"
+ "mangomaplemarchmarshmatchmayormeantmedalmediamelonmergemerrymetalmightminorminusmixermodelmoistmoneymonthmoral"
+ "motelmotormountmousemouthmoviemusicnastyneedynervenevernewernewlyninjaninthnoblenoisenoisynorthnotchnovelnurse"
+ "occuroceanofferoftenoliveonionoperaorbitorderorganotherouterownerpaintpanelpanicpaperpartypastapastepatchpatio"
+ "pausepeacepeachpearlpedalpennypetalphasephonephotopianopiecepilotpinchpizzaplaceplainplaneplankplantplateplaza"
+ "plumpplushpointpolarporchpouchpoundpowerprankpresspriceprideprimeprintpriorprizeproofproudproveprunepulsepunch"
+ "pupilpuppyqueenqueryquestqueuequickquietquiltquitequoteradarradioraiserallyranchrangerapidratiorazorreachreact"
+ "readyrealmreferrelaxrelayrenewrepayreplyresetrhinoriderridgerightrivalriverroastrobinrobotrockyrodeoroguerough"
+ "roundrouterulerrumorruralrustysaladsalonsaltysandyscalescarfscaryscenescentscoopscopescorescoutsenseserveseven"
+ "shadeshakeshallshameshapesharesharksharpshavesheepsheersheetshelfshellshiftshineshinyshirtshockshoreshortshout"
+ "shownsightsillysincesixthsixtyskateskillskirtskullslatesleepsleptsliceslideslopesmallsmartsmashsmellsmilesmoke"
+ "snacksnailsnakesolarsolidsolvesorrysoundsouthspacesparesparkspeakspeedspellspendspentspicespicyspikespillspine"
+ "spitesplitspoilspokespoonsportspraystackstaffstagestainstairstakestampstandstarestartstatesteakstealsteamsteel"
+ "steepsteersternstickstiffstillstingstinkstockstolestonestoodstoolstorestormstorystovestrawstripstuckstudystuff"
+ "stuntstylesugarsuitesunnysupersurgeswampswearsweatsweepsweetsweptswiftswingtabletakentastetastyteachtenththank"
+ "theirthemetherethesethickthiefthingthinkthirdthosethreethrowthumbtigertighttimertiredtitletoasttodaytokentooth"
+ "topictotaltouchtoughtoweltowertoxictracetracktradetrailtraintrashtreattrendtrialtricktriedtrucktrulytrunktrust"
+ "truthtuliptutortweettwicetwistultrauncleunderunionuniteuntilupperupseturbanusualvaguevalidvaluevalvevaultvenue"
+ "videovinylvirusvisitvitalvividvocalvoicevoterwagonwaistwastewatchwaterweighweirdwhalewheatwheelwherewhichwhile"
+ "whitewholewhosewiderwidthwittywomanwomenworldworryworseworstworthwouldwoundwritewrongwroteyachtyieldyoungyours"
+ "youth";
var EXT_PACK =
"abaciabackabaftabaseabashabateabbeyabbotabeamabetsabhorabideablerabodeabortabuseabutsabuzzabyssachedachesachoo"
+ "acidsacingacmesacornacresacridactedadageadaptaddedadderaddleadeptadieuadmanadmenadminadobeadoreadornadzesaegis"
+ "aeonsaerieaffixafireafootafoulagapeagateagaveagileagingagismaglowagonyaidedaidesailedaimedairedaislealderalgae"
+ "aliasalibialienalignalineallayalleyallotalloyaloesaloftalohaaloofaloudalphaaltaralthoaltosalumsamassamazeamber"
+ "ambleamebaameeramendamigoaminoamirsamissamityamourampleamplyampulamuckamuseangelangstanimeanionaniseankhsannex"
+ "annoyannulanodeanonsantedantesanticantisanvilaortaapaceaphidapingappalapronapsesapteraptlyaquaeaquasarborarced"
+ "ardorareasargonargotariasaromaarosearsonartsyascotashedashenashesaskedaskewaspenaspicassayassesassocasterastir"
+ "atlasatollatomsatoneatriaattaratticaudioauditaugeraughtaugurauntsauraeauralaurasautosavailavastaversavertavian"
+ "avowsawaitawashawingawokeaxialaxingaxiomaxlesaxonsazurebaaedbabelbabesbacksbagelbaggybailsbaitsbaizebakedbakes"
+ "baldsbaledbalesbalksbalkybalmsbalmybalsabanalbandsbandybanesbangsbanjobanksbannsbarbsbardsbaredbarerbaresbarfs"
+ "bargebarksbarnsbaronbasalbasedbaserbasesbasilbasinbasksbassibassobastebatedbatesbathebathsbatikbatonbattybauds"
+ "bawdybawlsbayedbayoubeadsbeadybeaksbeamsbeansbearsbeatsbeausbeauxbebopbecksbeechbeefsbeefybeepsbeersbeetsbefit"
+ "befogbegatbegetbegotbegunbeigebelaybelchbeliebellebellsbeltsbendsbentsberetbergsbermsberthberylbesetbesombesot"
+ "bestsbetasbevelbiblebicepbiddybidedbidesbidetbiersbiffsbightbigotbikedbikerbikesbilgebilksbillsbillybindsbinge"
+ "bingobipedbirchbirdsbisonbitesblabsblandblareblatsblazebleakbleatbleedbleepblentblestblimpblingblipsblissblitz"
+ "bloatblobsblocsblogsblondblotsblowsbluedbluerbluffbluntblurbblursblurtblushboarsboastboatsbobbybodedbodesbogey"
+ "boggybogiebogonbogusboilsboinkbolasbolesbollsboltsbondsbonedbonesboneybongobongsbonnybooedbooksboomsboonsboors"
+ "boothbootsbootyboozeboraxboredborerboresborneboronbosombossybosunbotchboughboutsbowedbowelbowerbowlsboxedboxen"
+ "boxerboxesbozosbracebractbradsbragsbraidbrashbrassbratsbravobrawlbrawnbraysbrewsbriarbribebrierbrigsbrimsbrine"
+ "brinkbrinybriskbroilbroodbrookbroombrothbrowsbruinbruntbruskbrutebucksbudgebuffsbuggybuglebulbsbulgebulgybulks"
+ "bulkybullsbullybumpsbumpybungsbunksbunnybuntsbuoysburgsburkaburlyburnsburntburpsburroburrsbusbybusedbusesbushy"
+ "bustsbutchbuttebuxombylawbytesbywaycabalcabbycacaocachecacticaddycadgecadrecagedcagescageycairncakedcakescalfs"
+ "califcalkscallscalmscalvecalyxcamelcameocampscampycanalcanedcanescannycanoecanoncantocantscapedcapercapescapon"
+ "caratcarbscardscaredcarescaretcargocarolcaromcarpicarpscartscarvecasedcasescaskscastecastscatercattycaulkcaved"
+ "cavescavilcawedcedarcededcedescellicellocellscentschadschafechaffchampchantchaoschapschaptcharscharychasmchats"
+ "cheepchefschewschewychickchidechilechilichimechimpchinachinkchinochinschipschitschivechockchompchopschowschuck"
+ "chugschumpchumschurlchurnchuteciliacinchcircacitedcitescivetciviccivilclackclamsclangclankclansclapsclawscleat"
+ "clefscleftclewsclimeclinkclipscliptclitsclodsclogsclompclopsclotscloutclovecloysclubscluckcluedcluesclumpclung"
+ "clunkclviiclxiiclxivclxixclxvicoalscoatscobracoccicockscockycodascodedcodescodexcoedscoifscoilscoinscokedcokes"
+ "colascoldscoliccoloncoltscomascombocombscomercomescomfycommacompoconchcondoconescongaconicconkscontdcooedcooks"
+ "cookycoolscoonscoopscootscopedcopescopracopsecordscoredcorescorkscormscornscornycostscotescoupecovencovescovet"
+ "coveycowedcowercowlscoyercoylycozencrabscragscrampcramscrankcrapecrasscratecravecrawscrayscrazecreakcredocreed"
+ "creelcreepcrepecreptcresscrestcrewscribscrickcriedcriercriescrimecrimpcroakcrocicrockcronecronycrookcrooncrops"
+ "croupcrowscrudecruetcruftcrumbcryptcubedcubescubiccubitcuffscuingcullscultscumincupidcurbscurdscuredcurercures"
+ "curiecuriocurlscurrycursecurstcurvycushycuspscutercutupcyniccystsczarsdachadaddydadosdaffydairydaisydalesdally"
+ "damesdampsdandydareddaresdarnsdartsdateddatesdatumdaubsdauntdavitdawnsdazeddazesddingdealsdeansdearsdeathdebar"
+ "debitdebtsdebugdecafdecaldecksdecordecoydecrydeedsdeemsdeepsdeersdeferdeicedeifydeigndeismdeitydelisdellsdelta"
+ "delvedemondemosdemurdenimdentsdepotderbydesksdeterdetoxdeucedevildhotidialsdiceddicesdiceydickydictadietsdiffs"
+ "digitdikeddikesdillsdillydimerdimesdimlydineddinerdinesdingodingsdingydinkydiodedirerdirgedirksdiscodiscsdisks"
+ "ditchdittodittydivandivasdiveddiverdivesdivotdivvydizzydjinndocksdodgedodgydodosdoersdoffsdoggydogiedogmadoily"
+ "doleddolesdollsdollydoltsdomeddomesdonutdoomsdoorsdopeddopesdopeydorksdorkydormsdoseddosesdoteddotesdottydouse"
+ "dovesdowdydoweldownsdownydowrydowsedoyendozeddozesdrabsdragsdrakedramsdrapedrawldrawsdraysdreaddregsdrierdries"
+ "drilydripsdroiddrolldrooldroopdropsdrossdrubsdrugsdruiddrumsdrunkdryaddryerdrylyducalducatduchyducksductsduded"
+ "dudesduelsduetsdukesdullsdullydummydumpsdumpyduncedunesdungsdunksdunnodupeddupesduskydustsduvetdwarfdwelldwelt"
+ "dyersdyingdykedearlsearnseasedeaseleaseseatereavesebbedebonyechosedemaedgededgeredgesedictedifyeditseerieegged"
+ "egreteiderejectekingelateelectelegyelfinelideelopeeludeelvesembedemceeemendemeryemirsemitsemojiemoteenactended"
+ "endowendueenemaenemyennuienrolensueenureenvoyepicsepochepoxyeraseerecterodeerrederuptesteretherethicethoseuros"
+ "evadeevensevictevilsevokeewersexaltexamsexecsexertexileexitsexpelexposextolexudeexulteyingfablefacedfacesfacet"
+ "factsfadedfadesfagotfailsfaintfairsfakedfakerfakesfakirfallsfamedfangsfarcefaredfaresfarmsfastsfatedfatesfatty"
+ "faunafaunsfawnsfaxedfaxesfazedfazesfearsfeatsfecalfecesfeedsfeelsfeignfeintfellsfelonfeltsfemurfendsferalferns"
+ "ferryfestsfetalfetchfetedfetidfetusfeudsfewerfezesfiatsfiberfichefiefsfiendfieryfifesfilchfiledfilesfiletfills"
+ "fillyfilmsfilmyfilthfinchfindsfinedfinerfinesfinisfinksfinnyfiordfiredfiresfirmsfirthfishyfistsfitlyfiverfives"
+ "fixedfixerfixesfizzyfjordflackflagsflailflakyflankflapsflareflaskflatsflawsflaysfleasfleckfleesflickfliedflier"
+ "fliesflingflintflipsflirtflitsflockfloesflogsflopsfloraflossflourfloutflowsflubsfluesfluffflukeflukyflumeflung"
+ "flunkflushflybyflyerfoalsfoamsfoamyfocalfogeyfoggyfoilsfoistfoldsfoliofollyfondufontsfoodsfoolsfootsforayfords"
+ "foresforgeforgoforksformsfortefortsfoulsfountfoursfowlsfoxedfoxesfoyerfrackfragsfrailfrancfrankfratsfraysfreak"
+ "freedfreerfreesfretsfriarfrierfriesfrillfriskfrizzfrockfrogsfrondfrothfrownfrozefrumpfryerfudgefuelsfuguefulls"
+ "fumedfumesfundsfungifunksfunkyfurlsfurorfurryfurzefusedfusesfussyfustyfutonfuzedfuzesfuzzygabbygablegaffegaffs"
+ "gagedgagesgailygainsgaitsgalasgalesgallsgamedgamergamesgameygamingammagamutgangsgapedgapesgarbsgasesgaspsgassy"
+ "gatedgatesgaudygauntgauzegauzygavelgawksgawkygayergaylygazedgazergazesgearsgeckogeeksgeekygeesegeldsgelidgenes"
+ "geniegeniigenregentsgenusgeodegermsgetupghoulgibedgibesgiddygiftsgildsgillsgiltsgimmegimpygipsygirdsgirlsgirth"
+ "girtsgismogivesgizmogladegladsglandglazegleamgleanglensglintglitzgloatglobsgloomglossglowsgluedgluesglueygluts"
+ "glyphgnarlgnashgnatsgnawngnawsgnomegoadsgoalsgoatsgodlygofergoldsgolfsgollygonadgonergongsgonksgonnagonzogoods"
+ "goodygooeygoofsgoofygooksgoonsgoredgoresgorgegorpsgorsegottagougegourdgoutygownsgrabsgradsgraftgrailgramsgrate"
+ "gravygraysgrazegrebegreedgrepsgreysgridsgrimegrimygrinsgripegripsgristgritsgroingroksgropegroutgrovegrowlgrows"
+ "grubsgruelgruesgruffgruntguanoguavaguileguisegulaggulchgulfsgullsgullygulpsgumbogummygunnyguppygurusgushygusto"
+ "gustsgustygutsyguyedgybedgybesgypsygyroshackshaftshaikuhailshairshakeshaledhalerhaleshallshalonhaloshaltshalve"
+ "handshangshankshankyhardyharedharemharesharksharmsharpsharpyharryhartshaspshastyhatedhaterhateshaulshavenhaves"
+ "havochawedhawkshayedhazedhazelhazesheadsheadyhealsheapshearsheathheatsheaveheedsheelsheftsheftyheirsheisthelix"
+ "helmshelothelpshennaherbsherdsheronheroshertzhewedhewerhexedhexeshickshidedhideshighshikedhikerhikeshillshilly"
+ "hiltshindshingehingshintshippohippyhiredhireshitchhivedhiveshoagyhoardhoaryhoboshockshoganhoisthokeyhokumholds"
+ "holedholeshollyhomedhomerhomeshomeyhomiehonedhoneshonkshoochhoodshooeyhoofshookshookyhoopshootshopedhopeshorde"
+ "hornshorsyhosedhoseshostshotlyhourshovelhowdyhowlshubbyhuffshuffyhugerhulashulkshullshumpshumushunchhunkshunts"
+ "hurlshurtshuskshuskyhutchhydrahyenahyinghymenhymnshypedhyperhypeshyposiambsiciericilyicingiconsideasidiomidiot"
+ "idledidleridlesidolsidyllidylsiglooikonsillusimamsimbedimbueimpelimplyinaneinaptinboxincedincurindueineptinert"
+ "inferinfixingotinkedinlayinletinnerinsetintelinterintroinureioctliotasirateirkedironsironyislesisletitchyitems"
+ "iviesivoryjabotjacksjadedjadesjailsjambsjapanjapedjapesjauntjawedjazzyjeansjeepsjeersjehadjellojellsjerksjerky"
+ "jestsjettyjibedjibesjiffyjihadjiltsjimmyjinnijinnsjivedjivesjocksjohnsjoinsjoistjokedjokerjokesjollyjoltsjoule"
+ "joustjowlsjoyedjulepjumbojumpsjumpyjuncojunksjunkyjurorkabobkapokkaputkaratkarmakayakkazookebabkebobkeelskeens"
+ "keepsketchkeyedkhakikhanskickskickykiddokiddykillskilnskiloskiltskindakindskingskinkskioskkitedkiteskittykiwis"
+ "klugeklutzknackknavekneadkneedkneesknellkneltknitsknobsknollknotsknowskoalakoanskookskookykopekkronekudoskudzu"
+ "labialacedlaceslacksladedladenladesladlelagerlairslaitylakeslamaslambslamedlamerlameslampslancelandslaneslanky"
+ "lapellapselarchlardslargolarkslarvalasedlaseslassolastslatchlatexlathelathslattelaudslawnslaxerlaxlylazedlazes"
+ "leachleadsleafsleaksleakyleansleapsleaptleechleeksleersleeryleftsleftyleggylegitlemmalemmelemurlendsleperletup"
+ "leveeleverlexerliarslibellicitlicksliegeliensliferliftslikedlikenlikerlikeslilacliltslimbolimbslimedlimeslimns"
+ "limoslimpslinedlinerlineslingolinkslintslionslipidliraslislelispslistsliterlithelivedlivenliveslividllamallano"
+ "loadsloafsloamyloansloathlobedlobeslockslocuslodesloftsloftylogesloginlogonlogosloinslollslonerlongslookslooms"
+ "loonsloonyloopsloopylootslopedlopeslordslorryloseslottolotuslouselousyloutslovedloveslowedlowlyloxesluauslubed"
+ "lubeslucidluckslucrelullslumpslumpylungelungslupinlupuslurchluredluresluridlurkslustsluteslxviilymphlynchlyres"
+ "lyricmacawmacedmacesmachomacromadammadlymagmamaidsmailsmaimsmainsmaizemakesmalesmallsmaltsmamasmambomammamanes"
+ "mangamangemangymaniamanicmanlymannamanormansemaresmariamarksmarrymartsmasksmasonmastsmatedmatesmattemattsmatzo"
+ "maulsmauvemavenmavinmaxedmaxesmaximmaybemazesmealsmealymeansmeatsmeatymeccameetsmeldsmeltsmemesmemosmendsmenus"
+ "meowsmercymeresmeritmesasmessymetedmetermetesmetromewedmewlsmiaowmicramiddymidgemidstmiensmiffsmikedmikesmilch"
+ "milermilesmilfsmilksmilkymillsmimedmimesmimicmincemindsminedminerminesminimminisminksmintsmintymiredmiresmirth"
+ "misdomisermistsmistymitermitesmittsmixedmixesmoansmoatsmochamocksmodalmodemmodesmogulmoiremolarmoldsmoldymoles"
+ "mollsmoltsmommamommymonksmoochmoodsmoodymooedmoonsmoorsmoosemootsmopedmopesmoraymoresmornsmoronmoseymossymotes"
+ "mothsmotifmottomoundmournmousymovedmovermovesmowedmowermucksmuckymucusmuddymuffsmuftimuggymulchmulesmullsmulti"
+ "mummymumpsmunchmungsmuralmurksmurkymusedmusesmushymuskymussymustsmustymutedmutermutesmuttsmynahmynasmyrrhmyths"
+ "nabobnachonacrenadirnaiadnailsnaivenakednamednamesnannynapesnappynarcsnarksnasalnatalnattynavelnavesnearsneath"
+ "necksneedsneighnerdsnerdynervynestsnewelnewsynewtsnexusnicernichenicksnieceniftynightnimbininesninnynippyniter"
+ "nitesnixednixesnoblynodalnoddynodesnoelsnomadnoncenooksnoosenormsnosednosesnoseynotednotesnounsnovaenovasnoway"
+ "nudernudgenukednullsnumbsnuttynylonnymphoakenoakumoaredoasesoasisoatenoathsobeseobeysobitsoboesocherochreoctal"
+ "octetodderoddlyodiumodorsoffaloffedogledoglesogresoiledoinksokaysokrasoldenolderoldieomegaomensomitsonsetoozed"
+ "oozesopalsopensopineopiumoptedopticoralsorateosierotteroughtounceoustsoutdooutedoutgoovalsovaryovensoversovert"
+ "ovoidovuleowingowletownedoxbowoxideozonepacedpacespackspactspaddypadrepaeanpaganpagedpagerpagespailspainspairs"
+ "paledpalerpalespallspalmspalmypalsypandapanespangspansypantspantypapalpapaspapawparchparedparesparkaparksparry"
+ "parsepartspashapastspastypatespathspatsypattypavedpavespawedpawlspawnspayedpayeepayerpeakspealspearspeasepecan"
+ "peckspeekspeelspeepspeerspeevepekoepeltspenalpencependspenespeonspeonypeppyperchperilperksperkypermspeskypesos"
+ "pestspeterpettypeweephagephialphishphloxphonyphylapickspickypierspietypiggypigmypiingpikedpikerpikespilafpilau"
+ "pilawpiledpilespillspinedpinespingspinkspinkypintopintspinuppiouspipedpiperpipespipitpiquepitchpithypitonpivot"
+ "pixelpixieplaidplaitplansplayspleadpleaspleatpliedpliesplodsplonkplopsplotsplowsployspluckplugsplumbplumeplums"
+ "plunkpoachpockspodiapoemspoesypoetspoisepokedpokerpokespokeypoledpolespoliopolkapollspolyppondsponespoochpoohs"
+ "poolspoopspopespoppapoppyporedporesportsposedposerposespositpossepostspottypourspoutspoxesprateprawnprayspreen"
+ "prepspreyspricypriedpriesprigsprimpprismprivyprobeprodsprofspromopromsproneprongpropsproseprosyprowlprowsproxy"
+ "prudepsalmpshawpsychpubicpuckspudgypuffspuffypukedpukespullspulpspulpypumaspumpspunkspuntspupaepupalpupaspuree"
+ "purerpurgepurlspurrspursepushyputtsputtypwnedpygmypylonpyrespyxesquackquadsquaffquailquakequalmquarkquartquash"
+ "quasiquaysquellquidsquillquinequipsquirequirkquitsquoitquotaquothrabbirabidracedracerracesracksradiiradonrafts"
+ "ragasragedragesraidsrailsrainsrainyrajahrajasrakedrakesrampsrangyranksrantsraredrarerraresraspsraspyratedrates"
+ "rattyravedravelravenravesrawerrayonrazedrazesreadsrealsreamsreapsrearmrearsrebelrebusrebutrecaprectarecurredid"
+ "reedsreedyreefsreeksreelsreeverefitregalrehabreignreinsrelicremitrenalrendsrentsreorgrepelreranrerunresinrests"
+ "retchretryreuserevelrevuerheasrheumrhymericedricesricksridesriferriffsriftsrigidrigorriledrilesrillsrimedrimes"
+ "rindsringsrinksrinseripenriperrisenriserrisesrisksriskyritesritzyrivenrivetroachroadsroamsroansroarsrobedrobes"
+ "rocksrogerroilsrolesrollsromanrompsroodsroofsrooksroomsroomyroostrootsropedropesrosesrosinrotorrougerouserouts"
+ "rovedroverrovesrowdyrowedrowelrowerroyalrubesrubleruddyruderruffsrugbyruingruinsruledrulesrumbarummyrumpsrunes"
+ "rungsrunicrunnyruntsrupeerusesrusksrustssablesackssadessadlysafersafessagassagersagessahibsailssaintsaithsales"
+ "sallysalsasaltssalvesambasamessandssanersappysareesarissassysataysatedsatessatinsatyrsaucesaucysaunasavedsaver"
+ "savessavorsavvysawedsaxesscabsscadsscagsscaldscalpscalyscampscamsscansscantscarescarsscatsschwascionscoffscold"
+ "sconescootscornscourscowlscowsscramscrapscrewscripscrodscrogscrubscubascudsscuffscullscumsscurfsealsseamsseamy"
+ "searsseatssectssedansedgeseedsseedyseeksseemsseepsseerssegueseizesellssemissendssennasepalsepiaseptasererserfs"
+ "sergeserumservosetupseversewedsewersexedsexesshackshadsshadyshaftshahsshakyshaleshaltshamsshankshardshawlsheaf"
+ "shearshedssheensheiksherdshiedshiesshillshimsshinsshipsshireshirkshirrshlepshoalshoedshoesshoneshookshoonshoos"
+ "shootshopsshornshotsshoveshowsshowyshredshrewshrubshrugshtikshuckshunsshuntshushshutsshyershylysibylsickssided"
+ "sidessidlesievesiftssighssigmasignssilkssilkysillssilossiltssinewsingesingssinkssinussiredsirensiressirupsisal"
+ "sisessissysitarsitedsitessixessizedsizersizesskeetskeinskewsskidsskiedskierskiesskiffskimpskimsskinsskipsskits"
+ "skulkskunkskyedslabsslackslagsslainslakeslamsslangslantslapsslashslatsslayssledssleeksleetslewsslickslierslily"
+ "slimeslimsslimyslingslinkslipsslitsslobssloesslogssloopslopssloshslothslotsslowssluedsluesslugsslumpslumsslung"
+ "slunkslurpslursslushslyerslylysmearsmeltsmirksmitesmithsmocksmokysmotesmurfsmutssnafusnagssnakysnapssnaresnarf"
+ "snarksnarlsneaksneersnidesniffsnipssnitssnobssnoopsnootsnoresnortsnotssnoutsnowssnowysnubssnucksnugssoakssoaps"
+ "soapysoarssobersockssodassofassoftysoggysoilssoledsolessolossonarsongssonicsonnysoothsootysoppysorersoressorta"
+ "sortssoughsoulssoupssoupysourssousesowedsowerspacyspadespakespamsspankspanssparsspasmspatespatsspawnspaysspeck"
+ "specsspeltspewsspiedspielspiesspikyspiltspinsspinyspirespitssplatsplayspoofspookspoolspoorsporespotsspoutsprat"
+ "spreesprigspudsspumespurnspursspurtsquabsquatsquawsquidstabsstagsstaidstalestalkstallstankstaphstarkstarsstash"
+ "statsstavestaysstdiosteadsteedsteinstemsstentstepsstewsstiesstilestiltstintstirsstoatstoicstokestompstonystoop"
+ "stopsstorkstoutstowsstrapstraystrepstrewstropstrumstrutstubsstudsstumpstungstunkstunsstyesstylisuavesuckssudsy"
+ "suedesuingsuitssulkssulkysullysumacsumpssunupsurersurfssurlysushiswabsswagsswainswamiswankswansswapsswardswarm"
+ "swashswathswatsswaysswellswigsswillswimsswineswipeswirlswishswoonswoopswopssworeswornswungsylphsynchsyncssynod"
+ "syrupsysoptabbytabootabustacittackstackytacostaffytailstainttakertakestalestalkstallytalontamedtamertamestamps"
+ "tangotangstangytansytapedtapertapestapirtardytaredtarestarostarottarpstarrytasertaskstattytaunttaupetawnytaxed"
+ "taxestaxisteakstealsteamstearstearyteaseteatstechsteemsteensteenyteethtelextellstempitempotempstempttendstenet"
+ "tenontenortensetentstepeetepidtermsternsterryterseteststestytextsthawstheestheftthetathighthinethinsthongthorn"
+ "thousthrewthrobthroethrumthudsthugsthumpthunkthymethymitiaratibiatickstidaltidedtidestierstiffstikestildetiled"
+ "tilestillstiltstimedtimestimidtinestingetingstinnytintstipistipsytirestirostitantithetizzytoadstoadytoddytoffy"
+ "togaetogastoilstokedtokestollstombstomestonaltonedtonertonestongstonictonnetoolstootstopaztoquetorchtorsitorso"
+ "tortetortstorustotedtotemtotestourstoutstowedtownstoxintoyedtracttraittramstranstrapstrawltraystreadtreastreed"
+ "treestrekstresstriadtribetricetriestriketrilltrimstriostripetripstritetrolltromptronstropetrothtrotstrouttroys"
+ "trucetruedtruertruestrumptrusstrysttsarstubastubbytubedtubertubestuckstuftstulletumidtummytumortunastunedtuner"
+ "tunestunictunnyturfsturnstuskstutustuxestwaintwangtweaktweedtwerktwerptwigstwilltwinetwinktwinstwirltwitstying"
+ "tykestypedtypestypostyrostzarsudderulcerulnaeulnasumbelumberumiakumpedunbaruncutundidundueunfitunifyunitsunity"
+ "unmanunpinunsayunsetuntieunwedunzipupenduppedurgedurgesurineusageusersusherusingusurpusuryuteriutteruvulavacua"
+ "valesvaletvalorvampsvanesvapedvapesvapidvaporvasesvastsvauntveepsveersveganveilsveinsveldsveldtvenalvendsvenom"
+ "ventsverbsvergeversevervevestsvetchvexedvexesvialsviandvibesvicarvicedvicesviewsvigilvigorvilervillavinesviola"
+ "violsviperviralvireovisasvisedvisesvisorvistavivasvixenvizorvodkavoguevoidsvoilevolesvoltsvomitvotedvotesvouch"
+ "vowedvowelvulvavyingwackowackswackywadedwaderwadeswadiswaferwaftswagedwagerwageswaifswailswaitswaivewakedwaken"
+ "wakeswaldowaledwaleswalkswallswaltzwandswanedwaneswanlywannawantswardswareswarezwarmswarnswarpswartswartywasps"
+ "wattswavedwaverwaveswaxedwaxenwaxeswealsweanswearswearyweavewedgeweedsweedyweeksweepsweepyweestweftsweirswelch"
+ "weldswellswelshweltswendswetlywhackwhamswharfwhatswhealwhelkwhelpwhenswhetswhiffwhimswhinewhinywhipswhirlwhirr"
+ "whirswhiskwhistwhitswhizzwhoopwhorlwickswidenwidowwieldwightwikiswildswiledwileswillswiltswimpswimpywincewinch"
+ "windswindywinedwineswingswinkswinoswipedwiperwipeswiredwireswiserwiseswispswispywitchwiveswizeswokenwolfswombs"
+ "wonkywoodswoodywooedwooerwoofswoolywoozywordswordyworkswormswormywovenwowedwrackwrapswraptwrathwreakwreckwrens"
+ "wrestwrierwringwristwritswrothwrungwryerwrylyxcviixenonxrefsxtermxviiixxiiixxviixxxiixxxivxxxixxxxvixylemyacks"
+ "yahooyanksyardsyarnsyawedyawlsyawnsyeahsyearnyearsyeastyellsyelpsyesesyocksyodelyoginyogisyokedyokelyokesyolks"
+ "yowlsyuccayucksyuckyyummyyuppyzebrazebuszeroszestszilchzincszingszippyzombizonalzonedzoneszoomszorch";
function unpack(s) { var out = [], i; for (i = 0; i < s.length; i += 5) out.push(s.substr(i, 5)); return out; }
var ANSWERS = unpack(ANS_PACK);
var ALLOWED = Object.create(null);
(function () {
var i, ex = unpack(EXT_PACK);
for (i = 0; i < ANSWERS.length; i++) ALLOWED[ANSWERS[i]] = 1;
for (i = 0; i < ex.length; i++) ALLOWED[ex[i]] = 1;
})();
var TOTAL = ANSWERS.length;
var OPENERS = ["crane", "slate", "trace", "least", "roast", "stare", "raise", "later",
"alter", "trail", "learn", "stone", "noise", "paint", "cheat", "train",
"score", "adore", "trade", "solar"];
/* ── pattern scoring: 0 = absent, 1 = elsewhere, 2 = exact spot ─────────── */
var _r = [0, 0, 0, 0, 0], _u = [0, 0, 0, 0, 0];
function patternCode(g, a) {
var i, j;
for (i = 0; i < 5; i++) { _r[i] = 0; _u[i] = 0; }
for (i = 0; i < 5; i++) if (g.charCodeAt(i) === a.charCodeAt(i)) { _r[i] = 2; _u[i] = 1; }
for (i = 0; i < 5; i++) {
if (_r[i] !== 0) continue;
for (j = 0; j < 5; j++) {
if (_u[j] === 0 && g.charCodeAt(i) === a.charCodeAt(j)) { _r[i] = 1; _u[j] = 1; break; }
}
}
return (((_r[0] * 3 + _r[1]) * 3 + _r[2]) * 3 + _r[3]) * 3 + _r[4];
}
function decode(code) {
var out = [0, 0, 0, 0, 0], i;
for (i = 4; i >= 0; i--) { out[i] = code % 3; code = (code - out[i]) / 3; }
return out;
}
function narrow(pool, guess, code) {
var out = [], i;
for (i = 0; i < pool.length; i++) if (patternCode(guess, pool[i]) === code) out.push(pool[i]);
return out;
}
/* ── solver: pick the guess that shrinks the candidate list the most ────── */
var _counts = new Int32Array(243);
function bestGuess(pool) {
if (!pool.length) return null;
if (pool.length === 1) return { word: pool[0], exp: 1 };
var cands = pool.length > 260 ? pool : ANSWERS;
var inPool = Object.create(null), i, j, c, sum, exp, isIn;
for (i = 0; i < pool.length; i++) inPool[pool[i]] = 1;
var best = pool[0], bestExp = Infinity, bestIn = -1;
for (i = 0; i < cands.length; i++) {
var g = cands[i];
_counts.fill(0);
for (j = 0; j < pool.length; j++) _counts[patternCode(g, pool[j])]++;
sum = 0;
for (j = 0; j < 243; j++) { c = _counts[j]; if (c) sum += c * c; }
exp = sum / pool.length;
isIn = inPool[g] ? 1 : 0;
if (exp < bestExp - 1e-9 || (exp < bestExp + 1e-9 && isIn > bestIn)) {
best = g; bestExp = exp; bestIn = isIn;
}
}
return { word: best, exp: bestExp };
}
/* ── DOM ────────────────────────────────────────────────────────────────── */
var root = document.documentElement;
var boardEl = document.getElementById("board");
var kbEl = document.getElementById("kb");
var toastEl = document.getElementById("toast");
var liveEl = document.getElementById("live");
var trailEl = document.getElementById("trail");
var hintOut = document.getElementById("hintOut");
var resultBox = document.getElementById("resultBox");
var gridEl = document.getElementById("grid");
var glineEl = document.getElementById("gline");
var gnoteEl = document.getElementById("gnote");
var newBtn = document.getElementById("newBtn");
var giveBtn = document.getElementById("giveBtn");
var hintBtn = document.getElementById("hintBtn");
var el = {
guess: document.getElementById("stGuess"), pool: document.getElementById("stPool"),
out: document.getElementById("stOut"), state: document.getElementById("stState"),
played: document.getElementById("tPlayed"), solved: document.getElementById("tSolved"),
streak: document.getElementById("tStreak"), avg: document.getElementById("tAvg")
};
var ROWS = 6, COLS = 5;
var tiles = [], rowEls = [];
(function buildBoard() {
var r, c;
for (r = 0; r < ROWS; r++) {
var row = document.createElement("div");
row.className = "row";
row.setAttribute("role", "group");
row.setAttribute("aria-label", "Row " + (r + 1) + ", empty");
var rt = [];
for (c = 0; c < COLS; c++) {
var t = document.createElement("div");
t.className = "tile";
row.appendChild(t);
rt.push(t);
}
boardEl.appendChild(row);
rowEls.push(row); tiles.push(rt);
}
})();
var KEYS = {};
var KROWS = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
(function buildKeyboard() {
var i, j;
for (i = 0; i < 3; i++) {
var row = document.createElement("div");
row.className = "krow";
if (i === 1) row.appendChild(mkSpacer());
if (i === 2) row.appendChild(mkKey("enter", "Enter", true));
for (j = 0; j < KROWS[i].length; j++) {
var ch = KROWS[i].charAt(j);
var k = mkKey(ch, ch, false);
KEYS[ch] = k;
row.appendChild(k);
}
if (i === 1) row.appendChild(mkSpacer());
if (i === 2) row.appendChild(mkKey("back", "Del", true));
kbEl.appendChild(row);
}
function mkSpacer() { var s = document.createElement("div"); s.className = "spacer"; return s; }
function mkKey(code, label, wide) {
var b = document.createElement("button");
b.type = "button";
b.className = "key" + (wide ? " wide" : "");
b.textContent = label;
b.setAttribute("aria-label", code === "back" ? "Delete letter" : code === "enter" ? "Submit guess" : "Letter " + code.toUpperCase());
b.addEventListener("click", function (e) { press(code); if (e.detail > 0) b.blur(); });
return b;
}
})();
/* ── motion ─────────────────────────────────────────────────────────────── */
var mqRM = window.matchMedia ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
var reduced = mqRM ? mqRM.matches : false;
/* ── game state ─────────────────────────────────────────────────────────── */
var state = null;
var session = { played: 0, solved: 0, streak: 0, sum: 0 };
var STATUS = { play: "in play", won: "solved", lost: "out of guesses", gave: "revealed" };
function newGame() {
var answer = ANSWERS[(Math.random() * TOTAL) | 0];
/* pick an opener that leaves a genuinely interesting board: at least one
coloured tile to read at a glance, but nowhere near a giveaway. */
var order = OPENERS.slice(), i, j, sw;
for (i = order.length - 1; i > 0; i--) {
j = (Math.random() * (i + 1)) | 0; sw = order[i]; order[i] = order[j]; order[j] = sw;
}
var opener = null, alt = "crane", altScore = -Infinity;
for (i = 0; i < order.length; i++) {
var o = order[i];
if (o === answer || !ALLOWED[o]) continue;
var marks = decode(patternCode(o, answer));
var lit = 0, green = 0, m;
for (m = 0; m < COLS; m++) { if (marks[m] > 0) lit++; if (marks[m] === 2) green++; }
var n = narrow(ANSWERS, o, patternCode(o, answer)).length;
var coloured = lit >= 1 && green <= 2;
if (coloured && n >= 5 && n <= 140) { opener = o; break; }
/* fallback ranking: colour first, then a candidate count inside the band */
var score = (coloured ? 100 : 0) + (n >= 5 && n <= 140 ? 50 : 0) - Math.abs(n - 60) / 1000;
if (score > altScore) { altScore = score; alt = o; }
}
if (!opener) opener = alt;
state = {
answer: answer, rows: [], cur: "", pool: ANSWERS.slice(), trail: [TOTAL],
keys: Object.create(null), over: false, won: false, busy: false, status: STATUS.play
};
var r, c;
for (r = 0; r < ROWS; r++) {
rowEls[r].classList.remove("bad");
rowEls[r].setAttribute("aria-label", "Row " + (r + 1) + ", empty");
for (c = 0; c < COLS; c++) {
var t = tiles[r][c];
t.textContent = "";
t.removeAttribute("data-s");
t.className = "tile";
}
}
for (var ch in KEYS) {
KEYS[ch].removeAttribute("data-s");
KEYS[ch].setAttribute("aria-label", "Letter " + ch.toUpperCase());
}
resultBox.hidden = true;
hintOut.textContent = "Scores every word by how far it would cut the candidate list, on average.";
setToast("");
updatePanel();
commit(opener);
}
function setToast(msg, cls) {
toastEl.textContent = msg;
toastEl.className = "toast" + (cls ? " " + cls : "");
}
function say(msg) { liveEl.textContent = msg; }
var NAMES = ["not in the word", "in the word, wrong spot", "exact spot"];
function commit(word) {
var idx = state.rows.length;
var code = patternCode(word, state.answer);
var arr = decode(code);
var i;
state.rows.push({ w: word, a: arr });
state.pool = narrow(state.pool, word, code);
state.trail.push(state.pool.length);
state.cur = "";
for (i = 0; i < COLS; i++) {
tiles[idx][i].textContent = word.charAt(i);
tiles[idx][i].classList.add("filled");
tiles[idx][i].classList.remove("pop");
}
state.busy = true;
var mine = state;
revealRow(idx, arr, function () {
if (state !== mine) return;
applyKeys(word, arr);
state.busy = false;
var won = word === state.answer;
if (won) finish(true);
else if (state.rows.length >= ROWS) finish(false);
else if (idx === 0) setToast("opening guess played for you — your turn");
else setToast("");
updatePanel();
announce(word, arr);
});
}
function revealRow(idx, arr, done) {
var i;
if (reduced) {
for (i = 0; i < COLS; i++) tiles[idx][i].setAttribute("data-s", arr[i]);
labelRow(idx, arr);
done();
return;
}
var mine = state;
for (i = 0; i < COLS; i++) {
(function (i) {
var t = tiles[idx][i];
setTimeout(function () {
if (state !== mine) return;
t.classList.remove("flip");
void t.offsetWidth;
t.classList.add("flip");
setTimeout(function () {
if (state !== mine) return;
t.setAttribute("data-s", arr[i]);
}, 170);
if (i === COLS - 1) setTimeout(function () {
if (state !== mine) return;
labelRow(idx, arr);
done();
}, 360);
}, i * 120);
})(i);
}
}
function labelRow(idx, arr) {
var w = state.rows[idx].w, parts = [], i;
for (i = 0; i < COLS; i++) parts.push(w.charAt(i).toUpperCase() + " " + NAMES[arr[i]]);
rowEls[idx].setAttribute("aria-label", "Row " + (idx + 1) + ": " + parts.join(", "));
}
function announce(word, arr) {
var parts = [], i;
for (i = 0; i < COLS; i++) parts.push(word.charAt(i).toUpperCase() + " " + NAMES[arr[i]]);
var tail = state.over
? (state.won ? " Solved in " + state.rows.length + "." : " The word was " + state.answer.toUpperCase() + ".")
: " " + state.pool.length + " candidate" + (state.pool.length === 1 ? "" : "s") + " left.";
say(word.toUpperCase() + ": " + parts.join(", ") + "." + tail);
}
function applyKeys(word, arr) {
var i;
for (i = 0; i < COLS; i++) {
var ch = word.charAt(i), s = arr[i];
var prev = state.keys[ch];
if (prev === undefined || s > prev) {
state.keys[ch] = s;
var k = KEYS[ch];
if (k) {
k.setAttribute("data-s", String(s));
k.setAttribute("aria-label", "Letter " + ch.toUpperCase() + ", " + NAMES[s]);
}
}
}
}
function paintCur(popLast) {
var idx = state.rows.length, i;
if (idx >= ROWS) return;
for (i = 0; i < COLS; i++) {
var t = tiles[idx][i], ch = state.cur.charAt(i) || "";
if (t.textContent !== ch) {
t.textContent = ch;
if (ch) t.classList.add("filled"); else t.classList.remove("filled");
if (ch && popLast && i === state.cur.length - 1 && !reduced) {
t.classList.remove("pop"); void t.offsetWidth; t.classList.add("pop");
}
}
}
}
function shake() {
var idx = state.rows.length;
if (idx >= ROWS || reduced) return;
var row = rowEls[idx];
row.classList.remove("bad"); void row.offsetWidth; row.classList.add("bad");
}
function submit() {
if (state.cur.length < COLS) { setToast("needs five letters", "warn"); shake(); say("Needs five letters."); return; }
var w = state.cur;
if (!ALLOWED[w]) { setToast('"' + w.toUpperCase() + '" is not in the word list', "warn"); shake(); say(w.toUpperCase() + " is not in the word list."); return; }
setToast("");
commit(w);
}
function press(code) {
if (!state) return;
if (state.over) {
if (code === "enter") newGame();
return;
}
if (code === "enter") { if (!state.busy) submit(); return; }
if (code === "back") {
if (state.cur.length) { state.cur = state.cur.slice(0, -1); paintCur(false); setToast(""); }
return;
}
if (state.cur.length < COLS) { state.cur += code; paintCur(true); }
}
function finish(won) {
if (state.cur) { state.cur = ""; paintCur(false); } /* drop letters typed mid-reveal */
state.over = true;
state.won = won;
state.status = won ? STATUS.won : STATUS.lost;
session.played++;
if (won) {
session.solved++; session.streak++; session.sum += state.rows.length;
var n = state.rows.length;
setToast(n === 1 ? "solved on the opening guess" : "solved in " + n + " guesses", "win");
if (!reduced) hopRow(state.rows.length - 1);
} else {
session.streak = 0;
setToast("out of guesses — the word was " + state.answer.toUpperCase(), "warn");
}
renderResult();
}
function giveUp() {
if (state.over || state.busy) return;
if (state.cur) { state.cur = ""; paintCur(false); }
state.over = true;
state.won = false;
state.status = STATUS.gave;
session.played++;
session.streak = 0;
setToast("revealed — the word was " + state.answer.toUpperCase(), "warn");
say("Revealed. The word was " + state.answer.toUpperCase() + ".");
renderResult();
updatePanel();
}
function hopRow(idx) {
var mine = state, i;
for (i = 0; i < COLS; i++) {
(function (i) {
setTimeout(function () {
if (state !== mine) return;
var t = tiles[idx][i];
t.classList.remove("hop"); void t.offsetWidth; t.classList.add("hop");
}, i * 70);
})(i);
}
}
function renderResult() {
var i, j;
gridEl.textContent = "";
for (i = 0; i < state.rows.length; i++) {
var gr = document.createElement("div");
gr.className = "grow";
for (j = 0; j < COLS; j++) {
var cell = document.createElement("div");
cell.className = "gcell";
cell.setAttribute("data-s", String(state.rows[i].a[j]));
gr.appendChild(cell);
}
gridEl.appendChild(gr);
}
if (state.won) {
glineEl.className = "gline ok";
glineEl.textContent = "word guess " + state.rows.length + "/6";
gnoteEl.innerHTML = "Nothing to copy, nothing to post — the grid just lives here. Press <b>Enter</b> or hit <b>New word</b> for another.";
} else {
glineEl.className = "gline miss";
glineEl.textContent = "word guess X/6 · " + state.answer.toUpperCase();
gnoteEl.innerHTML = "The answer was <span class=\"reveal\">" + state.answer.toUpperCase() + "</span>. Press <b>Enter</b> or hit <b>New word</b> for another.";
}
resultBox.hidden = false;
}
function updatePanel() {
var used = state.rows.length;
el.guess.textContent = (state.over ? used : Math.min(used + 1, ROWS)) + " / " + ROWS;
el.pool.textContent = String(state.pool.length);
el.pool.className = "sv" + (state.pool.length === 1 && !state.over ? " amber" : "");
var outc = 0, ch;
for (ch in state.keys) if (state.keys[ch] === 0) outc++;
el.out.textContent = outc + (outc === 1 ? " letter" : " letters");
el.state.textContent = state.status;
el.state.className = "sv small" + (state.status === STATUS.won ? " ok" : state.status === STATUS.play ? "" : " warn");
trailEl.textContent = "";
for (var i = 0; i < state.trail.length; i++) {
if (i) {
var a = document.createElement("span");
a.className = "arw"; a.textContent = "→";
trailEl.appendChild(a);
}
var n = document.createElement("span");
n.className = i === state.trail.length - 1 && i > 0 ? "cur" : "n0";
n.textContent = String(state.trail[i]);
trailEl.appendChild(n);
}
giveBtn.disabled = state.over;
hintBtn.disabled = state.over || state.pool.length === 0;
el.played.textContent = String(session.played);
el.solved.textContent = String(session.solved);
el.solved.className = "sv" + (session.solved > 0 ? " ok" : "");
el.streak.textContent = String(session.streak);
el.avg.textContent = session.solved ? (session.sum / session.solved).toFixed(1) : "—";
}
/* ── controls ───────────────────────────────────────────────────────────── */
newBtn.addEventListener("click", function () { newGame(); });
giveBtn.addEventListener("click", function () { giveUp(); });
hintBtn.addEventListener("click", function () {
if (!state || state.over) return;
var pool = state.pool;
if (!pool.length) { hintOut.textContent = "no candidate matches those colours."; return; }
hintOut.textContent = "thinking…";
var mine = state;
setTimeout(function () {
if (state !== mine) return;
var b = bestGuess(pool);
if (!b) { hintOut.textContent = "no candidate matches those colours."; return; }
if (pool.length === 1) {
hintOut.innerHTML = "one candidate left: <b>" + b.word + "</b>";
} else {
hintOut.innerHTML = "try <b>" + b.word + "</b> · leaves ≈ " +
(b.exp < 10 ? b.exp.toFixed(1) : Math.round(b.exp)) + " of " + pool.length;
}
say("Suggested guess: " + b.word.toUpperCase());
}, reduced ? 0 : 30);
});
document.addEventListener("keydown", function (e) {
if (e.ctrlKey || e.metaKey || e.altKey) return;
var ae = document.activeElement;
var onBtn = ae && ae.tagName === "BUTTON";
var k = e.key;
if (k === "Enter" || k === " " || k === "Spacebar") {
if (onBtn) return; /* let the focused button activate itself */
if (k === "Enter") { e.preventDefault(); press("enter"); }
return;
}
if (k === "Backspace") { e.preventDefault(); press("back"); return; }
if (k && k.length === 1) {
var c = k.toLowerCase();
if (c >= "a" && c <= "z") { e.preventDefault(); press(c); }
}
});
/* ── theme + motion plumbing ────────────────────────────────────────────── */
window.addEventListener("message", function (e) {
var d = e.data;
if (d && d.type === "sloprun:theme" && (d.theme === "light" || d.theme === "dark")) {
root.setAttribute("data-theme", d.theme);
}
});
if (mqRM) {
var onRM = function () { reduced = mqRM.matches; };
if (mqRM.addEventListener) mqRM.addEventListener("change", onRM);
else if (mqRM.addListener) mqRM.addListener(onRM);
}
newGame();
})();
</script>
</body>
</html>
source-visible by construction · nothing is published here without its code
Comments
0 totalNo comments yet. If you ran it, say what happened.