32word
The game engine for 3-2-Word: Solve Wordle in three guesses.

What This Is
Most people play Wordle casually. Guess some vowels. Eliminate common letters. Hope for the best. Maybe they've heard that STAIR + LEMON + PUDGY is unbeatable.
We know better.
3-2-Word is a training app that elevates Wordle from a casual puzzle into something you can practice and master—like Scrabble or a spelling bee. This library (32word) is the engine underneath.
Smart players solved Wordle years ago. They proved optimal strategies mathematically. But most people didn't change how they played. This library changes that. It codifies the strategies that work and makes them accessible to everyone.
It's fun to challenge yourself. It's fun to be smart. This gives you the tools to win.
Installation
pip install 32word
Why This Exists
You can solve Wordle blindly, or you can learn the patterns that elite players discovered through exhaustive analysis. This library provides:
- Optimal two-guess strategies that consistently solve Wordle in three attempts
- Pre-computed strategy tables based on simulations across all 3,158 target words
- A clean API for building bots, websites, and training tools
The solver logic lives here. Everything else—web apps, Discord bots, Telegram bots—imports this library as a dependency.
Quick Start
from word32 import generate_clue, filter_targets, load_strategy, get_second_guess
strategy = load_strategy("v1.0")
first_guess = strategy.first_guess()
print(f"First guess: {first_guess}")
target = "TRASH"
clue = generate_clue(first_guess, target)
print(f"Clue: {clue}")
from word32 import VALID_TARGETS
remaining = filter_targets(VALID_TARGETS, first_guess, clue)
print(f"{len(remaining)} words remain")
second_guess = get_second_guess(strategy, clue)
print(f"Second guess: {second_guess}")
Two guesses. Then solve. That's the strategy.
Phase 4.2/4.3 Features
The library now includes enhanced features for building interactive applications:
Response Schema (Phase 4.2)
Standardized JSON responses for cross-platform consistency:
from word32 import build_game_response, get_second_guess_recommendation
response = build_game_response(
guess="RAISE",
clue=('G', 'Y', 'X', 'X', 'G'),
remaining_targets=['AGILE', 'ALIAS', 'AMISS'],
strategy_recommendation={
'recommended_guess': 'CLOUD',
'confidence': 0.95
},
game_state={
'guess_number': 1,
'guesses_so_far': ['RAISE'],
'is_solved': False
}
)
print(response.to_json())
Custom First Guess Selection (Phase 4.3)
Choose from 32 optimal first guesses:
from word32 import get_available_first_guesses, select_first_guess, get_second_guess_recommendation
options = get_available_first_guesses()
for opt in options[:5]:
print(f"{opt['first_guess']} - Rank {opt['rank']}, Expected: {opt['expected_remaining']:.1f}")
selected = select_first_guess("RAISE")
if selected:
print(f"Selected: {selected['first_guess']} (Rank {selected['rank']})")
clue = ('G', 'Y', 'X', 'X', 'G')
recommendation = get_second_guess_recommendation("RAISE", clue)
print(f"Recommended second guess: {recommendation}")
Remaining Words Tracking
Track and display remaining possible words:
from word32 import build_game_response, filter_targets, VALID_TARGETS
remaining = filter_targets(VALID_TARGETS, "RAISE", ('G', 'Y', 'X', 'X', 'G'))
response = build_game_response(
guess="RAISE",
clue=('G', 'Y', 'X', 'X', 'G'),
remaining_targets=remaining,
sample_size=10
)
print(f"{response.remaining.count} words remain")
print(f"Sample: {response.remaining.sample}")
Minimal Memorization Strategies (Phase 4.8/4.9)
For mobile apps or players who want minimal memorization, use optimized 2d+8r strategies with tiny lookup tables (~650 bytes):
from word32 import load_strategy_by_components, list_strategies_by_depth
strategy = load_strategy_by_components("TRICE", 8)
strategies_8r = list_strategies_by_depth(8)
print(f"Available 8r strategies: {strategies_8r}")
clue = ('G', 'Y', 'X', 'X', 'G')
second_guess = strategy.get_second_guess(clue)
print(f"Recommended second guess: {second_guess}")
Trade-offs:
- ✅ Compact: ~650 bytes per strategy vs 425 KB for full lookup
- ✅ Portable: Ideal for mobile/embedded apps
- ⚠️ Coverage: Only 8 clue patterns per first guess (vs ~240 for full)
- ⚠️ Win rate: 37-39% for 2-guess wins (vs 90%+ for full strategy)
Best for: 3-guess play, mobile constraints, or training progression.
Integration Guides:
Core API
Clue Generation
generate_clue(guess: str, target: str) -> tuple[str, str, str, str, str]
Returns a 5-tuple representing Wordle's feedback:
'G': Green (correct letter, correct position)
'Y': Yellow (correct letter, wrong position)
'B': Black/Gray (letter not in target)
Example:
generate_clue("STARE", "TRASH")
Target Filtering
filter_targets(targets: list[str], guess: str, clue: tuple) -> list[str]
Returns all words in targets that would produce exactly clue if you guessed guess against them.
Example:
remaining = filter_targets(VALID_TARGETS, "STARE", ('G', 'Y', 'B', 'B', 'G'))
Strategy Loading
load_strategy(version: str = "v1.0") -> Strategy
Loads a pre-computed strategy table. The default v1.0 uses expected-remaining minimization over all 3,158 Wordle targets.
Strategy methods:
strategy = load_strategy("v1.0")
first = strategy.first_guess()
second = strategy.second_guess(clue)
meta = strategy.metadata()
Convenience Functions
get_second_guess(strategy: Strategy, first_clue: tuple) -> str
Shortcut for getting the optimal second guess.
is_valid_word(word: str) -> bool
Check if a word is in Wordle's valid guess list (14,855 words).
get_remaining_candidates(targets: list[str], guess: str, clue: tuple) -> int
Count how many targets remain after a guess.
Strategy Design
Each strategy is a lookup table built from tournament simulations. The process:
- First guess selection: Test every valid target word as a first guess against all 3,158 possible Wordle targets
- Clue simulation: For each first guess, generate all possible clues (up to 243 patterns, though most never occur)
- Second guess optimization: For each (first_guess, clue) pair, find the second guess that minimizes expected remaining candidates
- Tournament ranking: Score strategies by expected remaining words after two guesses across all targets
The default v1.0 strategy consistently leaves 1–3 candidates after two guesses, making the third guess nearly deterministic.
Strategy Metadata
strategy = load_strategy("v1.0")
meta = strategy.metadata()
print(meta)
Complete Example
from word32 import (
generate_clue,
filter_targets,
load_strategy,
get_second_guess,
VALID_TARGETS
)
strategy = load_strategy("v1.0")
target = "TRASH"
remaining = VALID_TARGETS.copy()
guess1 = strategy.first_guess()
clue1 = generate_clue(guess1, target)
remaining = filter_targets(remaining, guess1, clue1)
print(f"After '{guess1}': {len(remaining)} words remain")
guess2 = get_second_guess(strategy, clue1)
clue2 = generate_clue(guess2, target)
remaining = filter_targets(remaining, guess2, clue2)
print(f"After '{guess2}': {len(remaining)} words remain")
if len(remaining) == 1:
print(f"Solved in 3: {remaining[0]}")
elif len(remaining) <= 3:
print(f"Choose from: {remaining}")
else:
print(f"Manual selection needed from {len(remaining)} candidates")
Most games end after two optimal guesses with 1–3 candidates remaining.
Architecture
This library is designed as a single source of truth for Wordle solver logic. All downstream applications (website, bots, mobile apps) import this package.
32word (PyPI library)
↓
├─ 3-2-Word website (React + Flask/FastAPI)
├─ Discord bot
├─ Telegram bot
├─ Signal bot
└─ WhatsApp bot (future)
Design Principles
- Stateless: All functions are deterministic and side-effect-free
- Fast: Word lists cached in memory, strategy tables pre-computed
- Tested: 95%+ coverage on core logic (clue generation, filtering)
- Versioned: Strategy tables versioned independently from library code
- Simple API: Six core functions cover all use cases
Development
Running Tests
pip install -e ".[dev]"
pytest tests/ -v --cov=word32
Package Structure
word32/
├── __init__.py # Public API exports
├── core.py # Clue generation, filtering
├── strategy.py # Strategy loading and lookup
├── validation.py # Word list validation
├── data/
│ ├── strategies/
│ │ └── v1.0.json # Pre-computed optimal strategy
│ ├── targets.txt # 3,158 Wordle targets
│ └── valid_guesses.txt # 14,855 valid guesses
└── tests/
├── test_clues.py
├── test_filtering.py
├── test_strategy.py
└── test_integration.py
Creating New Strategies
Strategy tables are JSON files in word32/data/strategies/:
{
"metadata": {
"version": "v1.1-minimax",
"penalty_function": "minimax",
"depth": 2,
"created": "2026-01-20"
},
"first_guess": "SALET",
"clues": {
"GGGGG": {"second_guess": "N/A", "remaining": 0},
"GGGYB": {"second_guess": "BLAND", "remaining": 2},
...
}
}
To add a new strategy:
- Run the tournament simulation to generate the table
- Save as
v{X}.{Y}-{variant}.json
- Submit a PR with test coverage
Roadmap
Phase 1: Core Library ✅
Phase 2: Downstream Apps (In Progress)
Phase 4.2: Response Schema ✅
Phase 4.3: First Guess Selection ✅
Future Extensions
Why MIT Licensed?
This code should be free. The insights are already published—researchers solved Wordle years ago. I'm just packaging it so anyone can use it.
Build a bot. Build a training app. Build a better solver. The game is solved. Now go teach people how to win.
Data Completeness
The library requires several data files for full functionality. See Data Completeness Checklist for details.
Required files:
data/targets.txt - 2,309 target words
data/valid_guesses.txt - 12,950 valid guesses
data/phase2_naive_32.json - 32 first guess options
data/phase3_lookup.json - Strategy lookup for all patterns
The library will warn on import if data files are missing or incomplete.
Contributing
Contributions welcome! Please:
- Open an issue before starting major work
- Write tests for new features
- Follow the existing style (stateless functions, simple API)
- Update docs if you change the API
Integration Examples:
Areas for Contribution
- New strategies: Minimax, three-deep, custom anchor words
- Performance: Optimize filtering, caching
- Variants: Quordle, Absurdle, other Wordle clones
- Tests: Edge cases, integration tests
- Docs: Tutorials, strategy explanations
Related Projects
- 3-2-Word website: 3-2-word.com
- Discord bot: Coming soon
- Telegram bot: Coming soon
Acknowledgments
Built on the shoulders of researchers who solved Wordle mathematically. This library packages their insights for practical use.
Special thanks to the Wordle community for exploring optimal strategies and making the game more interesting.
License
MIT License. See LICENSE for details.
3-2-Word: The training app for people who want to master Wordle.
Built by Ben Mazzotta. Engine: 32word.
Get better at Wordle. Start here.