shithub: nordle

Download patch

ref: 3e700f39fc8f7376c24e8c93a1d706161502419d
author: phil9 <telephil9@gmail.com>
date: Sun Jan 16 05:11:55 EST 2022

initial import

--- /dev/null
+++ b/LICENSE
@@ -1,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 phil9 <telephil9@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,25 @@
+# nordle
+A [Wordle](https://www.powerlanguage.co.uk/wordle/) game clone for [9front](http://9front.org).
+
+![nordle](nordle.png)
+
+Use your keyboard to input a word, backspace to remove last entered character and enter to validate your choice.  
+Letters are coloured as follows:
+- green if the letter is at the right position
+- orange if the letter appears in the word but at a different position
+- dark gray if the letter does not appear in the word
+
+## Usage
+```sh
+% mk install
+% games/nordle <wordlist>
+```
+
+The provided wordlist file has been generated from `/lib/words`
+
+## License
+MIT
+
+## Bugs
+You tell me!
+
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,8 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/games/
+TARG=nordle
+OFILES=nordle.$O
+
+</sys/src/cmd/mkone
+
--- /dev/null
+++ b/nordle.c
@@ -1,0 +1,386 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ctype.h>
+#include <thread.h>
+#include <draw.h>
+#include <mouse.h>
+#include <keyboard.h>
+
+enum
+{
+	BACK,
+	TEXT,
+	BORD,
+	WPOS,
+	RPOS,
+	NONE,
+	NCOLS,
+};
+
+enum
+{
+	Maxwords = 4096,
+	Padding = 4,
+};
+
+enum
+{
+	Mnewgame,
+	Mexit,
+};
+char *menu3str[] = { "new game", "exit", nil };
+Menu menu3 = { menu3str };
+
+Mousectl *mc;
+Keyboardctl *kc;
+Font *lfont;
+Font *kfont;
+Image *cols[NCOLS];
+Point ls;
+Point l0;
+Point k0;
+char *words[Maxwords];
+int nwords;
+char *word;
+int lcount;
+int lnum;
+char lines[5][6];
+int tried[26];
+int done;
+int won;
+
+int
+validword(char *w)
+{
+	if(strlen(w) != 5)
+		return 0;
+	while(*w){
+		if(*w < 'a' || *w > 'z')
+			return 0;
+		w++;
+	}
+	return 1;
+}
+
+void
+readwords(char *filename)
+{
+	Biobuf *bp;
+	char *s;
+	int l;
+
+	bp = Bopen(filename, OREAD);
+	if(bp == nil)
+		sysfatal("Bopen: %r");
+	nwords = 0;
+	for(l = 1;; l++){
+		s = Brdstr(bp, '\n', 1);
+		if(s == nil)
+			break;
+		if(!validword(s)){
+			fprint(2, "invalid word '%s' at line %d\n", s, l);
+			threadexitsall("invalid word");
+		}
+		words[nwords++] = s;
+		if(nwords == Maxwords)
+			break;
+	}
+	Bterm(bp);
+	if(nwords == 0){
+		fprint(2, "empty wordlist\n");
+		threadexitsall("empty wordlist");
+	}
+}
+
+int
+wordexists(void)
+{
+	char w[6] = {0};
+	int i;
+
+	for(i = 0; i < 5; i++)
+		w[i] = lines[i][lnum];
+	for(i = 0; i < nwords; i++)
+		if(strncmp(words[i], w, 5) == 0)
+			return 1;
+	return 0;
+}
+
+void
+newgame(void)
+{
+	done = 0;
+	won = 0;
+	lcount = -1;
+	lnum = 0;
+	memset(tried, 0, 26*sizeof(uint));
+	memset(lines, 0, 30*sizeof(char));
+	word = words[nrand(nwords)];
+}
+
+int
+foundword(void)
+{
+	int i;
+	for(i = 0; i < 5; i++)
+		if(lines[i][lnum - 1] != word[i])
+			return 0;
+	return 1;
+}
+
+int
+trystate(int col, int row)
+{
+	int s;
+
+	if(lines[col][row] == word[col])
+		s = RPOS;
+	else if(strchr(word, lines[col][row]) != nil)
+		s = WPOS;
+	else
+		s = NONE;
+	return s;
+}
+
+void
+showmessage(char *message)
+{
+	Point p;
+	int w;
+
+	p = screen->r.min;
+	p.y += Padding + kfont->height;
+	w = stringwidth(kfont, message);
+	p.x += (Dx(screen->r) - w) / 2;
+	string(screen, p, cols[WPOS], ZP, kfont, message);
+	flushimage(display, 1);
+}
+
+void
+redraw(void)
+{
+	int i, j, c;
+	Point p, p1, pl;
+	Rectangle br;
+	char m[255], s[2] = {0};
+
+	draw(screen, screen->r, cols[BACK], nil, ZP);
+	if(done){
+		p = screen->r.min;
+		p.y += Padding + kfont->height;
+		if(won){
+			snprint(m, sizeof m, "congratulations");
+			c = RPOS;
+		}else{
+			snprint(m, sizeof m, "word was: %s", word);
+			c = TEXT;
+		}
+		i = stringwidth(kfont, m);
+		p.x += (Dx(screen->r) - i) / 2;
+		string(screen, p, cols[c], ZP, kfont, m);
+	}
+	for(j = 0; j < 6; j++){
+		for(i = 0; i < 5; i++){
+			p = Pt(l0.x + i*(ls.x + Padding), l0.y + j*(ls.y + Padding));
+			p1 = Pt(p.x + ls.x, p.y + ls.y);
+			br = Rpt(p, p1);
+			if(lnum < j || (lnum == j && lcount != 5))
+				border(screen, br, 1, cols[BORD], ZP);
+			if(lnum > j){
+				c = trystate(i, j);
+				draw(screen, br, cols[c], nil, ZP);
+			}
+			if(lnum > j || (lnum == j && lcount >= i)){
+				pl.x = p.x + (Dx(br) - ls.x/2) / 2;
+				pl.y = p.y + (Dy(br) - ls.y/2) / 2;
+				s[0] = toupper(lines[i][j]);
+				stringn(screen, pl, cols[TEXT], ZP, lfont, s, 1);
+			}
+		}
+	}
+	j = 0;
+	p = k0;
+	for(i = 0; i < 26; i++){
+		if(tried[i] == 0)
+			continue;
+		c = tried[i] == 1 ? NONE : RPOS;
+		s[0] = toupper(i + 'a');
+		p = stringnbg(screen, p, cols[TEXT], ZP, kfont, s, 1, cols[c], ZP);
+		p.x += 4;
+		j += 1;
+		if(j == 13){
+			j = 0;
+			p.x = k0.x;
+			p.y += kfont->height;
+		}
+	}
+	flushimage(display, 1);
+}
+
+void
+eresize(void)
+{
+	redraw();
+}
+
+void
+emouse(Mouse *m)
+{
+	if(m->buttons != 4)
+		return;
+	switch(menuhit(3, mc, &menu3, nil)){
+	case Mnewgame:
+		newgame();
+		redraw();
+		break;
+	case Mexit:
+		threadexitsall(nil);
+	}
+}
+
+void
+ekeyboard(Rune k)
+{
+	int i;
+	char c;
+
+	if(k == Kdel)
+		threadexitsall(nil);
+	if(done)
+		return;
+	if(lcount < 4 && 'a' <= k && k <= 'z'){
+		lines[++lcount][lnum] = (char)k;
+		redraw();
+	}else if(k == Kbs){
+		if(lcount >= 0){
+			lcount -= 1;
+			redraw();
+		}
+	}else if(k == '\n'){
+		if(lcount == 4){
+			if(!wordexists()){
+				lcount = -1;
+				redraw();
+				showmessage("invalid word");
+				return;
+			}
+			for(i = 0; i < 5; i++){
+				c = lines[i][lnum];
+				tried[c - 'a'] = 1 + (strchr(word, c) != nil);
+			}
+			++lnum;
+			lcount = -1;
+			if(foundword()){
+				done = 1;
+				won = 1;
+			}else if(lnum == 6){
+				done = 1;
+				won = 0;
+			}
+			redraw();
+		}
+	}
+
+}
+
+void
+initcols(void)
+{
+	cols[BACK] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x121213ff);
+	cols[TEXT] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xd7dadcff);
+	cols[BORD] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x818384ff);
+	cols[WPOS] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xb59f3bff);
+	cols[RPOS] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x538d4eff);
+	cols[NONE] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x3a3a3cff);
+}
+
+void
+initfont(void)
+{
+	lfont = openfont(display, "/lib/font/bit/lucidasans/typeunicode.16.font");
+	if(lfont == nil)
+		sysfatal("openfont: %r");
+	kfont = font;
+}
+
+void
+initsize(void)
+{
+	Point p;
+	int w, h, lw, lh, wfd, n;
+	char buf[255];
+
+	p = mulpt(stringsize(lfont, " "), 2);
+	lw = 5*(p.x + Padding);
+	lh = 6*(p.y + Padding);
+	w = 2*(p.x + Padding) + lw;
+	h = Padding + 3*kfont->height + lh + Padding + 3*kfont->height + Padding;
+	ls = p;
+	l0 = Pt(screen->r.min.x + Padding + p.x, screen->r.min.y + Padding + 3*kfont->height);
+	k0 = Pt(screen->r.min.x + Padding, screen->r.max.y - Padding - 2*kfont->height);
+	wfd = open("/dev/wctl", OWRITE);
+	if(wfd < 0)
+		sysfatal("open: %r");
+	n = snprint(buf, sizeof buf, "resize -dx %d -dy %d", w, h);
+	write(wfd, buf, n);
+	close(wfd);
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s <filename>\n", argv0);
+	threadexitsall("usage");
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+	enum { Emouse, Eresize, Ekeyboard };
+	Mouse m;
+	Rune k;
+	Alt a[] = {
+		{ nil, &m,  CHANRCV },
+		{ nil, nil, CHANRCV },
+		{ nil, &k,  CHANRCV },
+		{ nil, nil, CHANEND },
+	};
+
+	ARGBEGIN{ }ARGEND;
+	if(argc != 1)
+		usage();
+	readwords(argv[0]);
+	//srand(31337);
+	srand(time(0));
+	newgame();
+	if(initdraw(nil, nil, argv0) < 0)
+		sysfatal("initdraw: %r");
+	if((mc = initmouse(nil, screen)) == nil)
+		sysfatal("initmouse: %r");
+	if((kc = initkeyboard(nil)) == nil)
+		sysfatal("initkeyboard: %r");
+	a[Emouse].c = mc->c;
+	a[Eresize].c = mc->resizec;
+	a[Ekeyboard].c = kc->c;
+	initfont();
+	initcols();
+	initsize();
+	redraw();
+	for(;;){
+		switch(alt(a)){
+		case Emouse:
+			emouse(&m);
+			break;
+		case Eresize:
+			if(getwindow(display, Refnone) < 0)
+				sysfatal("getwindow: %r");
+			eresize();
+			break;
+		case Ekeyboard:
+			ekeyboard(k);
+			break;
+		}
+	}
+}
+
--- /dev/null
+++ b/wordlist
@@ -1,0 +1,2710 @@
+aback
+abaft
+abase
+abash
+abate
+abbey
+abbot
+abeam
+abhor
+abide
+abode
+abort
+about
+above
+abuse
+abyss
+acerb
+acorn
+acrid
+acute
+adage
+adapt
+addle
+adept
+adieu
+admit
+admix
+adobe
+adopt
+adore
+adorn
+adult
+aegis
+aerie
+affix
+afire
+afoot
+afoul
+again
+agape
+agate
+agave
+agent
+agile
+agley
+aglow
+agone
+agony
+agora
+agree
+ahead
+aisle
+akido
+alack
+alarm
+album
+alder
+aleph
+alert
+algae
+algal
+alias
+alibi
+alien
+align
+alike
+alive
+alkyd
+alkyl
+allay
+alley
+allot
+allow
+alloy
+allyl
+aloft
+aloha
+alone
+along
+aloof
+aloud
+alpha
+altar
+alter
+amass
+amaze
+amber
+ambit
+amble
+ameer
+amend
+amide
+amigo
+amine
+amino
+amiss
+amity
+among
+amort
+amour
+ample
+amply
+amuse
+anent
+angel
+anger
+angle
+angry
+angst
+anion
+anise
+ankle
+annex
+annoy
+annul
+annum
+anode
+antic
+anvil
+aorta
+apace
+apart
+aphid
+aphis
+apish
+apnea
+apple
+apply
+apron
+aptly
+arbor
+ardor
+areal
+arena
+argon
+argot
+argue
+arise
+armor
+aroma
+arose
+array
+arrow
+arson
+ascot
+ashen
+aside
+askew
+aspen
+aspic
+assai
+assay
+asset
+aster
+atlas
+atoll
+atone
+attar
+attic
+audio
+audit
+auger
+aught
+augur
+aural
+auric
+auxin
+avail
+avast
+avert
+avian
+avoid
+await
+awake
+award
+aware
+awash
+awful
+awoke
+axial
+axiom
+azure
+bacon
+badge
+bagel
+baggy
+baize
+baldy
+balsa
+banal
+bandy
+banjo
+banns
+barge
+baron
+barre
+basal
+basic
+basil
+basin
+basis
+bassi
+basso
+baste
+batch
+bathe
+batik
+baton
+bayou
+beach
+beard
+beast
+beaux
+bebop
+bedim
+beech
+befit
+befog
+began
+begat
+beget
+begin
+begot
+begun
+beige
+being
+belay
+belch
+belie
+belle
+belly
+below
+bench
+beret
+berne
+berry
+berth
+beryl
+beset
+besot
+betel
+bevel
+bezel
+bible
+biddy
+bight
+bigot
+bilge
+billy
+binge
+bingo
+biota
+biped
+birch
+birth
+bison
+bitch
+black
+blade
+blame
+blanc
+bland
+blank
+blare
+blast
+blaze
+bleak
+bleat
+bleed
+blend
+bless
+blest
+blimp
+blind
+blink
+bliss
+blitz
+bloat
+block
+bloke
+blond
+blood
+bloom
+bloop
+blown
+bluet
+bluff
+blunt
+blurb
+blurt
+blush
+board
+boast
+bobby
+bocce
+bogey
+bogus
+bonds
+bongo
+bonny
+bonus
+bonze
+boost
+booth
+booze
+borax
+boric
+borne
+boron
+bosom
+boson
+bosun
+botch
+bough
+boule
+bound
+bourn
+bowel
+bowie
+boyar
+brace
+bract
+braid
+brain
+brake
+brand
+brant
+brash
+brass
+brave
+bravo
+brawl
+brawn
+braze
+bread
+break
+bream
+breed
+breve
+briar
+bribe
+brick
+bride
+brief
+brier
+brine
+bring
+brink
+brisk
+broad
+broil
+broke
+brood
+brook
+broom
+broth
+brown
+bruit
+brunt
+brush
+brute
+buddy
+budge
+buggy
+bugle
+build
+built
+bulge
+bully
+bunch
+bunny
+buret
+burin
+burly
+burnt
+burro
+burst
+buses
+butch
+buteo
+butte
+butyl
+buxom
+buyer
+bylaw
+byway
+cabal
+cabby
+cabin
+cable
+cacao
+cache
+cacti
+caddy
+cadet
+cadge
+cadre
+cagey
+cairn
+calla
+calve
+calyx
+camel
+cameo
+canal
+candy
+canna
+canoe
+canon
+canst
+canto
+caper
+capon
+carat
+caret
+cargo
+carne
+carny
+carob
+carol
+carom
+carry
+carte
+carve
+caste
+catch
+cater
+catty
+caulk
+causa
+cause
+cavil
+cease
+cedar
+cello
+chafe
+chaff
+chain
+chair
+chalk
+champ
+chant
+chaos
+chard
+charm
+chart
+chary
+chase
+chasm
+cheap
+cheat
+check
+cheek
+cheer
+chert
+chess
+chest
+chick
+chide
+chief
+child
+chili
+chill
+chime
+chimp
+china
+chine
+chink
+chino
+chirp
+chive
+chock
+choir
+choke
+chomp
+chord
+chore
+chose
+chuck
+chuff
+chump
+chunk
+churl
+churn
+chute
+cider
+cigar
+cilia
+cinch
+circa
+civet
+civic
+civil
+clack
+claim
+clamp
+clang
+clank
+clans
+clash
+clasp
+class
+clean
+clear
+cleat
+cleft
+clerk
+click
+cliff
+climb
+clime
+cline
+cling
+clink
+cloak
+clock
+clomp
+clone
+close
+cloth
+cloud
+clout
+clove
+clown
+cluck
+clump
+clung
+clunk
+coach
+coact
+coast
+coati
+cobra
+cocci
+cocoa
+codex
+colic
+colon
+color
+colza
+comet
+comfy
+comic
+comma
+conch
+condo
+coney
+conga
+conic
+copra
+copse
+coral
+corps
+cosec
+coset
+cotta
+couch
+cough
+could
+count
+coupe
+court
+coven
+cover
+covet
+cowry
+coypu
+cozen
+crack
+craft
+cramp
+crane
+crank
+crape
+crash
+crass
+crate
+crave
+crawl
+craze
+creak
+cream
+credo
+creed
+creek
+creel
+creep
+crepe
+crept
+cress
+crest
+crick
+cried
+crime
+crimp
+crisp
+criss
+croak
+crock
+croft
+crone
+crook
+croon
+cross
+croup
+crowd
+crown
+crude
+cruel
+cruet
+crumb
+crump
+crush
+crust
+crypt
+cubic
+cubit
+culex
+culpa
+cumin
+curia
+curie
+curio
+curry
+curse
+curve
+cushy
+cutup
+cycad
+cycle
+cynic
+dacha
+daddy
+daffy
+daily
+dairy
+daisy
+dally
+dance
+dandy
+datum
+daunt
+davit
+dealt
+death
+debar
+debit
+debug
+debut
+decal
+decay
+decor
+decoy
+decry
+defer
+defog
+degas
+degum
+deice
+deify
+deign
+deism
+deist
+deity
+delay
+delft
+delta
+delve
+demit
+demon
+demur
+denim
+dense
+depot
+depth
+derby
+desex
+deter
+deuce
+devil
+dewar
+diary
+diazo
+dicky
+dicot
+dicta
+didst
+digit
+dilly
+dinar
+dingo
+dinky
+diode
+dirge
+dirty
+disco
+ditch
+ditto
+ditty
+divan
+divot
+divvy
+dizzy
+djinn
+dodge
+doeth
+dogma
+doily
+dolce
+dolly
+dolor
+donor
+dopey
+doubt
+douce
+dough
+douse
+dowdy
+dowel
+dower
+dowry
+dowse
+dozen
+draft
+drain
+drake
+drama
+drank
+drape
+drawl
+drawn
+dread
+dream
+drear
+dress
+dried
+drier
+drift
+drill
+drink
+drive
+droll
+drone
+drool
+droop
+dross
+drove
+drown
+druid
+drunk
+dryad
+ducal
+ducat
+duchy
+dully
+dulse
+dummy
+dunce
+duple
+dwarf
+dwell
+dwelt
+dying
+eager
+eagle
+early
+earth
+easel
+eaten
+ebony
+eclat
+edema
+edict
+edify
+educe
+eerie
+egret
+eider
+eight
+eject
+elate
+elbow
+elder
+elect
+elegy
+elfin
+elide
+elite
+elope
+elude
+elute
+elver
+elves
+embed
+ember
+emcee
+emend
+emery
+emote
+empty
+enact
+endow
+endue
+enema
+enemy
+enjoy
+ennui
+ensue
+enter
+entry
+envoi
+envoy
+epoch
+epoxy
+equal
+equip
+erase
+erect
+ergot
+erode
+error
+erupt
+esker
+essay
+ester
+estop
+ether
+ethic
+ethos
+ethyl
+etude
+evade
+event
+evert
+every
+evict
+evoke
+exact
+exalt
+excel
+exert
+exile
+exist
+expel
+extol
+extra
+exude
+exult
+exurb
+eyrie
+fable
+facet
+facto
+faery
+faint
+fairy
+faith
+fakir
+false
+fancy
+farad
+farce
+fatal
+fault
+fauna
+favor
+feast
+fecal
+feces
+feign
+feint
+felon
+femur
+fence
+feral
+ferry
+fetal
+fetch
+fetid
+fetus
+fever
+fiber
+fiche
+field
+fiend
+fiery
+fifth
+fifty
+fight
+filar
+filch
+filet
+filly
+filth
+final
+finch
+finis
+first
+fjord
+flack
+flail
+flair
+flake
+flame
+flank
+flare
+flash
+flask
+fleck
+fleet
+flesh
+flick
+flier
+fling
+flint
+flirt
+float
+flock
+flood
+floor
+flora
+floss
+flour
+flout
+flown
+fluff
+fluid
+fluke
+flume
+flung
+flunk
+flush
+flute
+flyby
+flyer
+focal
+focus
+fogey
+foist
+folio
+folly
+foray
+force
+forge
+forgo
+forte
+forth
+forty
+forum
+found
+fount
+fovea
+foyer
+frail
+frame
+franc
+frank
+fraud
+freak
+freed
+freon
+fresh
+friar
+fried
+frill
+frisk
+frizz
+frock
+frond
+front
+frosh
+frost
+froth
+frown
+froze
+fruit
+fudge
+fugal
+fugue
+fully
+fungi
+fungo
+funny
+furor
+furze
+fusil
+fusty
+gable
+gaffe
+gaily
+gamba
+games
+gamey
+gamin
+gamma
+gamut
+gases
+gator
+gauge
+gaunt
+gauss
+gauze
+gavel
+gecko
+geese
+geest
+gelid
+genie
+genii
+genre
+genus
+geode
+geoid
+getup
+ghost
+ghoul
+giant
+giddy
+gimpy
+girly
+girth
+given
+gizmo
+glace
+glade
+gland
+glare
+glass
+glaze
+gleam
+glean
+glide
+glint
+glitz
+gloat
+globe
+gloom
+glory
+gloss
+glove
+gluey
+glyph
+gnarl
+gnash
+gnome
+going
+golly
+gonad
+goody
+gooey
+goose
+gorge
+gorse
+gotta
+gouge
+gourd
+goyim
+grace
+grade
+graft
+grail
+grain
+grand
+grant
+grape
+graph
+grasp
+grass
+grata
+grate
+grave
+gravy
+graze
+great
+grebe
+greed
+green
+greet
+grief
+grill
+grime
+grind
+gripe
+grist
+groan
+groat
+groin
+groom
+grope
+gross
+group
+grout
+grove
+growl
+grown
+gruel
+gruff
+grunt
+guano
+guard
+guava
+guess
+guest
+guide
+guild
+guile
+guilt
+guise
+gulag
+gulch
+gully
+gumbo
+gunny
+guppy
+gurdy
+gussy
+gusto
+gutsy
+gypsy
+habit
+haiku
+hajji
+halve
+handy
+hanky
+hardy
+harem
+harpy
+harry
+harsh
+harum
+haste
+hasty
+hatch
+haunt
+haven
+havoc
+hazel
+heads
+heard
+heart
+heath
+heave
+heavy
+hedge
+heigh
+heist
+helix
+hello
+helms
+helot
+helve
+hence
+henna
+henry
+herds
+heron
+hertz
+hexad
+hilly
+hilum
+hinge
+hippo
+hippy
+hitch
+hoagy
+hoard
+hobby
+hocus
+hogan
+hoist
+hokum
+holey
+holly
+homey
+honey
+honky
+honor
+hooch
+hooey
+horde
+horse
+hotel
+hough
+hound
+house
+hovel
+hover
+howdy
+hoyle
+hubby
+human
+humic
+humid
+humor
+humph
+humus
+hunch
+hunts
+hurdy
+hurly
+hurry
+hussy
+hutch
+huzza
+hydra
+hydro
+hyena
+hying
+hymen
+ideal
+idiom
+idiot
+idyll
+igloo
+ileum
+iliac
+image
+imbue
+impel
+inane
+inapt
+incur
+index
+inept
+inert
+infer
+infix
+infra
+ingot
+inker
+inlay
+inlet
+inner
+input
+inset
+inter
+inure
+iodic
+ionic
+irate
+irony
+islet
+issue
+ivory
+jaunt
+jelly
+jenny
+jerry
+jetty
+jewel
+jiffy
+jihad
+jimmy
+jingo
+jinks
+joint
+joist
+jolly
+joule
+joust
+jowly
+judge
+juice
+julep
+jumbo
+junco
+junta
+juror
+kabob
+kafir
+kapok
+kappa
+kaput
+karma
+kayak
+kazoo
+kedge
+kerry
+ketch
+keyed
+khaki
+kiosk
+kitty
+knack
+knave
+knead
+kneel
+knell
+knelt
+knick
+knife
+knock
+knoll
+knout
+known
+knurl
+koala
+kooky
+kraal
+kraft
+kraut
+krill
+krona
+kudos
+kudzu
+kulak
+kvass
+kyrie
+label
+labia
+labor
+laden
+ladle
+lager
+laird
+laity
+lance
+lands
+lapel
+lapse
+larch
+lares
+large
+largo
+larva
+lasso
+latch
+latex
+lathe
+latus
+laugh
+layup
+leach
+leads
+leapt
+learn
+lease
+leash
+least
+leave
+ledge
+leech
+leery
+lefty
+legal
+legit
+lemma
+lemon
+lemur
+lento
+leper
+letup
+levee
+level
+lever
+lewis
+liana
+libel
+licit
+lifer
+light
+liken
+lilac
+limbo
+limey
+limit
+linen
+liner
+lingo
+lipid
+lisle
+liter
+lithe
+liven
+livid
+livre
+llama
+loath
+lobar
+lobby
+local
+locus
+lodge
+loess
+logic
+lolly
+loopy
+loose
+loran
+loris
+lorry
+lotto
+lotus
+loupe
+louse
+lower
+loyal
+lucid
+lucre
+lumen
+lunar
+lunch
+lunge
+lurch
+lurid
+lying
+lymph
+lynch
+lyric
+lyses
+lysis
+macaw
+macho
+macro
+madam
+magic
+magma
+magna
+maize
+major
+mamba
+mambo
+mamma
+mammy
+mange
+mango
+mania
+manic
+manna
+manor
+manse
+maple
+march
+marge
+maria
+marks
+marly
+marry
+marsh
+maser
+mason
+match
+mater
+matey
+matte
+mauve
+maxim
+maybe
+mayor
+mayst
+mealy
+meant
+mecca
+mecum
+medal
+media
+medic
+melee
+melon
+mercy
+merge
+merit
+merry
+meson
+metal
+meter
+metro
+mezzo
+micro
+midge
+midst
+might
+milch
+mimeo
+mimic
+mince
+minim
+minor
+minus
+mirth
+miser
+miter
+mixup
+mocha
+modal
+model
+modem
+modus
+mogul
+moire
+moist
+molal
+molar
+molto
+mommy
+monad
+monel
+money
+monte
+month
+mooch
+moose
+moral
+morel
+moron
+morph
+motel
+motet
+motif
+motor
+motto
+mound
+mount
+mourn
+mouse
+mouth
+movie
+moxie
+mucus
+muddy
+mufti
+mulch
+mulct
+multi
+mumbo
+mummy
+mumps
+munch
+mural
+murre
+music
+muzzy
+mylar
+mynah
+myrrh
+nabla
+nabob
+nacho
+nadir
+naiad
+naive
+naked
+nanny
+nares
+nasal
+nasty
+natal
+natty
+naval
+navel
+navvy
+neath
+neigh
+nerve
+never
+newel
+newsy
+nexus
+niche
+niece
+nifty
+night
+ninny
+ninth
+nisei
+nitty
+nizam
+noble
+nodal
+noise
+nomad
+nonce
+noose
+noria
+north
+notch
+novel
+nudge
+nurse
+nylon
+nymph
+oaken
+oakum
+oases
+oasis
+obese
+objet
+occur
+ocean
+ocher
+octal
+octet
+odeum
+odium
+offal
+offer
+often
+ohmic
+okapi
+olden
+oldie
+olive
+omega
+onion
+onset
+oomph
+opera
+opine
+opium
+optic
+orate
+orbit
+order
+organ
+ortho
+osier
+other
+otter
+ought
+ounce
+ouzel
+ovary
+ovate
+overt
+ovine
+ovoid
+owing
+owlet
+oxbow
+oxeye
+oxide
+ozone
+paddy
+padre
+paean
+pagan
+paint
+palsy
+pampa
+panda
+panel
+panic
+panky
+pansy
+panty
+papal
+papaw
+paper
+pappy
+parch
+parka
+parry
+parse
+party
+paseo
+pasha
+passe
+pasta
+paste
+patch
+patio
+patsy
+patty
+pause
+payee
+peace
+peach
+pearl
+peavy
+pecan
+pedal
+peeve
+pekoe
+penal
+pence
+penis
+penna
+penny
+peony
+perch
+peril
+pesky
+petal
+peter
+petit
+petri
+phage
+phase
+phial
+phlox
+phone
+photo
+phyla
+piano
+piece
+pieta
+piety
+pigmy
+pilaf
+pilot
+pinch
+pinko
+pinto
+pinup
+pious
+pique
+pitch
+piton
+pivot
+pixel
+pixie
+pizza
+place
+plaid
+plain
+plait
+plane
+plank
+plant
+plasm
+plate
+playa
+plaza
+plead
+pleat
+plebe
+plink
+pluck
+plumb
+plume
+plump
+plunk
+plush
+poach
+pocus
+podia
+poesy
+point
+poise
+pokey
+polar
+polio
+polis
+polka
+polyp
+pooch
+poppy
+porch
+porgy
+porno
+posit
+posse
+pouch
+pound
+power
+prank
+prate
+prawn
+preen
+press
+prexy
+price
+prick
+pride
+prima
+prime
+primo
+primp
+print
+prior
+prism
+privy
+prize
+probe
+prone
+prong
+proof
+prose
+proud
+prove
+prowl
+proxy
+prude
+prune
+psalm
+pshaw
+psych
+pubic
+pudgy
+pukka
+pulse
+punch
+pupae
+pupal
+pupil
+puppy
+puree
+purge
+purse
+putty
+pygmy
+pylon
+quack
+quaff
+quail
+quake
+qualm
+quark
+quart
+quash
+quasi
+queen
+queer
+quell
+query
+quest
+queue
+quick
+quiet
+quill
+quilt
+quint
+quire
+quirk
+quirt
+quite
+quoin
+quoit
+quota
+quote
+quoth
+rabbi
+rabid
+radar
+radii
+radio
+radix
+radon
+rafts
+raise
+rajah
+rally
+ranch
+randy
+range
+rapid
+ratio
+ravel
+raven
+rayon
+razor
+reach
+ready
+realm
+reave
+rebel
+rebut
+recto
+recur
+redox
+reeve
+refer
+reify
+reign
+relic
+remit
+renal
+repel
+retch
+revel
+rheum
+rhino
+rhomb
+rhumb
+rhyme
+ridge
+rifle
+right
+rigid
+rigor
+rilly
+rinse
+ripen
+risen
+ritzy
+rival
+riven
+river
+rivet
+roach
+roast
+robin
+robot
+rodeo
+rogue
+roily
+roman
+rondo
+roost
+rosin
+rotor
+rouge
+rough
+round
+rouse
+roust
+route
+rowdy
+rowel
+royal
+ruble
+ruddy
+rugby
+rumen
+rummy
+rumor
+runic
+rupee
+rural
+saber
+sable
+sabra
+sadhu
+sahib
+saint
+saith
+salad
+sales
+sally
+salon
+salve
+salvo
+samba
+sarge
+sassy
+satan
+satin
+satyr
+sauce
+sauna
+saute
+savor
+savoy
+savvy
+scads
+scald
+scale
+scalp
+scaly
+scamp
+scant
+scare
+scarf
+scarp
+scaup
+scene
+scent
+schwa
+scion
+scoff
+scold
+scone
+scoop
+scoot
+scope
+score
+scorn
+scour
+scout
+scowl
+scram
+scrap
+scree
+screw
+scrim
+scrip
+scrod
+scrog
+scrub
+scrum
+scuba
+scuff
+scull
+sedan
+seder
+sedge
+segue
+seine
+seism
+seize
+semen
+senor
+sense
+sepal
+sepia
+septa
+serge
+serif
+serum
+serve
+servo
+setup
+seven
+sever
+shack
+shade
+shaft
+shake
+shako
+shaky
+shale
+shall
+shalt
+shame
+shank
+shape
+shard
+share
+shark
+sharp
+shave
+shawl
+sheaf
+shear
+sheen
+sheep
+sheer
+sheet
+sheik
+shelf
+shell
+shied
+shift
+shill
+shine
+shire
+shirk
+shirr
+shirt
+shish
+shoal
+shock
+shoji
+shone
+shook
+shoot
+shore
+shorn
+short
+shout
+shove
+shown
+shred
+shrew
+shrub
+shrug
+shuck
+shunt
+shush
+shyly
+sibyl
+sidle
+siege
+sieve
+sight
+sigma
+silly
+since
+sinew
+singe
+sinus
+siren
+sisal
+sissy
+situs
+sixth
+sixty
+skate
+skeet
+skein
+skied
+skiff
+skill
+skimp
+skink
+skirl
+skirt
+skoal
+skulk
+skull
+skunk
+slack
+slain
+slake
+slang
+slant
+slash
+slate
+slave
+sleek
+sleep
+sleet
+slept
+slice
+slick
+slide
+slime
+sling
+slink
+sloop
+slope
+slosh
+sloth
+slump
+slung
+slunk
+slurp
+slush
+smack
+small
+smart
+smash
+smear
+smell
+smelt
+smile
+smirk
+smite
+smith
+smock
+smoke
+smote
+snack
+snafu
+snail
+snake
+snare
+snark
+snarl
+sneak
+sneer
+snell
+snick
+snide
+sniff
+snipe
+snook
+snoop
+snoot
+snore
+snort
+snout
+snuff
+sober
+soggy
+solar
+solid
+solve
+sonar
+sonic
+sonny
+sooth
+sorry
+sound
+souse
+south
+space
+spade
+spake
+spall
+spank
+spare
+spark
+spasm
+spate
+spawn
+speak
+spear
+speck
+speed
+spell
+spend
+spent
+sperm
+spice
+spiel
+spike
+spill
+spilt
+spine
+spire
+spite
+spitz
+splat
+splay
+split
+spoil
+spoke
+spoof
+spook
+spool
+spoon
+spoor
+spore
+sport
+spout
+spray
+spree
+sprig
+sprue
+spume
+spunk
+spurn
+spurt
+squab
+squad
+squat
+squaw
+squib
+squid
+stack
+staff
+stage
+staid
+stain
+stair
+stake
+stale
+stalk
+stall
+stamp
+stand
+stank
+staph
+stare
+stark
+start
+stash
+state
+stave
+stead
+steak
+steal
+steam
+steed
+steel
+steep
+steer
+stein
+stela
+stele
+steno
+stere
+stern
+stick
+stiff
+stile
+still
+stilt
+sting
+stink
+stint
+stoat
+stock
+stogy
+stoic
+stoke
+stole
+stoma
+stomp
+stone
+stood
+stool
+stoop
+store
+stork
+storm
+story
+stout
+stove
+strap
+straw
+stray
+strep
+strew
+strip
+strop
+strum
+strut
+stuck
+study
+stuff
+stump
+stung
+stunk
+stunt
+style
+styli
+suave
+sudsy
+suede
+sugar
+suite
+sulfa
+sulky
+sully
+sumac
+summa
+sunup
+super
+supra
+surge
+surly
+sushi
+sutra
+swage
+swain
+swale
+swami
+swamp
+swank
+sward
+swarm
+swart
+swash
+swath
+swear
+sweat
+sweep
+sweet
+swell
+swept
+swift
+swill
+swine
+swing
+swipe
+swirl
+swish
+swiss
+swoon
+swoop
+sword
+swore
+sworn
+swung
+sylph
+synch
+synod
+syrup
+tabby
+table
+taboo
+tacit
+taffy
+taint
+taken
+tally
+talon
+talus
+tango
+tangy
+tansy
+taper
+tapir
+tapis
+tardy
+tarry
+taste
+tasty
+tater
+taunt
+tawny
+taxon
+teach
+tease
+tecum
+teddy
+teeth
+tempo
+tempt
+tenet
+tenon
+tenor
+tense
+tenth
+tepee
+tepid
+terry
+terse
+thane
+thank
+theft
+their
+theme
+there
+therm
+these
+theta
+thick
+thief
+thigh
+thine
+thing
+think
+third
+thong
+thorn
+those
+three
+threw
+throb
+throw
+thrum
+thumb
+thump
+thyme
+tiara
+tibia
+tidal
+tiger
+tight
+tilde
+tilth
+timid
+tinge
+tipsy
+titan
+titer
+tithe
+title
+toady
+toast
+today
+toddy
+token
+tommy
+tonal
+tonic
+tonne
+tooth
+topaz
+toper
+topic
+topsy
+toque
+torch
+torso
+torte
+torus
+total
+totem
+touch
+tough
+towel
+towns
+toxic
+toxin
+trace
+track
+tract
+trade
+trail
+train
+trait
+tramp
+trash
+trawl
+tread
+treat
+trend
+tress
+triac
+triad
+trial
+tribe
+trice
+trick
+tried
+trill
+tripe
+trite
+troll
+troop
+trope
+troth
+trout
+trove
+truce
+truck
+truly
+trump
+trunk
+truss
+trust
+truth
+tubby
+tulip
+tulle
+tumid
+tummy
+tumor
+tunic
+turbo
+turvy
+tutor
+tutti
+twain
+twang
+tweak
+tweed
+tween
+tweet
+twerp
+twice
+twill
+twine
+twirl
+twist
+twixt
+tying
+typic
+udder
+ukase
+ulcer
+ultra
+umber
+umbra
+umiak
+unary
+uncle
+under
+unify
+union
+unite
+unity
+unmet
+until
+upend
+upset
+urban
+urine
+usage
+usher
+usual
+usurp
+usury
+utero
+utile
+utter
+uvula
+vacua
+vacuo
+vague
+valet
+valid
+valor
+value
+valve
+vapid
+vapor
+vasty
+vault
+vaunt
+veery
+velar
+veldt
+venal
+venin
+venom
+venue
+verge
+versa
+verse
+verso
+verst
+verve
+vetch
+viand
+vicar
+video
+vigil
+vigor
+villa
+vinyl
+viola
+viper
+viral
+vireo
+virus
+visit
+visor
+vista
+vitae
+vital
+vitro
+vivid
+vixen
+vocal
+vodka
+vogue
+voice
+vomit
+vouch
+vowel
+vulva
+vying
+wacky
+wader
+wafer
+wager
+wagon
+wahoo
+waist
+waive
+waken
+waltz
+waste
+watch
+water
+waver
+waxen
+weary
+weave
+weber
+wedge
+weigh
+weird
+welsh
+wench
+whack
+whale
+wharf
+wheat
+wheel
+whelk
+whelm
+whelp
+where
+which
+whiff
+while
+whine
+whirl
+whirr
+whish
+whisk
+whist
+white
+whole
+whomp
+whoop
+whore
+whorl
+whose
+widen
+widow
+width
+wield
+willy
+wince
+winch
+witch
+withe
+wizen
+woman
+women
+woods
+woozy
+world
+worry
+worse
+worst
+worth
+would
+wound
+woven
+wrack
+wrath
+wreak
+wreck
+wrest
+wring
+wrist
+write
+wrong
+wrote
+wrung
+wurst
+xebec
+xenon
+xeric
+xylem
+yacht
+yahoo
+yearn
+yeast
+yield
+yodel
+yokel
+young
+yours
+youth
+yucca
+yummy
+zebra
+zilch
+zloty
+zonal