Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:48:58 +08:00
commit df092d8cd2
127 changed files with 62057 additions and 0 deletions

View File

@@ -0,0 +1,304 @@
#!/bin/bash
# Reading Teacher - Game Generator
# Creates gamified reading challenges
set -e
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
print_success() { echo -e "${GREEN}$1${NC}"; }
print_info() { echo -e "${BLUE} $1${NC}"; }
prompt_select() {
local prompt="$1"
local var_name="$2"
shift 2
local options=("$@")
echo -e "${BLUE}${prompt}${NC}"
PS3="Select (1-${#options[@]}): "
select opt in "${options[@]}"; do
if [ -n "$opt" ]; then
eval "$var_name='$opt'"
break
fi
done
}
echo ""
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ Reading Teacher - Game Generator 🎮 ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo ""
print_info "Step 1/3: Game Type"
prompt_select "What type of game?" GAME_TYPE \
"Sight Word Speed Challenge" \
"Phonics Matching Game" \
"Word Building Adventure" \
"Reading Comprehension Quiz"
print_info "Step 2/3: Difficulty"
prompt_select "Difficulty level?" DIFFICULTY \
"Easy (Kindergarten)" \
"Medium (1st-2nd Grade)" \
"Hard (3rd+ Grade)"
print_info "Step 3/3: Output"
read -p "Game name (e.g., sight-word-game.html): " OUTPUT_FILE
OUTPUT_DIR="./reading-games"
mkdir -p "$OUTPUT_DIR"
OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE"
print_info "🎮 Generating your reading game..."
cat > "$OUTPUT_PATH" << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>📚 Reading Game Challenge</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Arial Black', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
.game-container {
background: rgba(255,255,255,0.1);
backdrop-filter: blur(10px);
padding: 40px;
border-radius: 30px;
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
max-width: 700px;
width: 90%;
text-align: center;
}
h1 { font-size: 3em; margin-bottom: 20px; }
.stats {
display: flex;
justify-content: space-around;
margin: 30px 0;
font-size: 1.5em;
}
.stat-box {
background: rgba(255,255,255,0.2);
padding: 15px 25px;
border-radius: 15px;
}
.word-display {
font-size: 5em;
margin: 40px 0;
font-weight: bold;
min-height: 120px;
display: flex;
align-items: center;
justify-content: center;
}
.answer-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 20px 0;
}
.btn {
background: rgba(255,255,255,0.3);
border: 3px solid white;
padding: 30px;
font-size: 2em;
border-radius: 15px;
cursor: pointer;
transition: all 0.2s;
font-weight: bold;
color: white;
}
.btn:hover {
background: rgba(255,255,255,0.5);
transform: scale(1.05);
}
.timer {
font-size: 3em;
color: #FFD700;
margin: 20px 0;
}
.feedback {
font-size: 2em;
min-height: 60px;
margin: 20px 0;
}
.correct { color: #4CAF50; }
.incorrect { color: #FF6347; }
.game-over {
display: none;
flex-direction: column;
gap: 20px;
}
.final-score { font-size: 5em; color: #FFD700; }
</style>
</head>
<body>
<div class="game-container">
<h1>🎯 Sight Word Challenge</h1>
<div class="stats">
<div class="stat-box">
<div>Score</div>
<div id="score">0</div>
</div>
<div class="stat-box">
<div>Streak</div>
<div id="streak">0</div>
</div>
</div>
<div id="game-area">
<div class="timer" id="timer">60</div>
<div class="word-display" id="word">the</div>
<div class="answer-buttons">
<button class="btn" onclick="checkAnswer(true)">I Know It! ✓</button>
<button class="btn" onclick="checkAnswer(false)">Skip ➡️</button>
</div>
<div class="feedback" id="feedback"></div>
</div>
<div class="game-over" id="gameOver">
<h2>🎉 Time's Up!</h2>
<div class="final-score" id="finalScore">0</div>
<p id="rating"></p>
<button class="btn" onclick="restartGame()" style="grid-column: span 2;">Play Again 🔄</button>
</div>
</div>
<script>
const sightWords = [
'the', 'of', 'and', 'a', 'to', 'in', 'is', 'you', 'that', 'it',
'he', 'was', 'for', 'on', 'are', 'as', 'with', 'his', 'they', 'I',
'at', 'be', 'this', 'have', 'from', 'or', 'one', 'had', 'by', 'words',
'but', 'not', 'what', 'all', 'were', 'we', 'when', 'your', 'can', 'said',
'there', 'use', 'an', 'each', 'which', 'she', 'do', 'how', 'their', 'if'
];
let score = 0;
let streak = 0;
let timeRemaining = 60;
let currentWord = '';
let gameActive = true;
let timerInterval;
function newWord() {
currentWord = sightWords[Math.floor(Math.random() * sightWords.length)];
document.getElementById('word').textContent = currentWord;
document.getElementById('feedback').textContent = '';
}
function checkAnswer(knows) {
if (!gameActive) return;
const feedback = document.getElementById('feedback');
if (knows) {
streak++;
const points = 10 * (1 + streak * 0.1);
score += Math.floor(points);
feedback.innerHTML = `<span class="correct">✓ Great! +${Math.floor(points)}</span>`;
if (streak % 5 === 0) {
feedback.innerHTML += ` <span style="color: #FFD700;">🔥 ${streak} Streak!</span>`;
}
} else {
streak = 0;
feedback.innerHTML = `<span class="incorrect">Keep practicing "${currentWord}"!</span>`;
}
updateStats();
setTimeout(newWord, 800);
}
function updateStats() {
document.getElementById('score').textContent = score;
document.getElementById('streak').textContent = streak;
}
function startTimer() {
timerInterval = setInterval(() => {
timeRemaining--;
document.getElementById('timer').textContent = timeRemaining;
if (timeRemaining <= 10) {
document.getElementById('timer').style.color = '#FF6347';
}
if (timeRemaining <= 0) {
endGame();
}
}, 1000);
}
function endGame() {
gameActive = false;
clearInterval(timerInterval);
document.getElementById('game-area').style.display = 'none';
document.getElementById('gameOver').style.display = 'flex';
document.getElementById('finalScore').textContent = score;
let rating;
if (score >= 300) rating = '🏆 Reading Superstar!';
else if (score >= 200) rating = '⭐ Excellent Reader!';
else if (score >= 100) rating = '👍 Great Job!';
else rating = '💪 Keep Practicing!';
document.getElementById('rating').textContent = rating;
}
function restartGame() {
score = 0;
streak = 0;
timeRemaining = 60;
gameActive = true;
document.getElementById('game-area').style.display = 'block';
document.getElementById('gameOver').style.display = 'none';
document.getElementById('timer').style.color = '#FFD700';
updateStats();
newWord();
startTimer();
}
// Keyboard controls
document.addEventListener('keydown', (e) => {
if (e.key === ' ' || e.key === 'Enter') checkAnswer(true);
if (e.key === 'ArrowRight') checkAnswer(false);
});
// Initialize
newWord();
startTimer();
</script>
</body>
</html>
EOF
echo ""
print_success "Game created: $OUTPUT_PATH"
echo ""
print_info "🎮 To play:"
echo " open $OUTPUT_PATH"
echo ""
print_info "Game features:"
echo " ✓ 60-second challenge"
echo " ✓ Sight word practice"
echo " ✓ Streak bonuses"
echo " ✓ Keyboard controls (Space/Enter = Know, Arrow = Skip)"
echo " ✓ Progress tracking"
echo ""

View File

@@ -0,0 +1,302 @@
#!/bin/bash
# Reading Teacher - Interactive Playground Generator
# Creates instant, interactive reading learning experiences
set -e
# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m'
print_success() { echo -e "${GREEN}$1${NC}"; }
print_info() { echo -e "${BLUE} $1${NC}"; }
prompt_select() {
local prompt="$1"
local var_name="$2"
shift 2
local options=("$@")
echo -e "${BLUE}${prompt}${NC}"
PS3="Select (1-${#options[@]}): "
select opt in "${options[@]}"; do
if [ -n "$opt" ]; then
eval "$var_name='$opt'"
break
fi
done
}
echo ""
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ Reading Teacher - Playground Generator 📚 ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo ""
print_info "Step 1/4: Age Group"
prompt_select "Choose age group:" AGE_GROUP \
"Toddler (Ages 1-3)" \
"Preschool (Ages 3-5)" \
"Early Elementary (Ages 5-7)" \
"Elementary (Ages 7-10)"
print_info "Step 2/4: Reading Skill"
case $AGE_GROUP in
"Toddler (Ages 1-3)")
prompt_select "Which skill?" SKILL \
"Letter Recognition" \
"Letter Sounds" \
"Alphabet Song"
;;
"Preschool (Ages 3-5)")
prompt_select "Which skill?" SKILL \
"Phonics - CVC Words" \
"Letter Matching" \
"Rhyming Words"
;;
"Early Elementary (Ages 5-7)")
prompt_select "Which skill?" SKILL \
"Sight Words" \
"Word Families" \
"Simple Sentences"
;;
"Elementary (Ages 7-10)")
prompt_select "Which skill?" SKILL \
"Reading Comprehension" \
"Vocabulary Building" \
"Story Sequencing"
;;
esac
print_info "Step 3/4: Activity Type"
prompt_select "Type of activity?" ACTIVITY_TYPE \
"Interactive Explorer" \
"Practice Game" \
"Timed Challenge"
print_info "Step 4/4: Output"
read -p "Playground name (e.g., letter-land.html): " OUTPUT_FILE
OUTPUT_DIR="./reading-playgrounds"
mkdir -p "$OUTPUT_DIR"
OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE"
print_info "📚 Generating your reading playground..."
# Generate based on skill (showing letter recognition as example)
cat > "$OUTPUT_PATH" << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>📚 Reading Playground</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Comic Sans MS', 'Chalkboard SE', cursive, sans-serif;
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.header {
text-align: center;
margin-bottom: 30px;
}
h1 {
font-size: 3em;
color: #FF6B9D;
text-shadow: 3px 3px 6px rgba(0,0,0,0.1);
}
.stars {
font-size: 2em;
background: rgba(255,255,255,0.8);
padding: 10px 30px;
border-radius: 30px;
margin-top: 10px;
}
.letter-display {
background: white;
width: 350px;
height: 350px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12em;
font-weight: bold;
color: #667eea;
box-shadow: 0 20px 60px rgba(0,0,0,0.2);
margin: 20px;
cursor: pointer;
transition: all 0.3s;
user-select: none;
}
.letter-display:hover { transform: scale(1.05); }
.letter-display:active { transform: scale(0.95); }
.controls {
display: flex;
gap: 20px;
margin: 20px;
flex-wrap: wrap;
justify-content: center;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 20px 40px;
font-size: 1.5em;
border-radius: 20px;
cursor: pointer;
transition: transform 0.2s;
font-weight: bold;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
}
.btn:hover { transform: translateY(-5px); }
.instruction {
font-size: 1.8em;
color: #333;
margin: 20px;
text-align: center;
background: rgba(255,255,255,0.9);
padding: 20px;
border-radius: 15px;
max-width: 600px;
}
.celebration {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
font-size: 8em;
animation: celebrate 1s ease forwards;
pointer-events: none;
}
@keyframes celebrate {
0% { transform: translate(-50%, -50%) scale(0) rotate(0); }
50% { transform: translate(-50%, -50%) scale(1.3) rotate(180deg); }
100% { transform: translate(-50%, -50%) scale(1) rotate(360deg); opacity: 0; }
}
</style>
</head>
<body>
<div class="header">
<h1>🌈 Letter Land Adventure!</h1>
<div class="stars">Stars: <span id="stars">0</span> ⭐</div>
</div>
<div class="letter-display" id="letterDisplay" onclick="clickLetter()">A</div>
<div class="instruction" id="instruction">
Click the letter to hear its name and sound!
</div>
<div class="controls">
<button class="btn" onclick="nextLetter()">Next Letter ➡️</button>
<button class="btn" onclick="randomLetter()">Random 🎲</button>
<button class="btn" onclick="playGame()">Practice Game 🎮</button>
</div>
<script>
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
const letterWords = {
'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephant',
'F': 'Fish', 'G': 'Goat', 'H': 'Hat', 'I': 'Ice Cream', 'J': 'Juice',
'K': 'Kite', 'L': 'Lion', 'M': 'Moon', 'N': 'Nest', 'O': 'Orange',
'P': 'Pig', 'Q': 'Queen', 'R': 'Rabbit', 'S': 'Sun', 'T': 'Tiger',
'U': 'Umbrella', 'V': 'Violin', 'W': 'Whale', 'X': 'X-ray', 'Y': 'Yellow', 'Z': 'Zebra'
};
const colors = ['#FF6B9D', '#4ECDC4', '#FFE66D', '#A8E6CF', '#FF8B94'];
let currentIndex = 0;
let stars = 0;
function updateDisplay(letter) {
const display = document.getElementById('letterDisplay');
display.textContent = letter;
display.style.color = colors[Math.floor(Math.random() * colors.length)];
}
function clickLetter() {
const letter = document.getElementById('letterDisplay').textContent;
stars++;
document.getElementById('stars').textContent = stars;
celebrate('🎉');
// Update instruction
document.getElementById('instruction').textContent =
`${letter}! ${letter} is for ${letterWords[letter]}!`;
// Speak letter (if browser supports)
if ('speechSynthesis' in window) {
const utterance = new SpeechSynthesisUtterance(
`${letter}. ${letter} is for ${letterWords[letter]}`
);
utterance.rate = 0.8;
utterance.pitch = 1.3;
speechSynthesis.speak(utterance);
}
}
function nextLetter() {
currentIndex = (currentIndex + 1) % alphabet.length;
updateDisplay(alphabet[currentIndex]);
document.getElementById('instruction').textContent = 'Click the letter!';
}
function randomLetter() {
currentIndex = Math.floor(Math.random() * alphabet.length);
updateDisplay(alphabet[currentIndex]);
celebrate('✨');
}
function playGame() {
// Simple recognition game
const target = alphabet[Math.floor(Math.random() * alphabet.length)];
document.getElementById('instruction').textContent =
`Find the letter ${target}! Click when you see it.`;
// Cycle through letters
let count = 0;
const interval = setInterval(() => {
updateDisplay(alphabet[Math.floor(Math.random() * alphabet.length)]);
count++;
if (count > 20) clearInterval(interval);
}, 800);
}
function celebrate(emoji) {
const div = document.createElement('div');
div.className = 'celebration';
div.textContent = emoji;
document.body.appendChild(div);
setTimeout(() => div.remove(), 1000);
}
// Initialize
updateDisplay(alphabet[0]);
</script>
</body>
</html>
EOF
echo ""
print_success "Playground created: $OUTPUT_PATH"
echo ""
print_info "🚀 To use:"
echo " open $OUTPUT_PATH"
echo ""
print_info "Features:"
echo " ✓ Interactive letter display"
echo " ✓ Audio pronunciation (if supported)"
echo " ✓ Star rewards"
echo " ✓ Practice game mode"
echo " ✓ Colorful, engaging design"
echo ""