# Wordle Clone v1 -- Task List

## Group 1: Word Bank & Data Layer

### 1.1 Curate the v1 word bank
- Source a frequency list of 5-letter English words from recent (last ~5 years) internet-based corpora (e.g., Twitter, Reddit, Wikipedia, Common Crawl snapshots).
- Filter out proper nouns, hyphenated forms, acronyms, offensive terms, and archaic/obsolete words.
- Produce a master list split into:
  - **Solution words** (common enough to be guessable, ~2,000-4,000 words).
  - **Valid guess words** (all reasonably known 5-letter words, ~10,000-15,000 words, includes solutions).
- Store both lists in a structured format (JSON arrays or line-delimited text files) checked into the repo or loaded at build time.

### 1.2 Build the word metadata module
- Define a data model for word metadata: unique word ID, text, difficulty tier (auto-computed, see Group 4), global attempt-count histogram, and a flag for "has image" (for simple words).
- Implement a module that loads and serves word data: `getDailyWord(date)`, `getRandomWord(excludeIds?)`, `isValidGuess(word)`.
- Wire up a dictionary API integration (e.g., Free Dictionary API) to fetch definitions, parts of speech, and etymology on demand, with a local cache to avoid re-fetching.

### 1.3 Set up the image store for simple words
- Identify the top ~200-500 most concrete/imageable solution words (nouns, animals, objects, etc.).
- Source or generate a small thumbnail/illustration for each (Creative Commons, Unsplash, or generated).
- Store images in a `/public/images/words/` directory keyed by word, and add the flag to metadata.

---

## Group 2: Core Gameplay Engine

### 2.1 Implement word validation
- Validate that a submitted guess is exactly 5 letters, alphabetic, and present in the valid-guess list.
- Return a structured error for invalid guesses (too short, too long, not a word).

### 2.2 Implement guess evaluation (green/yellow/gray)
- Given a target word and a guess, produce a per-letter result array.
- Correct handling of duplicate letters: a letter that appears twice in the guess but once in the target should show at most one green, then at most one yellow if unmet.
- Each position returns: `correct` (green -- right letter, right spot), `present` (yellow -- right letter, wrong spot), `absent` (gray -- letter not in word or all occurrences already accounted for).

### 2.3 Build the game session state machine
- A session holds: target word, guess history (ordered list), game status (`playing`, `won`, `lost`), attempt count, start time, and hint tier received (none, 5th-attempt hint, 6th-attempt hint).
- Enforce the 6-attempt maximum.
- Expose a pure function: `submitGuess(session, guess) -> updatedSession` (stateless/immutable-friendly for portability).

### 2.4 Wire up the daily word flow
- Use a deterministic function `dateToDailyWordIndex(date)` so every player gets the same word each calendar day.
- On first visit each day, auto-start a session with the daily word.
- After the daily game ends (win or lose), present a clear CTA: "Play more -- endless mode" that starts a new non-daily session with a random word.

### 2.5 Implement the infinite/after-play mode
- After the daily game, allow unlimited additional games with random solution words.
- Non-daily sessions are flagged so they do not count toward daily-only leaderboards/percentiles but do feed into adaptive difficulty data and personal lifetime stats.

---

## Group 3: Computer Baseline Solver

### 3.1 Implement a known-algorithm solver
- Build a solver that uses a standard Wordle strategy (e.g., entropy-based / min-max narrowing, starting from a fixed opener like SLATE or CRANE).
- The solver takes a target word and returns the number of attempts needed and the guess sequence.

### 3.2 Pre-compute the full solution-word baseline
- Run the solver against every word in the solution-word list and store the attempt count for each.
- Output a JSON/mapping file: `{ word: string, solverAttempts: number }` for the full solution set.
- This data is the foundation for difficulty tiering (Group 4) and for showing "computer took X attempts" context to players post-solve.

### 3.3 Expose solver replay as a teaching tool (post-solve)
- After a player solves (or loses), offer an animation/replay view: "See how a computer solver would tackle this word."
- Show the solver's guess sequence with the same green/yellow/gray grid format.

---

## Group 4: Adaptive Difficulty System

### 4.1 Implement per-word global attempt tracking
- On every game completion (daily or endless), record: word ID, attempt count (1-6), loss flag, and whether hints were received.
- Persist aggregated stats per word: total plays, total attempts sum, attempt-count histogram (buckets 1-6 plus loss), and current average attempts.

### 4.2 Implement difficulty-tier assignment
- Using the pre-computed solver baseline (Group 3) plus live player data, assign each solution word to a difficulty tier (e.g., Easy / Medium / Hard / Expert).
- Tiers are defined by thresholds on global average attempts: Easy (<= 3.5), Medium (3.5-4.5), Hard (4.5-5.5), Expert (> 5.5 or high loss rate). Exact thresholds are tunable.
- Recalculate tiers periodically (nightly batch) so they self-adjust as more data accumulates.

### 4.3 Implement adaptive word selection
- Track a hidden player skill rating (Elo or simple moving average of recent performance vs. global averages).
- On daily word selection: clamp within a mid-tier band at launch; over time, use the player's rating to bias toward words at the edge of their capability -- slightly harder than their recent average but not Expert-tier for beginners.
- For endless mode: random sampling weighted by the player's current skill band.

### 4.4 Store and surface a player MMR/Badge
- Maintain a moving-window skill score per player (last N games vs. global averages).
- Map score ranges to named badges (e.g., "Novice", "Word-smith", "Lexicon Master") displayable on the profile/stats screen.

---

## Group 5: Hints System

### 5.1 Design the standardized hints
- Define hint templates that do NOT reveal letter positions (to preserve stats comparability):
  - 5th-attempt hint (weaker): e.g., part of speech + first letter.
  - 6th-attempt hint (stronger): e.g., definition or usage in a sentence (still no position info).
