math-quiz-engine
v1.1.0
Published
Ultra-lightweight, zero-dependency math question generator with adaptive difficulty, cognitive distractors, mental math tips, LaTeX support, and full i18n.
Maintainers
Readme
🧮 math-quiz-engine
🌐 Language / Idioma: English · Español · Português · 中文
Ultra-lightweight, zero-dependency math question generator with adaptive difficulty, realistic cognitive distractors, mental math tips, LaTeX support, and full i18n — all in < 150 KB.
✨ Features
- ⚡ Zero dependencies — Pure TypeScript, < 150 KB bundle, blazing fast.
- 🌍 Multi-language (i18n) — Native support for English (
en), Spanish (es), Portuguese (pt), and Simplified Chinese (zh). Questions, hints, explanations, chapter names, and answer options are all localized. - 🎯 24 Math Chapters — From basic arithmetic to quadratic equations, trigonometry, and logarithms.
- 🧩 Cognitive Distractors — Wrong answers aren't random; they simulate real calculation mistakes (carry errors, PEMDAS confusion, fraction inversions, ± 10 shifts).
- 🧠 Mental Math Tips — Every question comes with a speed-solving hint and a step-by-step explanation.
- 📐 LaTeX Support — KaTeX / MathJax-ready representations for every question.
- 📈 Adaptive Difficulty — Automatically adjusts between
easy,normal,hard, andextremebased on player performance and response time. - 🎲 Seeded RNG — Reproducible question sequences for multiplayer sync, replays, or testing.
- 📦 Universal Bundle — Works with
import(ESM),require(CJS), and<script>(IIFE), with full.d.tstypings.
📦 Installation
npm install math-quiz-engineCDN (browser):
<script src="https://cdn.jsdelivr.net/npm/math-quiz-engine/dist/index.global.js"></script>
<script>
const engine = new MathQuizEngine.MathQuizEngine();
console.log(engine.generateQuestion());
</script>🚀 Quick Start
ESM (TypeScript / Modern JS)
import { MathQuizEngine, mathEngine } from 'math-quiz-engine';
// Option 1: Use the ready-made singleton
const q = mathEngine.generateQuestion();
// Option 2: Create your own configurable instance
const engine = new MathQuizEngine();
engine.setLocale('en');
const question = engine.generateQuestion({
category: 'fractions',
difficulty: 'hard',
includeHint: true,
includeLatex: true
});
console.log(question.question); // "7/8 − 2/3"
console.log(question.answer); // "5/24"
console.log(question.hint); // "Butterfly method: (7×3 − 2×8) over (8×3)..."
console.log(question.locale); // "en"CommonJS (Node.js)
const { mathEngine } = require('math-quiz-engine');
const q = mathEngine.generateQuestion({ category: 'multiplication_ab', difficulty: 'normal' });
console.log(q.question, '=', q.answer);📚 24 Chapters (Organized in 3 Eras)
| # | Category (category) | Era | Name | Example |
|:--|:--|:--|:--|:--|
| 01 | 'addition' | General | Speed Addition | 78 + 45 |
| 02 | 'subtraction' | General | Subtraction & Change | 142 − 89 or cash register change |
| 03 | 'multiplication_ab' | General | 2-Digit Multiplication | 14 × 17 (11-19 shortcut) |
| 04 | 'division' | General | Exact Division | 342 ÷ 9 |
| 05 | 'percentage' | General | Mental Percentages | 15% of 80 or 64% of 50 |
| 06 | 'fractions' | General | Fractions (+, −, ×, ÷) | 2/5 + 3/4 |
| 07 | 'combined_ops' | General | Order of Operations (PEMDAS) | 45 − 3 × 8 + 12 |
| 08 | 'estimation' | General | Estimation & Rounding | 89 × 41 ≈ ? |
| 09 | 'rule_of_three' | General | Rule of Three (Direct & Inverse) | 4 u. → $20, 12 u. → ? |
| 10 | 'fraction_to_decimal' | General | Fraction → Decimal | 3/8 = 0.375 |
| 11 | 'decimal_to_fraction' | General | Decimal → Fraction | 0.75 = 3/4 |
| 12 | 'powers_of_ten' | General | Powers of 10 | 4 × 10³ |
| 13 | 'multiplication_abc' | Bonus | 3-Digit Multiplication | 345 × 11, 124 × 25 |
| 14 | 'powers' | Bonus | Powers (x², x³) | 65² (ends-in-5 trick) |
| 15 | 'lcm_gcd' | Bonus | LCM & GCD | GCD(24, 36) |
| 16 | 'roots' | Bonus | Square & Cube Roots | √676 or ∛216 |
| 17 | 'geometry' | Bonus | Areas & Perimeters | Squares, triangles, circles |
| 18 | 'magic_square' | Bonus | Magic Squares (3×3) | Find missing cell |
| 19 | 'divisibility' | Bonus | Divisibility & Primes | Is 4,320 divisible by 9? / Is 91 prime? |
| 20 | 'sequences' | Bonus | Sequences & Missing Terms | 3, 7, 11, … or 4, 11, ??, 25, 32 |
| 21 | 'trigonometry' | Advanced | Trigonometric Ratios | sin(30°), cos(45°), tan(60°) |
| 22 | 'quadratic_equations' | Advanced | Quadratic Equations | x² − 5x + 6 = 0 |
| 23 | 'notable_triangles' | Advanced | Notable Triangles | 30°-60°, 45°-45°, 37°-53° |
| 24 | 'logarithms' | Advanced | Mental Logarithms | log₂(32) = 5 |
🛠️ API Reference
generateQuestion(config?): GeneratedQuestion
Generates a single question with shuffled options, distractors, and metadata.
const q = engine.generateQuestion({
category: 'logarithms', // MathCategory | MathCategory[] | 'general' | 'bonus' | 'advanced' | 'all'
difficulty: 'normal', // 'easy' | 'normal' | 'hard' | 'extreme'
locale: 'en', // 'es' | 'en' | 'zh' | 'pt' (overrides engine default)
optionCount: 4, // Number of answer choices (default: 4)
includeHint: true, // Include mental math tip
includeExplanation: true, // Include step-by-step solution
includeLatex: true, // Include LaTeX string
subType: 0 // (Optional) Force specific exercise subtype
});interface GeneratedQuestion {
id: string; // Unique hash (for deduplication)
chapterId: number; // Chapter 1–24
category: MathCategory;
era: EraType; // 'general' | 'bonus' | 'advanced'
subType: number;
subTypeName: string; // Localized subtype label
locale: SupportedLocale; // Language used for this question
difficulty: DifficultyLevel;
question: string; // Question text
latex?: string; // LaTeX representation
answer: string; // Correct answer
options: string[]; // Shuffled choices (includes answer)
correctIndex: number; // Index of correct option
suggestedTimeSeconds: number; // Recommended time limit
hint?: string; // Mental math tip
explanation?: string; // Step-by-step walkthrough
}generateQuiz(config): GeneratedQuestion[]
Generates a batch of deduplicated questions. Supports weighted category distribution:
const exam = engine.generateQuiz({
count: 10,
difficulty: 'hard',
locale: 'en',
categories: ['addition', 'multiplication_ab', 'percentage'],
weights: { multiplication_ab: 6, percentage: 3, addition: 1 },
preventDuplicates: true
});Locale / i18n
// Set a global default locale for the engine instance
engine.setLocale('zh');
engine.getLocale(); // 'zh'
// Or override per-question
engine.generateQuestion({ category: 'divisibility', locale: 'pt' });
// Localized metadata
engine.getChapters('en'); // All 24 chapters in English
engine.getChapter('fractions', 'pt'); // Single chapter in Portuguese
engine.getSubTypeNames('addition', 'zh'); // Subtype names in ChineseSupported locales: 'es' (Spanish), 'en' (English), 'zh' (Simplified Chinese), 'pt' (Portuguese).
Everything is localized: chapter names, subtype labels, question text, answer options (e.g. "Yes/No" → "是/否"), hints, and explanations.
Seeded RNG
engine.setSeed(42);
const q1 = engine.generateQuestion({ category: 'multiplication_ab' });
engine.setSeed(42);
const q2 = engine.generateQuestion({ category: 'multiplication_ab' });
// q1.question === q2.question — deterministic!
engine.setSeed(null); // Back to random modeAnswer Validation
const isCorrect = engine.validateAnswer(question, userInput);
// Case-insensitive, whitespace-tolerant comparisonAdaptive Difficulty
The engine tracks streaks, accuracy, and response time to automatically adjust difficulty:
- 3 fast correct answers → Difficulty increases (
easy→normal→hard→extreme) - 2 wrong answers → Difficulty decreases (to maintain engagement)
- Slow correct answers (> 30s) → No promotion (prevents premature escalation)
const newDifficulty = engine.recordAnswerResult(true, question.id, 4500);
// Returns: 'normal' | 'hard' | etc.
engine.getAdaptiveState(); // Read current streak, accuracy, history
engine.resetAdaptiveState(); // Reset to initial stateSession Management
engine.clearSessionHistory(); // Allow previously-seen questions to appear again🏗️ Contributing
Contributions are welcome! Please open an issue or submit a pull request.
# Clone and setup
git clone https://github.com/Manz-bot/math-quiz-engine.git
cd math-quiz-engine
npm install
# Development
npm run dev # Watch mode
npm run typecheck # Type validation
npm test # Run tests
npm run build # Production build📄 License
MIT © Manz-bot
