pyrdle first-pass

This commit is contained in:
Gregory Gauthier 2025-10-01 09:17:40 +01:00
commit 6d916622c6
12 changed files with 12059 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.DS_Store
.idea/
poetry.lock

91
README.md Normal file
View File

@ -0,0 +1,91 @@
# Python Wordle Game - Terminal Edition
A terminal-based implementation of Wordle using Python and ncurses.
## Requirements
- Python 3.6+
- ncurses library
## Files
- `pyrdle.py` - Main game implementation
- `pyrdle_words_[level].txt` - Tiered dictionaries of valid 5-letter words
## How to Run
```bash
$ poetry run python pyrdle.py --help (20361d14h4m)|*[main]
usage: pyrdle.py [-h] [--easy | --medium | --hard] [--common | --literary | --techy | --cultural | --full ]
[--wordlist FILE]
pyrdle Game - Guess the 5-letter word!
options:
-h, --help show this help message and exit
--easy Easy mode: common words only
--medium Medium mode: standard vocabulary
--hard Hard mode: includes obscure words
--common Common everyday words
--literary Literary and archaic terms
--techy Technical and scientific terms
--cultural Cultural and international terms
--full Full dictionary (all words)
--wordlist FILE Use custom word list file
Difficulty Levels:
--easy Common everyday words (default)
--medium Standard vocabulary including less common words
--hard Challenging words including archaic and technical terms
Word Categories:
--common Common English words (default)
--literary Literary and archaic terms
--techy Technical and scientific terms
--cultural Words from various cultures and languages
--full Complete dictionary with all words
Examples:
python3 pyrdle.py --easy
python3 pyrdle.py --techy
python3 pyrdle.py --hard --literary
```
## How to Play
1. The goal is to guess the secret 5-letter word within 6 attempts
2. Type your guess using the keyboard (A-Z letters)
3. Press Enter to submit your guess
4. After each guess, the color of the letters will change:
- **Green**: Letter is in the word and in the correct position
- **Yellow**: Letter is in the word but in the wrong position
- **Red**: Letter is NOT in the word (confirmed absent)
- **Gray/Dim**: Letter has not been used yet (shown on keyboard)
The keyboard at the bottom shows all letters with their current status,
making it easy to track which letters are still available for guessing.
## Controls
- **A-Z**: Type letters for your guess
- **Enter**: Submit your current guess
- **Backspace**: Delete the last letter
- **N**: Start a new game (when game is over)
- **Q** or **ESC**: Quit the game
- **Ctrl+C**: Force quit
## Adding More Words
To expand the word list, simply add more 5-letter words (one per line) to the appropriate file in the `wordlists` directory.
The game automatically filters for 5-letter words and converts them to uppercase.
## Troubleshooting
If colors don't display correctly:
- Ensure your terminal supports colors
- Try running with: `TERM=xterm-256color python3 wordle.py`
If the game doesn't fit your terminal:
- Resize your terminal window to at least 80x24 characters
- The game adapts to different terminal sizes but needs minimum space

16
pyproject.toml Normal file
View File

@ -0,0 +1,16 @@
[project]
name = "pyrdle"
version = "0.1.0"
description = ""
authors = [
{name = "Gregory Gauthier",email = "gregory.gauthier@perspectum.com"}
]
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

428
pyrdle.py Normal file
View File