- All hints must be deterministic from the target word so every player on the same word+attempt gets the identical hint.

### 5.2 Implement hint delivery in the game session
- After the 4th guess (i.e., entering the 5th attempt), offer the 5th-attempt hint. Player may dismiss it.
- After the 5th guess (entering the 6th attempt), auto-display the 6th-attempt hint.
- Flag the session when a hint is shown so stats can segment "solved with hints" vs. "solved without hints."

---

## Group 6: Results Screen & Statistics

### 6.1 Build the post-game results view
- Show: win/loss, number of attempts taken (1-6 or X for loss), the full guess grid with color feedback.
- Show the daily word's definition, part of speech, etymology, and an example sentence.
- For simple words that have an illustration: show the image.

### 6.2 Implement percentile ranking
- For the daily word, rank all players by: (attempts ascending, tie-broken by time-to-solve).
- Compute and display the player's percentile: "You solved this in the top X% today."
- Update in near-realtime (or on page refresh) as more players finish.

### 6.3 Build the lifetime statistics view
- Histogram by attempts: bar chart showing how many games ended in 1, 2, 3, 4, 5, 6 guesses, plus losses.
- Win rate percentage.
- Current and longest streak (see Group 7).
- Average attempts (for wins).
- Games played total (daily + endless).

---

## Group 7: Streak Tracking with Quality Weighting

### 7.1 Implement basic streak tracking
- A win on the daily word increments the current streak; a loss resets it to 0.
- Track the longest streak ever achieved.

### 7.2 Implement quality-weighted streaks
- Each daily win contributes a "quality score" proportional to: (7 - attempts) * difficultyWeight, where difficultyWeight is derived from the word's current global-average tier.
- Track both the raw streak count and the cumulative quality-weighted streak score.
- Display: "Current streak: 12 (Quality Score: 47.3)" and "Best Quality Streak: 52.1".
- Harder-word wins contribute more weight; a 3-guess solve on an Expert word is far more valuable than a 3-guess on an Easy word.

---

## Group 8: Keyboard & UI Input

### 8.1 Build the on-screen keyboard
- Render a QWERTY keyboard layout (3 rows: QWERTYUIOP / ASDFGHJKL / ZXCVBNM, plus Enter and Backspace keys).
- Support both on-screen tap/click and physical keyboard typing.

### 8.2 Implement letter-state highlighting on the keyboard
- After each guess, update each key's background to reflect its known state:
  - **Green**: letter is `correct` in at least one position.
  - **Yellow**: letter is `present` but not `correct` in any position.
  - **Gray**: letter has been guessed and is `absent`.
- Green overrides yellow overrides gray (priority: best-known state for that letter).

### 8.3 Build the guess input row
- Render a 5-column x 6-row grid showing all guesses submitted so far plus the current in-progress row.
- Each cell shows the letter and its color state (flip animation on reveal).
- Empty rows render as blank cells.

### 8.4 Handle invalid guess UX
- If a guess is not in the valid-word list, shake the current row (CSS animation) and clear the input for retry -- do not consume an attempt.
- If the guess is too short, do nothing until 5 letters are entered.

---

## Group 9: Post-Solve Learning Layer

### 9.1 Fetch and display word definition
- After game completion, call the dictionary API for the target word.
- Display: definition(s), part of speech, phonetic pronunciation.

### 9.2 Fetch and display etymology
- Pull etymology data if available from the dictionary API.
- Display a brief "Word Origin" section.

### 9.3 Display image for simple words
- If the target word has an associated image (see 1.3), display it alongside the definition.

### 9.4 Offer solver replay (ties to Group 3)
- Button: "See how the computer solved this."
- Plays back the solver's guess sequence step-by-step on the same grid layout.

---

## Group 10: Polish & Cross-Cutting

### 10.1 Mobile-responsive layout
- Game grid, keyboard, results, and stats views all render correctly on viewports from 320px wide to desktop.
- Keyboard sizing and spacing adapt to screen width.

### 10.2 Animations
- Tile flip animation on each guess submission (letter reveals with color).
- Win animation (e.g., tiles bounce).
- Shake animation on invalid word.

### 10.3 Local-storage persistence
- Persist game session state to `localStorage` so a refresh mid-game does not lose progress.
- Persist lifetime stats and streak data locally; sync to backend when available.

### 10.4 Accessibility
- Semantic ARIA labels on the grid, keyboard, and results.
- Color states supplemented with text/symbol indicators for color-blind players (e.g., subtle icon or pattern on green/yellow/gray tiles).
- Full keyboard-navigable input flow.

### 10.5 Dark mode
- Support a light/dark/system theme toggle.
- All color states (green/yellow/gray) adapt for contrast in both modes.

---

## Suggested Build Order

| Phase | Groups | Why |
|-------|--------|-----|
| **Phase A** | 2 (Core Engine) + 1.1 (Word Bank) | Playable console/headless game first -- validate core loop |
| **Phase B** | 1.2 (Metadata) + 8 (Keyboard/UI) + 10.3 (Persistence) | Minimal interactive UI, playable in browser |
| **Phase C** | 2.4/2.5 (Daily + Infinite) + 6 (Results/Stats) + 7 (Streaks) | Full single-player experience with stats |
| **Phase D** | 4 (Adaptive Difficulty) + 5 (Hints) | Difficulty tuning and retention mechanics |
| **Phase E** | 3 (Computer Solver) + 9 (Post-Solve Learning) | Enrichment layer -- teaching + deeper stats context |
| **Phase F** | 10.1/10.2/10.4/10.5 (Polish) | Ship-quality fit and finish |
