Skip to content

Grid Engines

Word Search Generator

Generates word search puzzles dynamically. The database only stores words and clues; the engine generates the grid.

Usage

const grid = engine.generateWordSearch(
[
{ word: 'APPLE', clue: { type: 'TEXT', value: 'A red fruit' } },
{ word: 'DOG', clue: { type: 'TEXT', value: 'A loyal pet' } },
],
12, // gridSize
true, // allowDiagonal
false, // allowReverse
);

Response

{
"grid": [
["A", "P", "P", "L", "E", "X", "K", "M", "R", "T", "W", "Z"],
["B", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A"],
["...", "...", "...", "...", "...", "...", "...", "...", "...", "...", "...", "..."]
],
"placedWords": [
{
"word": "APPLE",
"clue": { "type": "TEXT", "value": "A red fruit" },
"startRow": 0,
"startCol": 0,
"direction": [0, 1]
}
],
"size": 12
}

Directions

DirectionVectorDescription
Horizontal →[0, 1]Always available
Vertical ↓[1, 0]Always available
Diagonal ↘[1, 1]If allowDiagonal: true
Diagonal ↙[1, -1]If allowDiagonal: true
Horizontal ←[0, -1]If allowReverse: true
Vertical ↑[-1, 0]If allowReverse: true
Diagonal ↖[-1, -1]If both: true
Diagonal ↗[-1, 1]If both: true

Algorithm

  1. Sort words by length (longest first)
  2. For each word, try 100 random positions
  3. Place if no conflict (empty cell or same letter)
  4. Fill empty cells with random letters (A-Z)
  5. Return grid + placed words metadata

Crossword Generator

Generates crosswords with automatic backtracking.

Usage

const crossword = engine.generateCrossword(
[
{ answer: 'CAT', clue: { type: 'TEXT', value: 'A small animal' } },
{ answer: 'ACT', clue: { type: 'TEXT', value: 'To do something' } },
{ answer: 'DOG', clue: { type: 'TEXT', value: 'A loyal pet' } },
],
10, // gridSize
);

Response

{
"grid": [
["", "", "C", "", ""],
["", "", "A", "", ""],
["C", "A", "T", "", ""],
["", "", "", "", ""],
["...", "...", "...", "...", "..."]
],
"placements": [
{
"word": "CAT",
"clue": { "type": "TEXT", "value": "A small animal" },
"row": 2,
"col": 0,
"direction": "across",
"number": 1
},
{
"word": "ACT",
"clue": { "type": "TEXT", "value": "To do something" },
"row": 0,
"col": 2,
"direction": "down",
"number": 1
}
],
"size": 10
}

Algorithm

  1. Sort words by length (longest first)
  2. Place first word horizontally in the center
  3. For each remaining word, find valid intersections with backtracking
  4. Validate no adjacent letter conflicts
  5. Retry up to 50 times if it fails
  6. Fallback to linear mode (separate words) if crossing fails
  7. Auto-assign clue numbers

Crossing Rules

  • A word must share at least one letter with existing words
  • No perpendicular adjacent letters that aren’t part of another word
  • No letters before or after the word in the same direction

Integration with the Engine

The ExerciseEngineService exposes both generators:

// Word Search
const ws = engine.generateWordSearch(words, 12, true, false);
// Crossword
const cw = engine.generateCrossword(words, 10);

The VocabularyProcessor uses them internally to evaluate WORD_SEARCH and CROSSWORD exercises.