Files
anglina-vibecodin/2.html
2026-04-01 12:23:43 +02:00

1068 lines
31 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TechLex — AI & Tech Vocabulary Game</title>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<style>
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #0a0a0f;
--card: #12121a;
--border: #1e1e2e;
--cyan: #00f0ff;
--purple: #b44aff;
--pink: #ff2d7b;
--green: #00ff88;
--yellow: #ffd600;
--text: #e0e0e8;
--text-dim: #6b6b80;
--glow-cyan: 0 0 20px rgba(0, 240, 255, 0.3);
--glow-purple: 0 0 20px rgba(180, 74, 255, 0.3);
}
body {
font-family: 'Space Grotesk', sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
overflow-x: hidden;
background-image:
radial-gradient(ellipse at 20% 50%, rgba(0, 240, 255, 0.03) 0%, transparent 50%),
radial-gradient(ellipse at 80% 50%, rgba(180, 74, 255, 0.03) 0%, transparent 50%);
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
min-height: 100vh;
}
.screen {
display: none;
animation: fadeIn 0.4s ease;
}
.screen.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.02); }
}
@keyframes glow {
0%, 100% { box-shadow: 0 0 5px rgba(0, 240, 255, 0.2); }
50% { box-shadow: 0 0 20px rgba(0, 240, 255, 0.4), 0 0 40px rgba(0, 240, 255, 0.1); }
}
@keyframes slideIn {
from { opacity: 0; transform: translateX(-20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-8px); }
40% { transform: translateX(8px); }
60% { transform: translateX(-4px); }
80% { transform: translateX(4px); }
}
@keyframes success {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* Header */
.header {
text-align: center;
padding: 40px 0 30px;
}
.logo {
font-family: 'JetBrains Mono', monospace;
font-size: 3rem;
font-weight: 700;
background: linear-gradient(135deg, var(--cyan), var(--purple));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: 4px;
}
.tagline {
color: var(--text-dim);
font-size: 1rem;
margin-top: 8px;
letter-spacing: 2px;
}
/* Cards */
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 30px;
margin-bottom: 20px;
transition: all 0.3s ease;
}
.card:hover {
border-color: rgba(0, 240, 255, 0.2);
}
/* Buttons */
.btn {
font-family: 'Space Grotesk', sans-serif;
font-size: 1rem;
font-weight: 600;
padding: 14px 28px;
border: none;
border-radius: 12px;
cursor: pointer;
transition: all 0.2s ease;
text-transform: uppercase;
letter-spacing: 1px;
}
.btn-primary {
background: linear-gradient(135deg, var(--cyan), var(--purple));
color: #000;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: var(--glow-cyan);
}
.btn-secondary {
background: transparent;
border: 2px solid var(--purple);
color: var(--purple);
}
.btn-secondary:hover {
background: rgba(180, 74, 255, 0.1);
transform: translateY(-2px);
}
.btn-small {
padding: 10px 20px;
font-size: 0.85rem;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none !important;
}
/* Mode Selection */
.mode-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
margin-top: 30px;
}
.mode-card {
background: var(--card);
border: 2px solid var(--border);
border-radius: 20px;
padding: 35px 30px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.mode-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--cyan), var(--purple));
opacity: 0;
transition: opacity 0.3s ease;
}
.mode-card:hover {
border-color: var(--cyan);
transform: translateY(-4px);
box-shadow: var(--glow-cyan);
}
.mode-card:hover::before {
opacity: 1;
}
.mode-icon {
font-size: 3rem;
margin-bottom: 15px;
}
.mode-title {
font-size: 1.4rem;
font-weight: 700;
margin-bottom: 10px;
color: var(--cyan);
}
.mode-desc {
color: var(--text-dim);
font-size: 0.95rem;
line-height: 1.5;
}
/* Game Area */
.game-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
flex-wrap: wrap;
gap: 15px;
}
.game-title {
font-size: 1.5rem;
font-weight: 700;
color: var(--cyan);
}
.game-stats {
display: flex;
gap: 20px;
font-family: 'JetBrains Mono', monospace;
}
.stat {
text-align: center;
}
.stat-value {
font-size: 1.5rem;
font-weight: 700;
color: var(--purple);
}
.stat-label {
font-size: 0.75rem;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 1px;
}
/* Scramble */
.scramble-word {
font-family: 'JetBrains Mono', monospace;
font-size: 2.5rem;
font-weight: 700;
text-align: center;
padding: 30px;
background: linear-gradient(135deg, rgba(0, 240, 255, 0.05), rgba(180, 74, 255, 0.05));
border: 2px dashed var(--border);
border-radius: 16px;
margin: 20px 0;
letter-spacing: 8px;
color: var(--cyan);
word-break: break-word;
}
.hint-text {
text-align: center;
color: var(--text-dim);
font-size: 0.95rem;
margin-bottom: 20px;
font-style: italic;
}
.input-group {
display: flex;
gap: 12px;
margin-top: 20px;
}
.input-group input {
flex: 1;
font-family: 'JetBrains Mono', monospace;
font-size: 1.2rem;
padding: 14px 20px;
background: var(--bg);
border: 2px solid var(--border);
border-radius: 12px;
color: var(--text);
outline: none;
transition: border-color 0.2s ease;
}
.input-group input:focus {
border-color: var(--cyan);
}
.input-group input::placeholder {
color: var(--text-dim);
}
/* Definition Match */
.definitions-grid {
display: grid;
gap: 12px;
margin-top: 20px;
}
.def-option {
background: var(--bg);
border: 2px solid var(--border);
border-radius: 12px;
padding: 18px 20px;
cursor: pointer;
transition: all 0.2s ease;
text-align: left;
font-size: 1rem;
color: var(--text);
font-family: 'Space Grotesk', sans-serif;
line-height: 1.5;
}
.def-option:hover:not(:disabled) {
border-color: var(--cyan);
background: rgba(0, 240, 255, 0.05);
}
.def-option.correct {
border-color: var(--green);
background: rgba(0, 255, 136, 0.1);
animation: success 0.4s ease;
}
.def-option.wrong {
border-color: var(--pink);
background: rgba(255, 45, 123, 0.1);
animation: shake 0.4s ease;
}
.def-option:disabled {
cursor: not-allowed;
opacity: 0.7;
}
.term-display {
text-align: center;
font-size: 1.8rem;
font-weight: 700;
color: var(--purple);
margin: 20px 0;
padding: 20px;
background: linear-gradient(135deg, rgba(180, 74, 255, 0.1), rgba(0, 240, 255, 0.05));
border-radius: 16px;
border: 1px solid rgba(180, 74, 255, 0.2);
}
/* Progress Bar */
.progress-bar {
height: 6px;
background: var(--border);
border-radius: 3px;
margin-bottom: 25px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--cyan), var(--purple));
border-radius: 3px;
transition: width 0.3s ease;
}
/* Results */
.results-card {
text-align: center;
padding: 40px;
}
.score-display {
font-family: 'JetBrains Mono', monospace;
font-size: 4rem;
font-weight: 700;
background: linear-gradient(135deg, var(--cyan), var(--purple));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin: 20px 0;
}
.score-label {
color: var(--text-dim);
font-size: 1.1rem;
text-transform: uppercase;
letter-spacing: 2px;
}
.high-score {
color: var(--yellow);
font-size: 1rem;
margin-top: 10px;
}
.results-actions {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
flex-wrap: wrap;
}
/* Feedback */
.feedback {
text-align: center;
padding: 12px;
border-radius: 10px;
margin-top: 15px;
font-weight: 600;
animation: slideIn 0.3s ease;
}
.feedback.correct {
background: rgba(0, 255, 136, 0.1);
color: var(--green);
border: 1px solid rgba(0, 255, 136, 0.2);
}
.feedback.wrong {
background: rgba(255, 45, 123, 0.1);
color: var(--pink);
border: 1px solid rgba(255, 45, 123, 0.2);
}
/* Difficulty Badge */
.difficulty-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 10px;
}
.difficulty-badge.easy {
background: rgba(0, 255, 136, 0.1);
color: var(--green);
border: 1px solid rgba(0, 255, 136, 0.2);
}
.difficulty-badge.medium {
background: rgba(255, 214, 0, 0.1);
color: var(--yellow);
border: 1px solid rgba(255, 214, 0, 0.2);
}
.difficulty-badge.hard {
background: rgba(255, 45, 123, 0.1);
color: var(--pink);
border: 1px solid rgba(255, 45, 123, 0.2);
}
/* Responsive */
@media (max-width: 600px) {
.logo { font-size: 2rem; }
.scramble-word { font-size: 1.5rem; letter-spacing: 4px; }
.term-display { font-size: 1.3rem; }
.score-display { font-size: 3rem; }
.game-stats { gap: 15px; }
.input-group { flex-direction: column; }
.mode-grid { grid-template-columns: 1fr; }
}
/* Circuit pattern decoration */
.circuit-bg {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
z-index: -1;
opacity: 0.03;
background-image:
linear-gradient(90deg, var(--cyan) 1px, transparent 1px),
linear-gradient(var(--cyan) 1px, transparent 1px);
background-size: 50px 50px;
}
/* Timer bar */
.timer-bar {
height: 4px;
background: var(--border);
border-radius: 2px;
margin-top: 15px;
overflow: hidden;
}
.timer-fill {
height: 100%;
background: linear-gradient(90deg, var(--green), var(--yellow), var(--pink));
border-radius: 2px;
transition: width 0.1s linear;
}
</style>
</head>
<body>
<div class="circuit-bg"></div>
<div class="container">
<!-- MENU SCREEN -->
<div id="menu-screen" class="screen active">
<div class="header">
<div class="logo">TECHLEX</div>
<div class="tagline">Master AI & Tech Vocabulary</div>
</div>
<div class="mode-grid">
<div class="mode-card" onclick="startScramble()">
<div class="mode-icon">&#x1F500;</div>
<div class="mode-title">Word Scramble</div>
<div class="mode-desc">Unscramble tech terms before time runs out. Use hints wisely!</div>
</div>
<div class="mode-card" onclick="startDefinitions()">
<div class="mode-icon">&#x1F4DA;</div>
<div class="mode-title">Definition Match</div>
<div class="mode-desc">Match the correct definition to each tech term. 10 rounds!</div>
</div>
</div>
<div class="card" style="margin-top: 30px; text-align: center;">
<div style="color: var(--text-dim); font-size: 0.9rem;">
<strong style="color: var(--cyan);">High Scores</strong>
</div>
<div style="display: flex; justify-content: center; gap: 40px; margin-top: 15px; font-family: 'JetBrains Mono', monospace;">
<div>
<div style="color: var(--text-dim); font-size: 0.75rem;">SCRAMBLE</div>
<div id="menu-high-scramble" style="font-size: 1.5rem; color: var(--purple);">0</div>
</div>
<div>
<div style="color: var(--text-dim); font-size: 0.75rem;">DEFINITIONS</div>
<div id="menu-high-def" style="font-size: 1.5rem; color: var(--purple);">0</div>
</div>
</div>
</div>
</div>
<!-- SCRAMBLE SCREEN -->
<div id="scramble-screen" class="screen">
<div class="game-header">
<button class="btn btn-secondary btn-small" onclick="showMenu()">&#x2190; Menu</button>
<div class="game-title">Word Scramble</div>
<div class="game-stats">
<div class="stat">
<div id="scramble-score" class="stat-value">0</div>
<div class="stat-label">Score</div>
</div>
<div class="stat">
<div id="scramble-round" class="stat-value">1/10</div>
<div class="stat-label">Round</div>
</div>
</div>
</div>
<div class="progress-bar">
<div id="scramble-progress" class="progress-fill" style="width: 0%"></div>
</div>
<div class="card">
<div id="scramble-difficulty" class="difficulty-badge easy">Easy</div>
<div id="scramble-word" class="scramble-word">LOADING</div>
<div id="scramble-hint" class="hint-text">Hint will appear here</div>
<div class="timer-bar">
<div id="scramble-timer" class="timer-fill" style="width: 100%"></div>
</div>
<div class="input-group">
<input type="text" id="scramble-input" placeholder="Type your answer..." autocomplete="off" onkeydown="if(event.key==='Enter')checkScramble()">
<button class="btn btn-primary" onclick="checkScramble()">Submit</button>
</div>
<div style="display: flex; gap: 10px; margin-top: 12px; justify-content: center;">
<button class="btn btn-secondary btn-small" onclick="useHint()">Hint (-5 pts)</button>
<button class="btn btn-secondary btn-small" onclick="skipScramble()">Skip</button>
</div>
<div id="scramble-feedback"></div>
</div>
</div>
<!-- DEFINITIONS SCREEN -->
<div id="definitions-screen" class="screen">
<div class="game-header">
<button class="btn btn-secondary btn-small" onclick="showMenu()">&#x2190; Menu</button>
<div class="game-title">Definition Match</div>
<div class="game-stats">
<div class="stat">
<div id="def-score" class="stat-value">0</div>
<div class="stat-label">Score</div>
</div>
<div class="stat">
<div id="def-round" class="stat-value">1/10</div>
<div class="stat-label">Round</div>
</div>
</div>
</div>
<div class="progress-bar">
<div id="def-progress" class="progress-fill" style="width: 0%"></div>
</div>
<div class="card">
<div style="text-align: center; color: var(--text-dim); margin-bottom: 10px;">What does this term mean?</div>
<div id="def-term" class="term-display">TERM</div>
<div id="def-options" class="definitions-grid"></div>
<div id="def-feedback"></div>
</div>
</div>
<!-- RESULTS SCREEN -->
<div id="results-screen" class="screen">
<div class="card results-card">
<div class="score-label" id="results-mode">GAME OVER</div>
<div id="results-score" class="score-display">0</div>
<div id="results-high" class="high-score"></div>
<div id="results-details" style="color: var(--text-dim); margin-top: 15px;"></div>
<div class="results-actions">
<button class="btn btn-primary" id="results-replay" onclick="replayGame()">Play Again</button>
<button class="btn btn-secondary" onclick="showMenu()">Main Menu</button>
</div>
</div>
</div>
</div>
<script>
// WORD BANK
const wordBank = [
{ term: "ALGORITHM", hint: "Step-by-step procedure for calculations", difficulty: "easy" },
{ term: "SENSOR", hint: "Device that detects changes in environment", difficulty: "easy" },
{ term: "DRONE", hint: "Unmanned aerial vehicle", difficulty: "easy" },
{ term: "ROBOT", hint: "Programmable machine that carries out tasks", difficulty: "easy" },
{ term: "CLOUD", hint: "Remote servers for storing data over the internet", difficulty: "easy" },
{ term: "DATA", hint: "Facts and statistics collected for analysis", difficulty: "easy" },
{ term: "CODE", hint: "Instructions written for computers to execute", difficulty: "easy" },
{ term: "BIAS", hint: "Systematic error in AI decision making", difficulty: "easy" },
{ term: "NODE", hint: "Connection point in a network or neural structure", difficulty: "easy" },
{ term: "CHIP", hint: "Small electronic circuit that processes information", difficulty: "easy" },
{ term: "AUTONOMOUS", hint: "Self-governing, operating without human control", difficulty: "medium" },
{ term: "NEURAL", hint: "Relating to nerve cells or brain-like networks", difficulty: "medium" },
{ term: "CYBER", hint: "Prefix relating to computers and information technology", difficulty: "medium" },
{ term: "VIRTUAL", hint: "Simulated environment created by software", difficulty: "medium" },
{ term: "DIGITAL", hint: "Using discrete values, typically binary", difficulty: "medium" },
{ term: "NETWORK", hint: "Interconnected group of computers or people", difficulty: "medium" },
{ term: "BINARY", hint: "Number system using only 0 and 1", difficulty: "medium" },
{ term: "PYTHON", hint: "Popular programming language named after a comedy group", difficulty: "medium" },
{ term: "SERVER", hint: "Computer that provides data to other computers", difficulty: "medium" },
{ term: "ROUTER", hint: "Device that forwards data between networks", difficulty: "medium" },
{ term: "ACTUATOR", hint: "Component that moves or controls a mechanism", difficulty: "medium" },
{ term: "QUANTUM", hint: "Smallest discrete unit of a phenomenon", difficulty: "medium" },
{ term: "BLOCKCHAIN", hint: "Distributed ledger technology behind cryptocurrencies", difficulty: "hard" },
{ term: "CYBERSECURITY", hint: "Protection of systems from digital attacks", difficulty: "hard" },
{ term: "MACHINE LEARNING", hint: "AI that improves through experience without explicit programming", difficulty: "hard" },
{ term: "DEEP LEARNING", hint: "Neural networks with many layers for complex pattern recognition", difficulty: "hard" },
{ term: "COMPUTER VISION", hint: "AI field enabling machines to interpret visual information", difficulty: "hard" },
{ term: "NATURAL LANGUAGE", hint: "Human communication as used in AI processing", difficulty: "hard" },
{ term: "AUGMENTED REALITY", hint: "Technology overlaying digital info on the real world", difficulty: "hard" },
{ term: "INTERNET OF THINGS", hint: "Network of connected physical devices with sensors", difficulty: "hard" },
{ term: "EXOSKELETON", hint: "Wearable robotic device that enhances human strength", difficulty: "hard" },
{ term: "BIOMETRIC", hint: "Authentication using unique physical characteristics", difficulty: "hard" },
{ term: "NANOTECHNOLOGY", hint: "Engineering at the atomic or molecular scale", difficulty: "hard" },
{ term: "AUTOMATION", hint: "Using technology to perform tasks with minimal human input", difficulty: "hard" },
{ term: "ROBOTICS", hint: "Branch of technology dealing with robot design and operation", difficulty: "hard" }
];
// AUDIO ENGINE
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function playSound(type) {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.connect(gain);
gain.connect(audioCtx.destination);
switch(type) {
case 'correct':
osc.frequency.setValueAtTime(523.25, audioCtx.currentTime);
osc.frequency.setValueAtTime(659.25, audioCtx.currentTime + 0.1);
osc.frequency.setValueAtTime(783.99, audioCtx.currentTime + 0.2);
gain.gain.setValueAtTime(0.15, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.4);
osc.start(audioCtx.currentTime);
osc.stop(audioCtx.currentTime + 0.4);
break;
case 'wrong':
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(200, audioCtx.currentTime);
osc.frequency.setValueAtTime(150, audioCtx.currentTime + 0.15);
gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.3);
osc.start(audioCtx.currentTime);
osc.stop(audioCtx.currentTime + 0.3);
break;
case 'click':
osc.frequency.setValueAtTime(800, audioCtx.currentTime);
gain.gain.setValueAtTime(0.08, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.05);
osc.start(audioCtx.currentTime);
osc.stop(audioCtx.currentTime + 0.05);
break;
case 'hint':
osc.type = 'sine';
osc.frequency.setValueAtTime(400, audioCtx.currentTime);
osc.frequency.setValueAtTime(600, audioCtx.currentTime + 0.1);
gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.2);
osc.start(audioCtx.currentTime);
osc.stop(audioCtx.currentTime + 0.2);
break;
case 'win':
[523.25, 587.33, 659.25, 783.99, 880, 1046.5].forEach((freq, i) => {
const o = audioCtx.createOscillator();
const g = audioCtx.createGain();
o.connect(g);
g.connect(audioCtx.destination);
o.frequency.setValueAtTime(freq, audioCtx.currentTime + i * 0.1);
g.gain.setValueAtTime(0.12, audioCtx.currentTime + i * 0.1);
g.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + i * 0.1 + 0.3);
o.start(audioCtx.currentTime + i * 0.1);
o.stop(audioCtx.currentTime + i * 0.1 + 0.3);
});
break;
}
}
// UTILITIES
function shuffle(arr) {
const a = [...arr];
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
function scrambleWord(word) {
const letters = word.replace(/ /g, '').split('');
let scrambled;
do {
scrambled = shuffle(letters);
} while (scrambled.join('') === word.replace(/ /g, '') && word.replace(/ /g, '').length > 1);
// Insert spaces back for multi-word terms
const cleanWord = word.replace(/ /g, '');
let result = '';
let spaceIdx = word.indexOf(' ');
let letterIdx = 0;
if (spaceIdx === -1) return scrambled.join('');
for (let i = 0; i < word.length; i++) {
if (word[i] === ' ') {
result += ' ';
} else {
result += scrambled[letterIdx++];
}
}
return result;
}
function getHighScore(mode) {
return parseInt(localStorage.getItem(`techlex_${mode}`) || '0');
}
function setHighScore(mode, score) {
const current = getHighScore(mode);
if (score > current) {
localStorage.setItem(`techlex_${mode}`, score);
return true;
}
return false;
}
// SCREEN MANAGEMENT
function showScreen(id) {
document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
document.getElementById(id).classList.add('active');
playSound('click');
}
function showMenu() {
if (scrambleTimer) clearInterval(scrambleTimer);
updateMenuScores();
showScreen('menu-screen');
}
function updateMenuScores() {
document.getElementById('menu-high-scramble').textContent = getHighScore('scramble');
document.getElementById('menu-high-def').textContent = getHighScore('definitions');
}
// SCRAMBLE GAME
let scrambleState = {
words: [],
current: 0,
score: 0,
correct: 0,
timer: null,
timeLeft: 100,
hintUsed: false
};
function startScramble() {
const easy = wordBank.filter(w => w.difficulty === 'easy');
const medium = wordBank.filter(w => w.difficulty === 'medium');
const hard = wordBank.filter(w => w.difficulty === 'hard');
scrambleState.words = shuffle([
...shuffle(easy).slice(0, 3),
...shuffle(medium).slice(0, 4),
...shuffle(hard).slice(0, 3)
]);
scrambleState.current = 0;
scrambleState.score = 0;
scrambleState.correct = 0;
scrambleState.hintUsed = false;
showScreen('scramble-screen');
loadScrambleWord();
}
function loadScrambleWord() {
if (scrambleState.current >= scrambleState.words.length) {
endScramble();
return;
}
const word = scrambleState.words[scrambleState.current];
scrambleState.timeLeft = 100;
scrambleState.hintUsed = false;
document.getElementById('scramble-word').textContent = scrambleWord(word.term);
document.getElementById('scramble-hint').textContent = 'Press Hint for a clue (-5 points)';
document.getElementById('scramble-score').textContent = scrambleState.score;
document.getElementById('scramble-round').textContent = `${scrambleState.current + 1}/${scrambleState.words.length}`;
document.getElementById('scramble-progress').style.width = `${(scrambleState.current / scrambleState.words.length) * 100}%`;
document.getElementById('scramble-input').value = '';
document.getElementById('scramble-feedback').innerHTML = '';
const diffBadge = document.getElementById('scramble-difficulty');
diffBadge.textContent = word.difficulty;
diffBadge.className = `difficulty-badge ${word.difficulty === 'easy' ? 'easy' : word.difficulty === 'medium' ? 'medium' : 'hard'}`;
startScrambleTimer();
document.getElementById('scramble-input').focus();
}
function startScrambleTimer() {
if (scrambleTimer) clearInterval(scrambleTimer);
scrambleState.timeLeft = 100;
document.getElementById('scramble-timer').style.width = '100%';
scrambleTimer = setInterval(() => {
scrambleState.timeLeft -= 0.5;
document.getElementById('scramble-timer').style.width = `${scrambleState.timeLeft}%`;
if (scrambleState.timeLeft <= 0) {
clearInterval(scrambleTimer);
scrambleTimeout();
}
}, 100);
}
function scrambleTimeout() {
const word = scrambleState.words[scrambleState.current];
playSound('wrong');
document.getElementById('scramble-feedback').innerHTML = `<div class="feedback wrong">Time's up! The answer was: ${word.term}</div>`;
scrambleState.current++;
setTimeout(loadScrambleWord, 2000);
}
function checkScramble() {
const input = document.getElementById('scramble-input').value.trim().toUpperCase();
if (!input) return;
const word = scrambleState.words[scrambleState.current];
const feedback = document.getElementById('scramble-feedback');
if (input === word.term) {
clearInterval(scrambleTimer);
playSound('correct');
let points = 10;
if (word.difficulty === 'medium') points = 15;
if (word.difficulty === 'hard') points = 20;
if (scrambleState.hintUsed) points -= 5;
if (points < 1) points = 1;
scrambleState.score += points;
scrambleState.correct++;
document.getElementById('scramble-score').textContent = scrambleState.score;
feedback.innerHTML = `<div class="feedback correct">Correct! +${points} points</div>`;
scrambleState.current++;
setTimeout(loadScrambleWord, 1200);
} else {
playSound('wrong');
feedback.innerHTML = `<div class="feedback wrong">Try again!</div>`;
document.getElementById('scramble-input').value = '';
document.getElementById('scramble-input').focus();
}
}
function useHint() {
if (scrambleState.hintUsed) return;
scrambleState.hintUsed = true;
playSound('hint');
const word = scrambleState.words[scrambleState.current];
const firstLetter = word.term[0];
const length = word.term.length;
document.getElementById('scramble-hint').textContent = `Starts with "${firstLetter}" — ${length} characters`;
}
function skipScramble() {
clearInterval(scrambleTimer);
const word = scrambleState.words[scrambleState.current];
playSound('click');
document.getElementById('scramble-feedback').innerHTML = `<div class="feedback wrong">Skipped! Answer: ${word.term}</div>`;
scrambleState.current++;
setTimeout(loadScrambleWord, 1500);
}
function endScramble() {
clearInterval(scrambleTimer);
const isNewHigh = setHighScore('scramble', scrambleState.score);
playSound('win');
document.getElementById('results-mode').textContent = 'WORD SCRAMBLE COMPLETE';
document.getElementById('results-score').textContent = scrambleState.score;
document.getElementById('results-high').textContent = isNewHigh ? '🏆 New High Score!' : `High Score: ${getHighScore('scramble')}`;
document.getElementById('results-details').textContent = `${scrambleState.correct}/${scrambleState.words.length} correct`;
document.getElementById('results-replay').onclick = startScramble;
showScreen('results-screen');
}
// DEFINITIONS GAME
let defState = {
questions: [],
current: 0,
score: 0,
correct: 0,
total: 10
};
function startDefinitions() {
const shuffled = shuffle(wordBank);
defState.questions = shuffled.slice(0, defState.total).map(word => {
const wrongDefs = shuffle(wordBank.filter(w => w.term !== word.term)).slice(0, 3).map(w => w.hint);
const options = shuffle([word.hint, ...wrongDefs]);
return {
term: word.term,
correctHint: word.hint,
options: options,
difficulty: word.difficulty
};
});
defState.current = 0;
defState.score = 0;
defState.correct = 0;
showScreen('definitions-screen');
loadDefQuestion();
}
function loadDefQuestion() {
if (defState.current >= defState.questions.length) {
endDefinitions();
return;
}
const q = defState.questions[defState.current];
document.getElementById('def-term').textContent = q.term;
document.getElementById('def-score').textContent = defState.score;
document.getElementById('def-round').textContent = `${defState.current + 1}/${defState.total}`;
document.getElementById('def-progress').style.width = `${(defState.current / defState.total) * 100}%`;
document.getElementById('def-feedback').innerHTML = '';
const optionsContainer = document.getElementById('def-options');
optionsContainer.innerHTML = '';
q.options.forEach((opt, idx) => {
const btn = document.createElement('button');
btn.className = 'def-option';
btn.textContent = opt;
btn.onclick = () => checkDefAnswer(idx, btn);
optionsContainer.appendChild(btn);
});
}
function checkDefAnswer(idx, btn) {
const q = defState.questions[defState.current];
const buttons = document.querySelectorAll('.def-option');
const feedback = document.getElementById('def-feedback');
buttons.forEach(b => b.disabled = true);
if (q.options[idx] === q.correctHint) {
playSound('correct');
btn.classList.add('correct');
let points = 10;
if (q.difficulty === 'medium') points = 15;
if (q.difficulty === 'hard') points = 20;
defState.score += points;
defState.correct++;
document.getElementById('def-score').textContent = defState.score;
feedback.innerHTML = `<div class="feedback correct">Correct! +${points} points</div>`;
} else {
playSound('wrong');
btn.classList.add('wrong');
buttons.forEach(b => {
if (b.textContent === q.correctHint) b.classList.add('correct');
});
feedback.innerHTML = `<div class="feedback wrong">Wrong! The correct answer is highlighted.</div>`;
}
defState.current++;
setTimeout(loadDefQuestion, 1800);
}
function endDefinitions() {
const isNewHigh = setHighScore('definitions', defState.score);
playSound('win');
document.getElementById('results-mode').textContent = 'DEFINITION MATCH COMPLETE';
document.getElementById('results-score').textContent = defState.score;
document.getElementById('results-high').textContent = isNewHigh ? '🏆 New High Score!' : `High Score: ${getHighScore('definitions')}`;
document.getElementById('results-details').textContent = `${defState.correct}/${defState.total} correct`;
document.getElementById('results-replay').onclick = startDefinitions;
showScreen('results-screen');
}
function replayGame() {
const mode = document.getElementById('results-mode').textContent;
if (mode.includes('SCRAMBLE')) startScramble();
else startDefinitions();
}
// INIT
updateMenuScores();
</script>
</body>
</html>