Files
gh-jamesrochabrun-skills/skills/math-teacher/references/gamification.md
2025-11-29 18:48:55 +08:00

636 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gamification Reference
Game mechanics, reward systems, and engagement techniques for math learning.
## Points System
### Base Points
```javascript
const POINTS = {
// Correctness
CORRECT_FIRST_TRY: 10,
CORRECT_SECOND_TRY: 7,
CORRECT_THIRD_TRY: 5,
CORRECT_WITH_HINT: 3,
// Exploration
TRY_DIFFERENT_VALUE: 2,
DISCOVER_PATTERN: 15,
FIND_SPECIAL_CASE: 20,
// Speed
SPEED_BONUS_5SEC: 5,
SPEED_BONUS_10SEC: 3,
SPEED_BONUS_30SEC: 1,
// Completion
COMPLETE_LEVEL: 50,
COMPLETE_CHALLENGE: 100,
PERFECT_SCORE: 200,
// Daily
DAILY_LOGIN: 10,
DAILY_CHALLENGE: 25
};
```
### Multipliers
```javascript
function calculateMultiplier(state) {
let multiplier = 1.0;
// Streak multiplier
if (state.streak >= 3) multiplier += 0.5;
if (state.streak >= 5) multiplier += 0.5;
if (state.streak >= 10) multiplier += 1.0;
// Difficulty multiplier
multiplier *= {
'easy': 1.0,
'medium': 1.5,
'hard': 2.0,
'expert': 3.0
}[state.difficulty] || 1.0;
// Level multiplier
multiplier *= (1 + (state.level * 0.1));
return Math.min(multiplier, 5.0); // Cap at 5x
}
```
### Total Score Calculation
```javascript
function awardPoints(basePoints, state) {
const multiplier = calculateMultiplier(state);
const speedBonus = calculateSpeedBonus(state.timeSpent);
const total = Math.floor(basePoints * multiplier) + speedBonus;
return {
base: basePoints,
multiplier: multiplier,
speedBonus: speedBonus,
total: total,
breakdown: `${basePoints} × ${multiplier.toFixed(1)} + ${speedBonus}`
};
}
function calculateSpeedBonus(seconds) {
if (seconds < 5) return POINTS.SPEED_BONUS_5SEC;
if (seconds < 10) return POINTS.SPEED_BONUS_10SEC;
if (seconds < 30) return POINTS.SPEED_BONUS_30SEC;
return 0;
}
```
## Achievements
### Achievement Definitions
```javascript
const ACHIEVEMENTS = {
first_steps: {
id: 'first_steps',
name: '🌟 First Steps',
description: 'Complete your first problem',
condition: (stats) => stats.problemsCompleted >= 1,
points: 10,
rarity: 'common'
},
hot_streak: {
id: 'hot_streak',
name: '🔥 Hot Streak',
description: 'Get 5 correct answers in a row',
condition: (stats) => stats.currentStreak >= 5,
points: 25,
rarity: 'uncommon'
},
speed_demon: {
id: 'speed_demon',
name: '⚡ Speed Demon',
description: 'Solve 10 problems in under 5 seconds each',
condition: (stats) => stats.fastSolves >= 10,
points: 50,
rarity: 'rare'
},
perfectionist: {
id: 'perfectionist',
name: '💯 Perfectionist',
description: 'Get 100% on a challenge',
condition: (stats) => stats.perfectScores >= 1,
points: 100,
rarity: 'epic'
},
math_master: {
id: 'math_master',
name: '🏆 Math Master',
description: 'Reach 1000 total points',
condition: (stats) => stats.totalPoints >= 1000,
points: 200,
rarity: 'legendary'
},
explorer: {
id: 'explorer',
name: '🔍 Explorer',
description: 'Try 50 different values',
condition: (stats) => stats.valuesExplored >= 50,
points: 30,
rarity: 'uncommon'
},
pattern_finder: {
id: 'pattern_finder',
name: '🧩 Pattern Finder',
description: 'Discover 5 mathematical patterns',
condition: (stats) => stats.patternsFound >= 5,
points: 75,
rarity: 'rare'
},
night_owl: {
id: 'night_owl',
name: '🦉 Night Owl',
description: 'Practice after midnight',
condition: (stats) => stats.lateNightSessions >= 1,
points: 15,
rarity: 'common'
},
early_bird: {
id: 'early_bird',
name: '🐦 Early Bird',
description: 'Practice before 6 AM',
condition: (stats) => stats.earlyMorningSessions >= 1,
points: 15,
rarity: 'common'
},
week_warrior: {
id: 'week_warrior',
name: '📅 Week Warrior',
description: 'Practice 7 days in a row',
condition: (stats) => stats.dailyStreak >= 7,
points: 150,
rarity: 'epic'
}
};
```
### Achievement Checker
```javascript
function checkAchievements(stats, unlockedAchievements) {
const newAchievements = [];
for (const [id, achievement] of Object.entries(ACHIEVEMENTS)) {
if (!unlockedAchievements.includes(id)) {
if (achievement.condition(stats)) {
newAchievements.push(achievement);
unlockedAchievements.push(id);
}
}
}
return newAchievements;
}
```
### Achievement Display
```javascript
function showAchievementPopup(achievement) {
const popup = document.createElement('div');
popup.className = 'achievement-popup';
popup.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, ${getRarityColor(achievement.rarity)});
color: white;
padding: 20px 30px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
animation: slideIn 0.5s ease, pulse 0.5s ease 0.5s;
z-index: 1000;
font-weight: bold;
min-width: 250px;
`;
popup.innerHTML = `
<div style="font-size: 2em; text-align: center;">${achievement.name}</div>
<div style="margin-top: 10px; text-align: center;">${achievement.description}</div>
<div style="margin-top: 10px; text-align: center; font-size: 1.5em;">
+${achievement.points} points
</div>
`;
document.body.appendChild(popup);
// Play sound
playAchievementSound(achievement.rarity);
// Remove after 4 seconds
setTimeout(() => {
popup.style.animation = 'slideOut 0.5s ease';
setTimeout(() => popup.remove(), 500);
}, 4000);
}
function getRarityColor(rarity) {
const colors = {
common: '#909090, #606060',
uncommon: '#4CAF50, #388E3C',
rare: '#2196F3, #1565C0',
epic: '#9C27B0, #6A1B9A',
legendary: '#FFC107, #F57C00'
};
return colors[rarity] || colors.common;
}
```
## Progress Tracking
### Stats Structure
```javascript
const playerStats = {
// Basic counts
problemsAttempted: 0,
problemsCompleted: 0,
correctAnswers: 0,
incorrectAnswers: 0,
// Streaks
currentStreak: 0,
longestStreak: 0,
dailyStreak: 0,
// Performance
averageTime: 0,
fastestTime: Infinity,
fastSolves: 0,
perfectScores: 0,
// Exploration
valuesExplored: 0,
patternsFound: 0,
// Points & Level
totalPoints: 0,
level: 1,
pointsToNextLevel: 100,
// Time tracking
totalTimeSpent: 0,
sessionsCount: 0,
lastSessionDate: null,
lateNightSessions: 0,
earlyMorningSessions: 0,
// Achievements
achievementsUnlocked: [],
achievementPoints: 0
};
```
### Level System
```javascript
function calculateLevel(points) {
// Level 1: 0-100 points
// Level 2: 100-300 points
// Level 3: 300-600 points
// Formula: points_needed = 100 * level * (level + 1) / 2
let level = 1;
let pointsNeeded = 100;
let totalPointsForLevel = 0;
while (points >= totalPointsForLevel + pointsNeeded) {
totalPointsForLevel += pointsNeeded;
level++;
pointsNeeded = 100 * level;
}
return {
level: level,
currentPoints: points,
pointsInLevel: points - totalPointsForLevel,
pointsToNextLevel: pointsNeeded,
progress: (points - totalPointsForLevel) / pointsNeeded
};
}
function checkLevelUp(oldPoints, newPoints) {
const oldLevel = calculateLevel(oldPoints).level;
const newLevel = calculateLevel(newPoints).level;
if (newLevel > oldLevel) {
showLevelUpAnimation(newLevel);
return true;
}
return false;
}
```
### Progress Visualization
```javascript
function drawProgressBar(progress, canvas) {
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = 40;
// Background
ctx.fillStyle = '#E0E0E0';
ctx.fillRect(0, 0, width, height);
// Progress fill
const gradient = ctx.createLinearGradient(0, 0, width * progress, 0);
gradient.addColorStop(0, '#667eea');
gradient.addColorStop(1, '#764ba2');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width * progress, height);
// Border
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.strokeRect(0, 0, width, height);
// Text
ctx.fillStyle = '#333';
ctx.font = 'bold 18px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(`${Math.floor(progress * 100)}%`, width / 2, height / 2);
}
```
## Reward Animations
### Confetti
```javascript
function createConfetti() {
const colors = ['#FF6347', '#FFD700', '#4CAF50', '#2196F3', '#9C27B0'];
const confettiCount = 50;
const confetti = [];
for (let i = 0; i < confettiCount; i++) {
confetti.push({
x: Math.random() * window.innerWidth,
y: -20,
vx: (Math.random() - 0.5) * 5,
vy: Math.random() * 3 + 2,
color: colors[Math.floor(Math.random() * colors.length)],
size: Math.random() * 10 + 5,
rotation: Math.random() * 360,
rotationSpeed: (Math.random() - 0.5) * 10
});
}
return confetti;
}
function animateConfetti(confetti, ctx) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
let active = 0;
confetti.forEach(piece => {
piece.x += piece.vx;
piece.y += piece.vy;
piece.vy += 0.1; // Gravity
piece.rotation += piece.rotationSpeed;
if (piece.y < ctx.canvas.height) {
active++;
ctx.save();
ctx.translate(piece.x, piece.y);
ctx.rotate(piece.rotation * Math.PI / 180);
ctx.fillStyle = piece.color;
ctx.fillRect(-piece.size / 2, -piece.size / 2, piece.size, piece.size);
ctx.restore();
}
});
if (active > 0) {
requestAnimationFrame(() => animateConfetti(confetti, ctx));
}
}
function celebrateWithConfetti() {
const canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.cssText = `
position: fixed;
top: 0;
left: 0;
pointer-events: none;
z-index: 9999;
`;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const confetti = createConfetti();
animateConfetti(confetti, ctx);
setTimeout(() => canvas.remove(), 5000);
}
```
### Score Popup
```javascript
function showScorePopup(points, x, y) {
const popup = document.createElement('div');
popup.textContent = `+${points}`;
popup.style.cssText = `
position: absolute;
left: ${x}px;
top: ${y}px;
color: #FFD700;
font-size: 2em;
font-weight: bold;
animation: floatUp 1s ease-out forwards;
pointer-events: none;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
z-index: 1000;
`;
document.body.appendChild(popup);
setTimeout(() => popup.remove(), 1000);
}
// Add CSS animation
const style = document.createElement('style');
style.textContent = `
@keyframes floatUp {
from {
transform: translateY(0) scale(1);
opacity: 1;
}
to {
transform: translateY(-100px) scale(1.5);
opacity: 0;
}
}
`;
document.head.appendChild(style);
```
## Challenge Modes
### Time Attack
```javascript
class TimeAttackMode {
constructor(duration = 60) {
this.duration = duration;
this.timeRemaining = duration;
this.problemsSolved = 0;
this.totalPoints = 0;
this.isActive = false;
}
start() {
this.isActive = true;
this.timer = setInterval(() => {
this.timeRemaining--;
this.updateDisplay();
if (this.timeRemaining <= 0) {
this.end();
}
}, 1000);
}
solve(points) {
if (this.isActive) {
this.problemsSolved++;
this.totalPoints += points;
this.generateNewProblem();
}
}
end() {
this.isActive = false;
clearInterval(this.timer);
this.showResults();
}
showResults() {
const results = {
problemsSolved: this.problemsSolved,
totalPoints: this.totalPoints,
averageTime: this.duration / this.problemsSolved,
rating: this.calculateRating()
};
displayResults(results);
}
calculateRating() {
if (this.problemsSolved >= 30) return '🏆 Master';
if (this.problemsSolved >= 20) return '⭐ Expert';
if (this.problemsSolved >= 15) return '👍 Good';
if (this.problemsSolved >= 10) return '✓ Average';
return '💪 Keep Practicing';
}
}
```
### Accuracy Challenge
```javascript
class AccuracyChallenge {
constructor(problemCount = 10) {
this.problemCount = problemCount;
this.currentProblem = 0;
this.correctAnswers = 0;
this.mistakes = 0;
this.maxMistakes = 3;
}
checkAnswer(userAnswer, correctAnswer) {
if (userAnswer === correctAnswer) {
this.correctAnswers++;
this.currentProblem++;
celebrateCorrect();
if (this.currentProblem >= this.problemCount) {
this.complete();
} else {
this.nextProblem();
}
} else {
this.mistakes++;
if (this.mistakes >= this.maxMistakes) {
this.fail();
} else {
showMistakeWarning(this.maxMistakes - this.mistakes);
}
}
}
complete() {
const accuracy = (this.correctAnswers / this.problemCount) * 100;
showCompletionScreen({
success: true,
accuracy: accuracy,
perfect: accuracy === 100,
reward: this.calculateReward(accuracy)
});
}
fail() {
showCompletionScreen({
success: false,
correctAnswers: this.correctAnswers,
totalProblems: this.problemCount
});
}
calculateReward(accuracy) {
if (accuracy === 100) return 200;
if (accuracy >= 90) return 150;
if (accuracy >= 80) return 100;
if (accuracy >= 70) return 75;
return 50;
}
}
```
## Sound Effects
### Audio System
```javascript
const sounds = {
correct: 'data:audio/wav;base64,...', // Positive chime
incorrect: 'data:audio/wav;base64,...', // Gentle buzz
achievement: 'data:audio/wav;base64,...', // Fanfare
levelUp: 'data:audio/wav;base64,...', // Ascending notes
click: 'data:audio/wav;base64,...' // Click sound
};
function playSound(soundName) {
if (!sounds[soundName]) return;
const audio = new Audio(sounds[soundName]);
audio.volume = 0.3;
audio.play().catch(() => {
// Ignore if user hasn't interacted yet
});
}
```
## Summary
These gamification patterns provide:
- Comprehensive points and achievement systems
- Progressive difficulty with level systems
- Engaging reward animations
- Multiple challenge modes
- Progress tracking and visualization
- Sound effects and celebrations
Use these to make math learning addictively fun!