math-game-sdk
v3.0.1
Published
Math Game SDK v3 — utility library for building HTML math games
Readme
Math Game SDK v3 — AI Reference
QUAN TRỌNG — Namespace: SDK expose global object tên
MathGameSDK(PascalCase). KHÔNG dùngmathGameSDK,mathgameSDKhay bất kỳ biến thể nào khác. SDK v3 có 5 namespace:bridge·math·utils·geo·easeKHÔNG viết fallback logic nội bộ. Nếu SDK không load được, hiển thị lỗi rõ ràng và dừng lại. Không tự viết lại shuffle, calcScore, hay bất kỳ utility nào có sẵn trong SDK.
<script src="https://cdn.jsdelivr.net/npm/math-game-sdk@3/math-game-sdk.js"></script>bridge — Platform (bắt buộc gọi)
MathGameSDK.bridge.reportScore(correct, total) // sau mỗi câu đúng — 2 số nguyên
MathGameSDK.bridge.reportProgress(current, total) // mỗi câu mới — 2 số nguyên
MathGameSDK.bridge.reportComplete() // khi kết thúc game
MathGameSDK.bridge.onReady(callback) // callback khi platform sẵn sàng
MathGameSDK.bridge.getPlayerName() // Promise<string> — tên người chơi
MathGameSDK.bridge.saveState(key, data) // lưu state
MathGameSDK.bridge.loadState(key) // Promise<unknown> — đọc stateLỗi thường gặp cần tránh:
// ❌ SAI namespace
window.mathGameSDK.bridge.reportScore(...)
// ❌ SAI — reportProgress nhận ratio thay vì 2 số
MathGameSDK.bridge.reportProgress(score / total)
// ✅ ĐÚNG
MathGameSDK.bridge.reportScore(correct, total) // (correct, total) — 2 số nguyên
MathGameSDK.bridge.reportProgress(current, total) // (current, total) — 2 số nguyênmath — Toán học
generate(options) → MathQuestion[]
Tạo câu hỏi toán. Dùng khi cần sinh câu hỏi ngẫu nhiên.
const qs = MathGameSDK.math.generate({ type: 'addition', difficulty: 1, count: 10 })
// qs[0] = { type, prompt: "3 + 4 = ?", answer: 7, difficulty: 1 }type: 'addition'|'subtraction'|'multiplication'|'division'|'comparison'|'missing-number'|'fractions'|'word-problem'
difficulty: 1 (dễ) | 2 (trung bình) | 3 (khó)
checkAnswer(question, userAnswer) → { correct, correctAnswer }
MathGameSDK.math.checkAnswer(qs[0], 7) // { correct: true, correctAnswer: 7 }combination(n, k) → number
MathGameSDK.math.combination(5, 2) // → 10 C(5,2)permutation(n, k) → number
MathGameSDK.math.permutation(5, 2) // → 20 P(5,2)getAllCombinations(n, k) → number[][]
Trả về mảng các tổ hợp dưới dạng index 0-based (không phải giá trị phần tử).
Số lượng phần tử = combination(n, k).
MathGameSDK.math.getAllCombinations(4, 2)
// → [[0,1],[0,2],[0,3],[1,2],[1,3],[2,3]]calculateStars(score, maxScore, thresholds?) → 1 | 2 | 3
MathGameSDK.math.calculateStars(8, 10) // → 3 (80% ≥ 0.8)
MathGameSDK.math.calculateStars(6, 10) // → 2 (60% ∈ [0.5, 0.8))
MathGameSDK.math.calculateStars(3, 10) // → 1 (30% < 0.5)
MathGameSDK.math.calculateStars(8, 10, [0.6, 0.9]) // → 2 (custom)thresholds: mảng 2 phần tử [low, high], giá trị 0–1. Mặc định [0.5, 0.8].
distance(x1, y1, x2, y2) → number
MathGameSDK.math.distance(0, 0, 3, 4) // → 5 (Euclidean)degToRad(degrees) → number
MathGameSDK.math.degToRad(180) // → Math.PIradToDeg(radians) → number
MathGameSDK.math.radToDeg(Math.PI) // → 180utils — Tiện ích
shuffle(array) → array
Fisher-Yates, phân phối đều. Mutates và trả về array.
MathGameSDK.utils.shuffle([1, 2, 3, 4]) // → [3, 1, 4, 2]createScoreTracker(maxScore?) → tracker
const s = MathGameSDK.utils.createScoreTracker(10)
s.add() // +10 điểm
s.subtract() // -5 điểm (không xuống dưới 0)
s.get() // điểm hiện tại
s.percentage() // 0-100createTimer(seconds) → timer
const t = MathGameSDK.utils.createTimer(60)
t.onTick(remaining => updateUI(remaining))
t.onEnd(() => showResult())
t.start() // t.pause() / t.stop()createGrid(rows, cols, defaultValue?) → grid
Mutable 2D grid. isFull() = không có ô nào là null.
const grid = MathGameSDK.utils.createGrid(4, 4, null)
grid.set(0, 0, 'X')
grid.get(0, 0) // 'X'
grid.fill(null) // reset
grid.count() // số ô !== null
grid.isFull() // true khi không còn ô null
grid.toArray() // 2D array
grid.forEach((val, r, c) => console.log(r, c, val))clamp(value, min, max) → number
MathGameSDK.utils.clamp(15, 0, 10) // → 10
MathGameSDK.utils.clamp(-3, 0, 10) // → 0lerp(a, b, t) → number
Linear interpolation. t ∈ [0, 1].
MathGameSDK.utils.lerp(0, 100, 0.3) // → 30Dùng với easing: lerp(start, end, ease.quadOut(progress))
wrap(value, min, max) → number
Cyclical — giá trị vượt max sẽ quay về min.
MathGameSDK.utils.wrap(11, 0, 10) // → 1
MathGameSDK.utils.wrap(-1, 0, 10) // → 9randomInt(min, max) → number
Inclusive — bao gồm cả min và max.
MathGameSDK.utils.randomInt(1, 6) // → 4 (xúc xắc)randomPick(array) → T
MathGameSDK.utils.randomPick(['A', 'B', 'C']) // → 'B'percent(value, min, max) → number
Vị trí của value trong [min, max] dưới dạng 0–1. Trả về 0 khi min === max.
MathGameSDK.utils.percent(7, 0, 10) // → 0.7
MathGameSDK.utils.percent(150, 0, 200) // → 0.75geo — Hình học (cho game Venn/circle)
isPointInCircle(point, circle) → boolean
MathGameSDK.geo.isPointInCircle({ x: 100, y: 100 }, { x: 150, y: 150, radius: 80 })
// → truedetermineZone(point, circleA, circleB) → 'A' | 'B' | 'AB' | 'outside'
MathGameSDK.geo.determineZone({ x: 200, y: 200 }, circleA, circleB)
// → 'AB' (điểm nằm trong cả 2 vùng)ease — Animation easing
Tất cả nhận t ∈ [0, 1] và trả về số (thường 0–1). Dùng kết hợp với utils.lerp.
const x = MathGameSDK.utils.lerp(startX, endX, MathGameSDK.ease.quadOut(progress))linear(t) → t
MathGameSDK.ease.linear(0.5) // → 0.5 (tốc độ đều)quadIn(t) → t²
Tăng tốc từ đầu.
MathGameSDK.ease.quadIn(0.5) // → 0.25quadOut(t) → t(2-t)
Giảm tốc về cuối — dùng phổ biến nhất cho slide/fade.
MathGameSDK.ease.quadOut(0.5) // → 0.75bounceOut(t) → number
Nảy cuối animation, settle về 1.
MathGameSDK.ease.bounceOut(1.0) // → 1.0
MathGameSDK.ease.bounceOut(0.8) // → ~0.97 (đang nảy)elasticOut(t) → number
Spring — vượt quá điểm đích rồi quay về. Overshoot tối đa ~1.03.
MathGameSDK.ease.elasticOut(0.8) // → ~1.03
MathGameSDK.ease.elasticOut(1.0) // → 1.0Minimal game template
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"></head>
<body>
<script src="https://cdn.jsdelivr.net/npm/math-game-sdk@3/math-game-sdk.js"></script>
<script>
MathGameSDK.bridge.onReady(() => {
const questions = MathGameSDK.math.generate({ type: 'addition', difficulty: 1, count: 5 })
let current = 0
function showQuestion() {
MathGameSDK.bridge.reportProgress(current + 1, questions.length)
document.getElementById('q').textContent = questions[current].prompt
}
document.getElementById('submit').addEventListener('click', () => {
const userAnswer = Number(document.getElementById('answer').value)
const result = MathGameSDK.math.checkAnswer(questions[current], userAnswer)
if (result.correct) {
current++
MathGameSDK.bridge.reportScore(current, questions.length)
if (current === questions.length) {
MathGameSDK.bridge.reportComplete()
} else {
showQuestion()
}
}
})
showQuestion()
})
</script>
<div id="q"></div>
<input id="answer" type="number">
<button id="submit">Trả lời</button>
</body>
</html>Chỉ trả về 1 file HTML duy nhất.
