Word Scramble++

A browser-based timed anagram game. Unscramble letters to form words from themed categories or a random pool, and compete for the high score. Visit /puzzles/wordscramble.

Architecture

The game is entirely client-side JavaScript. The server provides:

  1. The template (templates/wordscramble.html) — page layout with controls (category, timer, game area), high score sidebar, and name submission modal.
  2. The game script (static/js/wordscramble.js) — ~560 lines handling word selection, letter scrambling, timer, scoring, streak tracking, hint system, and high score API integration. Keyboard shortcuts: Enter to submit, Tab to skip, Space for hint.
  3. The game route (src/routers/wordscramble.py) — serves the template. High score endpoints are shared with existing games via src/routers/highscores.py and src/store.py.

The existing high score system is fully reused — no server-side changes were needed. Scores are stored per-category and per-timer combination under data/wordscramble_<category>_<timer>s/highscores.json (e.g. data/wordscramble_animals_60s/highscores.json).

Game Flow

  1. Player selects a Category (Animals, Countries, Programming, Space, Food, Sports, Music, Nature, Geography, Science, or Random).
  2. Player sets a Timer (30s / 60s / 90s / 120s) by clicking the button.
  3. Player clicks Start Game.
  4. A word is randomly picked from the category, scrambled, and displayed as letter tiles.
  5. The player types the answer and presses Enter (or clicks Submit).
  6. Correct: points are awarded and the next word appears after a 1.2s pause.
  7. Wrong: streak resets and the correct answer is shown before advancing.
  8. When the timer expires, the final score is checked against the high score leaderboard.

Scoring

Factor Formula
Base points word.length × 10
Streak multiplier min(streak, 5) — consecutive correct answers multiply points
Hint penalty ÷ 2 (rounded down) — using a hint halves the points for that word
Skip penalty −10 points per skip

The feedback after each correct answer shows the full breakdown, e.g.: - Correct! DOG = 30 (base) × 3 (streak) = 90 pts - Correct! PYTHON = 60 (base) ÷ 2 (hint) = 30 pts

Controls

Key Action
Enter Submit answer
Tab Skip word (−10 pts)
Space Hint (corrects one letter, halves points)

High Scores

When the timer ends, the game checks GET /api/highscores/check?game=wordscramble_<category>_<timer>s&score=N. If the score qualifies for the top 10, a modal appears with a 10-second countdown to submit a name. The leaderboard is displayed in the sidebar and refreshes after each submission. Each category and timer setting has its own independent leaderboard. A score of 0 is never considered a high score. All backed by the generic src/routers/highscores.py API and src/store.py store.

Word Categories

Category Word count
Animals ~60
Countries 50
Programming 50
Space 41
Food 52
Sports 30
Music 30
Nature 30
Geography 30
Science 30
Random ~132K (via data/words/english.txt)

The Random category fetches 50 words from /api/wordsearch/random-words?count=50 on each game start.

Files

File Role
templates/wordscramble.html Game template (layout, controls, high score sidebar, modals)
static/js/wordscramble.js Game engine (word selection, scramble, timer, scoring, high scores)
static/js/wordsearch.js Shared WORD_LISTS and random-words API (reused)
src/routers/wordscramble.py GET /puzzles/wordscramble
src/routers/highscores.py Generic high score API (shared with other games)
src/store.py Generic high score data store (shared)
data/words/english.txt Word pool for Random mode
tests/test_routes.py Route tests for puzzle page rendering