@ -0,0 +1,428 @@
#!/usr/bin/env python3
"""
pyrdle Game Implementation using ncurses
Supports multiple difficulty levels and word categories
"""
import argparse
import curses
import random
import sys
import os
from typing import List, Tuple
WORDLIST_DIR = "wordlists"
class pyrdleGame:
def __init__(self):
self.word_list = []
self.target_word = ""
self.guesses = []
self.current_guess = ""
self.game_over = False
self.won = False
self.max_guesses = 6
self.word_length = 5
# Color pairs for the display
self.COLOR_DEFAULT = 1
self.COLOR_CORRECT = 2 # Green - letter in correct position
self.COLOR_PRESENT = 3 # Yellow - letter in word but wrong position
self.COLOR_ABSENT = 4 # Red - letter not in word (confirmed absent)
self.COLOR_WHITE = 5
self.COLOR_UNUSED = 6 # Gray - letter not yet used
# Keyboard layout for visual keyboard
self.keyboard_rows = [
"QWERTYUIOP",
"ASDFGHJKL",
"ZXCVBNM"
]
self.letter_status = {} # Track letter status for keyboard coloring
def load_words(self, filename: str = f"pyrdle_words.txt") -> bool:
"""Load word list from file"""
filepath = os.path.join(WORDLIST_DIR, filename)
try:
# Check if file exists
if not os.path.exists(filepath):
# Try with .txt extension if not provided
if not filepath.endswith('.txt'):
filepath = filepath + '.txt'
if not os.path.exists(filepath):
return False
with open(filepath, 'r') as f:
self.word_list = [word.strip().upper() for word in f.readlines()
if len(word.strip()) == self.word_length]
if not self.word_list:
return False
self.target_word = random.choice(self.word_list)
return True
except FileNotFoundError:
return False
def is_valid_word(self, word: str) -> bool:
"""Check if word exists in word list"""
return word.upper() in self.word_list
def check_guess(self, guess: str) -> List[int]:
"""
Check guess against target word
Returns list of color codes for each letter
"""
guess = guess.upper()
target = self.target_word
result = [self.COLOR_ABSENT] * self.word_length # Start with red (not in word)
target_chars = list(target)
# First pass: mark correct positions
for i in range(self.word_length):
if guess[i] == target[i]:
result[i] = self.COLOR_CORRECT
target_chars[i] = None
self.letter_status[guess[i]] = self.COLOR_CORRECT
# Second pass: mark present but wrong position
for i in range(self.word_length):
if result[i] == self.COLOR_ABSENT and guess[i] in target_chars:
result[i] = self.COLOR_PRESENT
target_chars[target_chars.index(guess[i])] = None
if guess[i] not in self.letter_status or \
self.letter_status[guess[i]] != self.COLOR_CORRECT:
self.letter_status[guess[i]] = self.COLOR_PRESENT
elif result[i] == self.COLOR_ABSENT:
# Letter is definitely not in the word - mark as red
if guess[i] not in self.letter_status:
self.letter_status[guess[i]] = self.COLOR_ABSENT
return result
def make_guess(self, guess: str) -> Tuple[bool, List[int]]:
"""
Process a guess
Returns (success, color_results)
"""
if len(guess) != self.word_length:
return False, []
if not self.is_valid_word(guess):
return False, []
colors = self.check_guess(guess)
self.guesses.append((guess.upper(), colors))
if guess.upper() == self.target_word:
self.game_over = True
self.won = True
elif len(self.guesses) >= self.max_guesses:
self.game_over = True
self.won = False
return True, colors
def draw_title(stdscr, y_offset: int, difficulty: str = ""):
"""Draw game title"""
title = "pyrdle"
if difficulty:
title += f" [{difficulty}]"
height, width = stdscr.getmaxyx()
x = (width - len(title)) // 2
stdscr.attron(curses.A_BOLD)
stdscr.addstr(y_offset, x, title)
stdscr.attroff(curses.A_BOLD)
def draw_board(stdscr, game: pyrdleGame, y_offset: int):
"""Draw the game board with all guesses"""
height, width = stdscr.getmaxyx()
board_x = (width - (game.word_length * 4 - 1)) // 2
for row in range(game.max_guesses):
y = y_offset + row * 2
if row < len(game.guesses):
# Draw completed guess
guess, colors = game.guesses[row]
for col, (letter, color) in enumerate(zip(guess, colors)):
x = board_x + col * 4
stdscr.attron(curses.color_pair(color))
stdscr.addstr(y, x, f"[{letter}]")
stdscr.attroff(curses.color_pair(color))
elif row == len(game.guesses) and not game.game_over:
# Draw current guess
for col in range(game.word_length):
x = board_x + col * 4
if col < len(game.current_guess):
letter = game.current_guess[col]
else:
letter = " "
stdscr.attron(curses.color_pair(game.COLOR_WHITE))
stdscr.addstr(y, x, f"[{letter}]")
stdscr.attroff(curses.color_pair(game.COLOR_WHITE))
else:
# Draw empty slots
for col in range(game.word_length):
x = board_x + col * 4
stdscr.addstr(y, x, "[ ]")
def draw_keyboard(stdscr, game: pyrdleGame, y_offset: int):
"""Draw visual keyboard showing letter status"""
height, width = stdscr.getmaxyx()
for row_idx, row in enumerate(game.keyboard_rows):
# Center each keyboard row
x = (width - (len(row) * 2 - 1)) // 2
y = y_offset + row_idx
# Add indentation for second and third rows
if row_idx == 1:
x += 1
elif row_idx == 2:
x += 3
for letter in row:
# Get color based on letter status
if letter in game.letter_status:
color = game.letter_status[letter]
else:
# Letter not yet used - show in gray/dim
color = game.COLOR_UNUSED
# Apply dim attribute for unused letters
if color == game.COLOR_UNUSED:
stdscr.attron(curses.A_DIM)
stdscr.addstr(y, x, letter)
stdscr.attroff(curses.A_DIM)
else:
stdscr.attron(curses.color_pair(color))
stdscr.addstr(y, x, letter)
stdscr.attroff(curses.color_pair(color))
x += 2
def draw_message(stdscr, message: str, y_offset: int, color_pair: int = 1):
"""Draw centered message"""
height, width = stdscr.getmaxyx()
x = (width - len(message)) // 2
stdscr.attron(curses.color_pair(color_pair))
stdscr.addstr(y_offset, x, message)
stdscr.attroff(curses.color_pair(color_pair))
def draw_instructions(stdscr, y_offset: int):
"""Draw game instructions"""
instructions = [
"Guess the 5-letter word in 6 tries!",
"",
"Colors: GREEN=Correct, YELLOW=Wrong position, RED=Not in word",
"",
"Type letters: A-Z",
"Enter: Submit guess",
"Backspace: Delete letter",
"Ctrl+C: Quit game"
]
height, width = stdscr.getmaxyx()
for i, line in enumerate(instructions):
if y_offset + i < height - 1:
x = (width - len(line)) // 2
stdscr.addstr(y_offset + i, x, line)
def parse_arguments():
"""Parse command line arguments for difficulty/category selection"""
parser = argparse.ArgumentParser(
description='pyrdle Game - Guess the 5-letter word!',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Difficulty Levels:
--easy Common everyday words (default)
--medium Standard vocabulary including less common words
--hard Challenging words including archaic and technical terms
Word Categories:
--common Common English words (default)
--literary Literary and archaic terms
--techy Technical and scientific terms
--cultural Words from various cultures and languages
--full Complete dictionary with all words
Examples:
python3 pyrdle.py --easy
python3 pyrdle.py --techy
python3 pyrdle.py --hard --literary
"""
)
# Difficulty levels (mutually exclusive)
difficulty = parser.add_mutually_exclusive_group()
difficulty.add_argument('--easy', action='store_true',
help='Easy mode: common words only')
difficulty.add_argument('--medium', action='store_true',
help='Medium mode: standard vocabulary')
difficulty.add_argument('--hard', action='store_true',
help='Hard mode: includes obscure words')
# Word categories (mutually exclusive)
category = parser.add_mutually_exclusive_group()
category.add_argument('--common', action='store_true',
help='Common everyday words')
category.add_argument('--literary', action='store_true',
help='Literary and archaic terms')
category.add_argument('--techy', action='store_true',
help='Technical and scientific terms')
category.add_argument('--cultural', action='store_true',
help='Cultural and international terms')
category.add_argument('--full', action='store_true',
help='Full dictionary (all words)')
# Custom word list
parser.add_argument('--wordlist', type=str, metavar='FILE',
help='Use custom word list file')
args = parser.parse_args()
# Determine which word list to use
if args.wordlist:
return args.wordlist, "CUSTOM"
# Map arguments to word list files
if args.techy:
return "pyrdle_words_techy.txt", "TECHNICAL"
elif args.literary:
return "pyrdle_words_literary.txt", "LITERARY"
elif args.cultural:
return "pyrdle_words_cultural.txt", "CULTURAL"
elif args.full:
return "pyrdle_words_full.txt", "FULL"
elif args.hard:
return "pyrdle_words_hard.txt", "HARD"
elif args.medium:
return "pyrdle_words_medium.txt", "MEDIUM"
else: # Default to easy/common
return "pyrdle_words_easy.txt", "EASY"
def main(stdscr):
"""Main game loop"""
# Parse command line arguments
word_file, difficulty_name = parse_arguments()
# Initialize curses
curses.curs_set(0) # Hide cursor
stdscr.clear()
# Initialize colors
curses.start_color()
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) # Default
curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_GREEN) # Correct position
curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_YELLOW) # Wrong position
curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_RED) # Not in word (confirmed absent)
curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_BLACK) # Current input
curses.init_pair(6, curses.COLOR_WHITE, curses.COLOR_BLACK) # Unused letters (gray/dim)
# Initialize game
game = pyrdleGame()
if not game.load_words(word_file):
# Try fallback to default word list
if word_file != "pyrdle_words.txt" and game.load_words("pyrdle_words.txt"):
difficulty_name = "DEFAULT"
else:
stdscr.addstr(0, 0, f"Error: Could not load word list from {word_file}")
stdscr.addstr(1, 0, "Press any key to exit...")
stdscr.getch()
return
message = ""
message_color = 1
while True:
stdscr.clear()
height, width = stdscr.getmaxyx()
# Calculate vertical positions
y_pos = 1
# Draw components
draw_title(stdscr, y_pos, difficulty_name)
y_pos += 2
draw_board(stdscr, game, y_pos)
y_pos += game.max_guesses * 2 + 1
draw_keyboard(stdscr, game, y_pos)
y_pos += 4
# Draw message if exists
if message:
draw_message(stdscr, message, y_pos, message_color)
y_pos += 2
# Draw instructions at bottom
if y_pos + 6 < height:
draw_instructions(stdscr, y_pos)
# Show game over message
if game.game_over:
y_pos = height - 3 if height > 20 else y_pos
if game.won:
win_message = f"Congratulations! You won in {len(game.guesses)} guesses!"
draw_message(stdscr, win_message, y_pos, 2)
else:
lose_message = f"Game Over! The word was: {game.target_word}"
draw_message(stdscr, lose_message, y_pos, 4)
draw_message(stdscr, "Press 'N' for new game or 'Q' to quit", y_pos + 1, 1)
stdscr.refresh()
key = stdscr.getch()
if key in [ord('n'), ord('N')]:
# Start new game
game = pyrdleGame()
game.load_words(word_file)
message = ""
continue
elif key in [ord('q'), ord('Q'), 27]: # 27 is ESC
break
continue
stdscr.refresh()
# Get input
key = stdscr.getch()
# Handle input
if key == 27: # ESC key
break
elif key == ord('\n'): # Enter key
if len(game.current_guess) == game.word_length:
success, _ = game.make_guess(game.current_guess)
if success:
game.current_guess = ""
message = ""
else:
message = "Not in word list!"
message_color = 4
else:
message = f"Word must be {game.word_length} letters!"
message_color = 4
elif key == curses.KEY_BACKSPACE or key == 127: # Backspace
if game.current_guess:
game.current_guess = game.current_guess[:-1]
message = ""
elif ord('a') <= key <= ord('z'): # Lowercase letter
if len(game.current_guess) < game.word_length:
game.current_guess += chr(key).upper()
message = ""
elif ord('A') <= key <= ord('Z'): # Uppercase letter
if len(game.current_guess) < game.word_length:
game.current_guess += chr(key)
message = ""
if __name__ == "__main__":
# Handle help before initializing curses
if "--help" in sys.argv or "-h" in sys.argv:
# Parse arguments just to show help
word_file, difficulty = parse_arguments()
sys.exit(0)
try:
curses.wrapper(main)
except KeyboardInterrupt:
sys.exit(0)

2771
wordlists/pyrdle_words.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,247 @@
ADOBE
ALOHA
ALTAR
AMIGO
AMISH
AORTA
ATOLL
BABEL
BAGEL
BAYOU
BIMBO
BINGO
BIOME
BISON
BLITZ
BONGO
BORAX
BRAVO
BREWS
BRIGS
BRINY
BUDGE
BUGLE
BULKS
BUNKS
BURRO
CACTI
CALMS
CALYX
CAMEL
CAMEO
CANAL
CANDY
CANOE
CANON
CANTO
CAPED
CAPER
CAPON
CARNY
CAROL
CARPS
CASTE
CAULK
CAVED
CAVER
CAVES
CAVIL
CEASE
CEDAR
CEDED
CELEB
CELLO
CENTS
CHAFE
CHAFF
CHAMP
CHANT
CHAOS
CHAPS
CHARD
CHARM
CHARS
CHARY
CHASM
CHATS
CHEAP
CHEAT
CHECK
CHEEK
CHEEP
CHEER
CHESS
CHEST
CHEWY
CHICK
CHIDE
CHIEF
CHILD
CHILE
CHILI
CHILL
CHIME
CHIMP
CHINA
CHINK
CHINO
CHIPS
CHIRP
CHIVE
CHOCK
CHOIR
CHOKE
CHOMP
CHOPS
CHORD
CHORE
CHOSE
CHOWS
CHUCK
CHUMP
CHUNK
CHURN
CHUTE
CIDER
CIGAR
CINCH
CIRCA
CISCO
CITED
CITES
CIVET
CIVIC
CIVIL
CLACK
CLAIM
CLAMP
CLAMS
CLANG
CLANK
CLAPS
CLASH
CLASP
CLASS
CLAWS
CLAYS
CLEAN
CLEAR
CLEAT
CLEFT
CLERK
CLICK
CLIFF
CLIMB
CLIME
CLING
CLINK
CLOAK
CLOCK
CLONE
CLOPS
CLOSE
CLOTH
CLOTS
CLOUD
CLOUT
CLOVE
CLOWN
CLUBS
CLUCK
CLUED
CLUES
CLUMP
CLUNG
CLUNK
COACH
COALS
COAST
COATS
COBRA
COCKY
COCOA
CODED
CODER
CODES
CODEX
CODON
COEDS
COILS
COINS
COKES
COLDS
COLON
COLOR
COLTS
COMBO
COMBS
COMER
COMES
COMET
COMFY
COMIC
COMMA
CONCH
CONDO
CONED
CONES
CONEY
CONGA
CONGO
CONKS
COOED
COOKS
COOLS
COOPS
COOPT
COPED
COPER
COPES
COPSE
CORAL
CORDS
CORED
CORER
CORES
CORGI
CORKS
CORKY
CORNY
CORPS
COSTS
COUCH
COUGH
COULD
COUPE
COUPS
COURT
COUTH
COVEN
COVER
COVES
COVET
COWED
COWER
COYLY
COZEN
CRABS
CRACK
CRAFT
CRAGS
DHOTI
DINGO
DIRGE
DODOS
DOGMA
DOILY
DONNA
DONOR
DONUT
DOOMS
DOOZY
DOPED
DOPER
DOPES
DOPEY
DORKS
DORKY

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
ADAGE
AGLOW
ALOFT
APACE
ARDOR
ASKEW
ASPEN
ATONE
AUGUR
AVIAN
AVION
AWASH
BALMY
BEGOT
BELIE
BERTH
BESET
BESOT
BIDED
BILGE
BOWER
BRACE
BRIAR
BRINE
BRINY
CAIRN
CHIDE
CLEFT
COUTH
CRAVE
CREST
DALLY
DEWED
DIRGE
DOTED
DOWER
DREAR
DUSKY
DWELT
EAVES
EBBED
EDIFY
ELEGY
EMBER
ENSUE
EPOCH
ERRED
ESTOP
ETUDE
EVADE
EXALT
EXULT
FABLE
FEIGN
FEINT
FERAL
FETID
FJORD
FLESH
FLORA
FOLLY
FORGE
FORTE
FOUNT
FRIAR
FROST
FROTH
GABLE
GAILY
GAVEL
GLADE
GLEAN
GLOAM
GNARL
GNASH
GNOME
GORGE
GOUGE
GRAVE
GREBE
GRIEF
GRIFT
GRIME
GROVE
GUILD
GUILE
GULCH
GULLY
GUSTS
GUSTY
HAPLY
HARDY
HASTE
HAUNT
HAVEN
HEADY
HEATH
HEDGE
HEIGH
HENCE
HERON
HOARD
HOARY
HOIST
HOLLY
HORDE
HOUND
HOVEL
HOVER
IDYLL
INANE
INLET
LEDGE
LOFTY
MELEE
OCEAN
ONSET
OUGHT
PERCH
PIOUS
PLAIN
PLUMB
PRIDE
PRIME
PRIVY
PROUD
PROVE
PSALM
QUEST
QUEUE
QUITE
RAPID
REALM
REBEL
REIGN
RIDGE
RIVAL
ROOST
ROUGE
ROUTE
ROVER
RUDDY
RUMOR
SALLY
SCALE
SCORN
SEVER
SHADE
SHARD
SHAWL
SHEAR
SHEEN
SHIED
SHIRE
SHONE
SHORN
SHOVE
SHOWN
SHREW
SHRUB
SHUCK
SHUNT
SIEGE
SINEW
SINGE
SIREN
SLATE
SLEEK
SLEET
SLICK
SLIME
SLIMY
SLING
SLOSH
SLOTH
SMALL
SMEAR
SMELT
SMILE
SMIRK
SMITE
SMITH
SMOKE
SNARE
SNARL
SNEER
SNIDE
SNIFF
SNORE
SNORT
SNOUT
SNOWY
SOBER
SOGGY
SOLAR
SOLVE
SONAR
SONIC
SOOTH
SOOTY
SORRY
SOUND
SOUTH
SPACE
SPADE
SPARE
SPARK
SPAWN
SPEAK
SPEAR
SPECK
SPEED
SPELL
SPELT
SPEND
SPENT
SPIED
SPIEL
SPIKE
SPIKY
SPILL
SPINE
SPINY
SPIRE
SPITE
SPLAT
SPLIT

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,337 @@
ALLOY
ALPHA
AMINO
ARRAY
ASSAY
AUDIO
AXIAL
AXIOM
AZURE
BATCH
BATON
BIOME
BIPED
CACHE
CALYX
CARET
CASES
CASTS
CELLS
CHIPS
CHORD
CHUNK
CIRCA
CITED
CLAMP
CLONE
CLOUD
CODON
COILS
COMET
CORAL
CORES
CRAMP
CRANK
CREST
CRUST
CRYPT
CUBIC
CUBIT
CURVE
CYCAD
CYCLE
CYNIC
CYSTS
DATUM
DEBUG
DECAF
DECAL
DECAY
DECOR
DECOY
DEFER
DEFOG
DELTA
DENSE
DEPOT
DEPTH
DETOX
DIODE
DIPPY
DISCO
DISCS
DISKS
DOPED
DOPER
DOSES
DRAFT
DRAIN
DRIFT
DRILL
DRONE
DRUPE
DUALS
DUREX
DWELL
EBOOK
EDEMA
ELUTE
EMAIL
EMCEE
EMEND
EMIRS
EMITS
EMOTE
EPOCH
EPOXY
ERGOT
ERUPT
ESTER
ETHER
ETHIC
ETHOS
EUROS
EVADE
EXACT
EXALT
EXECS
EXERT
EXILE
EXIST
EXITS
EXPAT
EXPEL
EXPOS
EXTRA
EXUDE
EXULT
EXURB
FECAL
FECES
FEMUR
FERMI
FETAL
FETUS
FIBER
FIBRE
FIELD
FILES
FILTH
FINAL
FINED
FINER
FINIS
FINNY
FIORD
FIXED
FIXER
FIZZY
FJORD
FLAGS
FLASK
FLECK
FLEXS
FLINT
FLOAT
FLORA
FLOUR
FLUKY
FLUME
FLUOR
FLUSH
FOCAL
FOCUS
FOILS
FONTS
FORCE
FORMS
FORTE
FORUM
FOSSE
FOXED
FRAME
FREED
FRESH
FRITS
FROND
FROST
FROTH
FUGAL
FUGUE
FUMED
FUMES
FUNGI
FUNGO
FURLS
FUROR
FURTH
FUSED
FUSEE
FUSEL
FUSES
FUTON
FUZED
FUZES
FUZZY
GAGES
GALES
GAMMA
GANGS
GASES
GATED
GATES
GAUGE
GAUNT
GAUSS
GAUZE
GAVEL
GEARS
GECKO
GEEKS
GEESE
GENES
GENIE
GENII
GENRE
GENUS
GEODE
GERMS
GESSO
GIDDY
GILDS
GILLS
GIMPS
GIRTH
GISMO
GIZMO
GLAND
GLASS
GLAZE
GLEAM
GLEAN
GLIDE
GLIMS
GLINT
GLITZ
GLOBE
GLOBS
GLOPS
GLOSS
GLOWS
GLOZE
GLUED
GLUES
GLUEY
GLUMS
GLUON
GLUTE
GLUTS
GLYPH
GNASH
GNOME
GONAD
GONGS
GOODS
GOUGE
GOURD
GOUTS
GRADE
GRADS
GRAFT
GRAIN
GRAMS
GRAPH
GRASP
GRATE
GRAVE
GRAYS
GRAZE
GREBE
GREED
GREYS
GRIDE
GRIDS
GRIFF
GRIFT
GRILL
GRIME
GRIMY
GRIND
GRINS
GRIPE
GRIPS
GRIST
GRITS
GROAN
GROAT
GROGS
GROIN
GROOM
GROPE
GROSS
GROTS
GROUP
GROUT
GROVE
GROWL
GROWN
GROWS
GRUBS
GRUEL
GRUFF
GRUMP
GRUNT
GUANO
GUARD
GUAVA
GUESS
GUEST
GUIDE
HELIX
HERTZ
HEXAD
HEXED
HEXES
HYENA
HYOID
HYPED
HYPER
HYPES
HYPHA
HYPOS
ICHOR
ICONS
IDEAL
IDEAS
IDOLS
IMAGE
IMBED
IMBUE
IMPEL
INANE
INBOX
INCUR
INDEX
INDIE
INERT
INFER
INFIX
INKLE
INLAY
INLET
INNER
INPUT
INRUN
INTER
INTRO
INURE
INURN
INVAR
IODIC
IODID
IODIN
IONIC
IOTAS
IRADE
IRATE
IRIDS

File diff suppressed because it is too large Load Diff