How AnyTool Places Words and Fills the Grid
Generation runs entirely in the browser. The raw word list is first sanitized — uppercased, stripped to A–Z only, words under two letters dropped, and duplicates removed in first-seen order. A working grid size is chosen that is never smaller than the longest word (and at least 5×5, at most 30×30). Words are placed longest-first, since long words are the hardest to fit before the grid fills. For each word the engine builds every valid (start cell × allowed direction) option, shuffles them with the Web Crypto API (crypto.getRandomValues via rejection sampling, never Math.random), and walks them until one fits: a placement fits when it stays in bounds and every cell it covers is either empty or already holds the matching letter, so words may legally cross where they share a letter. Because the start options are exhaustive, a word is reported unplaceable only when it genuinely cannot fit the current grid. With Auto-grow on, the grid enlarges one step at a time until every word fits or it reaches 30×30. Finally, each still-empty cell is filled with a crypto-random letter A–Z so the hidden words blend in.
- Words sanitized: uppercased, letters-only, min 2 letters, de-duplicated
- Placed longest-first; start cells × directions shuffled with the Web Crypto API
- A word fits when in-bounds and overlaps only on matching letters (legal crossings)
- Unplaceable words are flagged; Auto-grow enlarges the grid (up to 30×30) to fit them
- Empty cells filled with crypto-random letters — all client-side, nothing uploaded
