Extreme Addition - Ekstrem Edition
by EpicPanda80834 lines43.7 KB
```html
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Extreme Addition - Ekstrem Edition</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- FontAwesome Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;700;900&family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Plus Jakarta Sans', sans-serif;
background-color: #020617;
}
.font-orbitron {
font-family: 'Orbitron', sans-serif;
}
/* Neon Glows */
.neon-border-blue {
box-shadow: 0 0 15px rgba(59, 130, 246, 0.35);
}
.neon-border-red {
box-shadow: 0 0 20px rgba(239, 68, 68, 0.45);
}
.neon-border-green {
box-shadow: 0 0 15px rgba(34, 197, 94, 0.35);
}
.neon-border-amber {
box-shadow: 0 0 15px rgba(245, 158, 11, 0.35);
}
/* Grid transitions */
.grid-cell {
transition: all 0.15s ease;
}
.grid-cell:hover {
transform: scale(1.1);
z-index: 10;
}
/* Row highlight mode helper */
.highlighted-row {
background-color: rgba(239, 68, 68, 0.15) !important;
border-color: rgba(239, 68, 68, 0.4) !important;
}
</style>
</head>
<body class="text-gray-100 min-h-screen flex flex-col justify-between overflow-x-hidden relative select-none">
<!-- Cyberpunk Grid Overlay -->
<div class="absolute inset-0 bg-[linear-gradient(to_right,#0f172a_1px,transparent_1px),linear-gradient(to_bottom,#0f172a_1px,transparent_1px)] bg-[size:3rem_3rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_0%,#000_70%,transparent_100%)] pointer-events-none z-0"></div>
<div class="absolute top-10 left-10 w-72 h-72 bg-blue-600/10 rounded-full blur-[100px] pointer-events-none z-0"></div>
<div class="absolute bottom-10 right-10 w-72 h-72 bg-red-600/10 rounded-full blur-[100px] pointer-events-none z-0"></div>
<!-- Header Navigation -->
<header class="border-b border-slate-800 bg-slate-950/80 backdrop-blur-md sticky top-0 z-40 px-4 py-3">
<div class="max-w-5xl mx-auto flex justify-between items-center">
<div class="flex items-center gap-2.5">
<span class="text-red-500 text-2xl animate-pulse"><i class="fa-solid fa-brain"></i></span>
<div>
<h1 class="text-lg sm:text-xl font-black tracking-widest text-transparent bg-clip-text bg-gradient-to-r from-red-500 via-orange-500 to-yellow-500 font-orbitron">
EXTREME <span class="text-white text-xs sm:text-sm font-light">ADDITION</span>
</h1>
<p class="text-[9px] text-slate-400 tracking-wider uppercase font-semibold">Clash of Champions Simulator</p>
</div>
</div>
<div class="flex items-center gap-3">
<button id="btn-stats" class="text-slate-400 hover:text-white transition-colors p-2 text-md" title="Statistik">
<i class="fa-solid fa-chart-bar"></i>
</button>
<button id="btn-how" class="text-slate-400 hover:text-white transition-colors p-2 text-md" title="Cara Bermain">
<i class="fa-solid fa-circle-question"></i>
</button>
<div class="bg-slate-900 border border-slate-800 px-3 py-1 rounded-full flex items-center gap-1.5 text-[11px]">
<span class="w-2 h-2 rounded-full bg-red-500 animate-ping"></span>
<span class="font-bold text-slate-300 font-orbitron">COC.EDITION</span>
</div>
</div>
</div>
</header>
<!-- Main Game Container -->
<main class="flex-grow flex items-center justify-center p-3 sm:p-4 z-10 w-full">
<div class="w-full max-w-4xl grid grid-cols-1 lg:grid-cols-12 gap-4">
<!-- Left Side: Puzzle Area & Controls (8 cols) -->
<div class="lg:col-span-8 flex flex-col gap-3">
<!-- Difficulty Selection -->
<div class="grid grid-cols-4 gap-1.5 p-1 bg-slate-950/90 rounded-xl border border-slate-800/80">
<button onclick="changeLevel('easy')" id="tab-easy" class="py-2 text-[11px] font-bold rounded-lg transition-all uppercase tracking-wider duration-300">
Mudah <span class="block text-[8px] opacity-70">3 × 3</span>
</button>
<button onclick="changeLevel('normal')" id="tab-normal" class="py-2 text-[11px] font-bold rounded-lg transition-all uppercase tracking-wider duration-300">
Normal <span class="block text-[8px] opacity-70">6 × 6</span>
</button>
<button onclick="changeLevel('hard')" id="tab-hard" class="py-2 text-[11px] font-bold rounded-lg transition-all uppercase tracking-wider duration-300">
Sulit <span class="block text-[8px] opacity-70">12 × 12</span>
</button>
<button onclick="changeLevel('extreme')" id="tab-extreme" class="py-2 text-[11px] font-bold rounded-lg transition-all uppercase tracking-wider duration-300">
EKSTREM <span class="block text-[8px] opacity-70">20 × 20</span>
</button>
</div>
<!-- HUD Info -->
<div class="grid grid-cols-3 gap-2">
<div class="bg-slate-950/70 border border-slate-800 p-2 rounded-xl text-center">
<div class="text-[9px] text-slate-400 uppercase tracking-wider">Skor Akumulasi</div>
<div id="hud-score" class="text-lg font-bold font-orbitron text-white">0</div>
</div>
<div class="bg-slate-950/70 border border-slate-800 p-2 rounded-xl text-center relative overflow-hidden" id="streak-card">
<div class="text-[9px] text-slate-400 uppercase tracking-wider">Streak Beruntun</div>
<div id="hud-streak" class="text-lg font-bold font-orbitron text-orange-500">0</div>
<div id="streak-glow" class="absolute inset-0 bg-orange-500/5 opacity-0 pointer-events-none"></div>
</div>
<div class="bg-slate-950/70 border border-slate-800 p-2 rounded-xl text-center">
<div class="text-[9px] text-slate-400 uppercase tracking-wider">Durasi Tes</div>
<div id="hud-timer" class="text-lg font-bold font-orbitron text-yellow-500">00:00.0</div>
</div>
</div>
<!-- Main Arena Board -->
<div id="puzzle-container" class="bg-slate-900/60 border border-slate-850 rounded-2xl p-3 sm:p-5 relative overflow-hidden flex flex-col justify-between min-h-[380px] transition-all duration-300">
<!-- Top Ribbon -->
<div class="flex justify-between items-center mb-3">
<div class="flex items-center gap-2">
<span id="level-badge" class="px-2.5 py-0.5 rounded text-[9px] font-black uppercase tracking-widest font-orbitron">
MUDAH
</span>
<span class="text-[10px] text-slate-400 hidden sm:inline" id="grid-desc-text">Tambahkan seluruh angka di bawah</span>
</div>
<div class="flex items-center gap-2">
<!-- Toggle Helper Highlight Row -->
<button onclick="toggleHighlightMode()" id="btn-highlight-toggle" class="px-2 py-1 bg-slate-800 hover:bg-slate-700 text-slate-300 rounded text-[10px] font-semibold flex items-center gap-1 transition-all" title="Klik baris untuk menandai pembacaan">
<i class="fa-solid fa-highlighter"></i> Highlight: <span id="highlight-status-text">OFF</span>
</button>
<!-- Shuffle Question Button -->
<button onclick="regenerateGrid(true)" class="group flex items-center gap-1 px-2.5 py-1 bg-red-950/30 hover:bg-red-900/40 text-red-400 border border-red-900/30 hover:border-red-800 rounded-lg transition-all text-[10px] font-bold">
<i class="fa-solid fa-arrows-rotate group-hover:rotate-180 transition-transform duration-500"></i>
ACAR ANGKA
</button>
</div>
</div>
<!-- The dynamic grid -->
<div class="flex-grow flex items-center justify-center my-2 overflow-auto max-h-[420px] bg-black/40 rounded-xl p-2 border border-slate-950">
<div id="numbers-grid" class="grid mx-auto select-none">
<!-- Grid cells are injected here -->
</div>
</div>
<!-- Bottom Indicator: Helper Info -->
<div class="text-[9.5px] text-slate-500 text-center mt-2 flex items-center justify-center gap-1.5">
<i class="fa-solid fa-circle-info"></i>
<span>Tips: Jumlah baris demi baris agar tidak lupa. Gunakan fitur Highlight jika kesulitan fokus.</span>
</div>
</div>
</div>
<!-- Right Side: Input & Verification Panel (4 cols) -->
<div class="lg:col-span-4 flex flex-col gap-3">
<!-- Input Box -->
<div class="bg-slate-950/90 border border-slate-800 rounded-2xl p-4 flex flex-col gap-2">
<label class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Input Jawaban Total:</label>
<div class="relative">
<div id="answer-box" class="w-full bg-slate-900 border-2 border-slate-800 rounded-xl py-4 px-3 text-center text-2xl font-bold font-orbitron tracking-widest text-slate-200 min-h-[64px] flex items-center justify-center transition-all">
<span id="answer-placeholder" class="text-slate-600 font-sans text-xs font-normal tracking-normal">Tekan tombol angka di bawah...</span>
<span id="answer-text" class="hidden"></span>
</div>
<button onclick="clearAnswer()" class="absolute right-3 top-1/2 -translate-y-1/2 w-8 h-8 flex items-center justify-center rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-400 hover:text-white transition-all">
<i class="fa-solid fa-backspace"></i>
</button>
</div>
<div id="feedback-msg" class="text-center text-xs font-semibold min-h-[16px] opacity-0 transition-opacity duration-300">
Feedback status
</div>
</div>
<!-- Custom Touch Keypad -->
<div class="bg-slate-950/90 border border-slate-800 rounded-2xl p-3 grid grid-cols-3 gap-1.5">
<button onclick="pressKey('1')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">1</button>
<button onclick="pressKey('2')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">2</button>
<button onclick="pressKey('3')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">3</button>
<button onclick="pressKey('4')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">4</button>
<button onclick="pressKey('5')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">5</button>
<button onclick="pressKey('6')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">6</button>
<button onclick="pressKey('7')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">7</button>
<button onclick="pressKey('8')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">8</button>
<button onclick="pressKey('9')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">9</button>
<button onclick="backspace()" class="py-3.5 bg-slate-900/40 hover:bg-amber-950/30 text-amber-500 active:scale-95 text-base rounded-xl border border-amber-900/20 transition-all">
<i class="fa-solid fa-delete-left"></i>
</button>
<button onclick="pressKey('0')" class="py-3.5 bg-slate-900 hover:bg-slate-800 active:scale-95 text-lg font-bold font-orbitron rounded-xl border border-slate-800/50 transition-all">0</button>
<button onclick="clearAnswer()" class="py-3.5 bg-slate-900/40 hover:bg-slate-800 text-slate-400 active:scale-95 text-xs font-semibold uppercase rounded-xl border border-slate-800/50 transition-all">
Reset
</button>
<button onclick="submitAnswer()" id="btn-submit" class="col-span-3 py-3.5 bg-gradient-to-r from-red-600 to-orange-600 hover:from-red-500 hover:to-orange-500 text-white font-black tracking-widest text-xs uppercase rounded-xl transition-all shadow-lg active:scale-95 font-orbitron mt-1">
Kirim Jawaban <i class="fa-solid fa-circle-check ml-1"></i>
</button>
</div>
<!-- Analysis Helper Section -->
<div class="bg-slate-950/90 border border-slate-800 rounded-2xl p-4">
<button onclick="toggleHint()" class="flex items-center justify-between w-full text-xs text-slate-500 hover:text-slate-300 transition-colors">
<span class="flex items-center gap-1.5"><i class="fa-regular fa-lightbulb"></i> Analisa & Kunci Jawaban</span>
<i id="hint-chevron" class="fa-solid fa-chevron-down transition-transform"></i>
</button>
<div id="hint-content" class="hidden mt-3 p-3 bg-slate-900 border border-slate-850 rounded-lg text-xs leading-relaxed text-slate-400 max-h-[140px] overflow-y-auto">
<!-- Filled on generation -->
</div>
</div>
</div>
</div>
</main>
<!-- Modal: Statistik -->
<div id="modal-stats" class="fixed inset-0 bg-black/80 backdrop-blur-md flex items-center justify-center p-4 z-50 hidden transition-all duration-300 opacity-0">
<div class="bg-slate-900 border border-slate-800 w-full max-w-md rounded-2xl overflow-hidden relative">
<div class="absolute top-0 left-0 right-0 h-1.5 bg-gradient-to-r from-red-500 via-orange-500 to-yellow-500"></div>
<div class="p-6">
<div class="flex justify-between items-center mb-6">
<h3 class="text-sm font-black font-orbitron text-white tracking-widest flex items-center gap-2">
<i class="fa-solid fa-chart-line text-red-500"></i> PERFORMA EXTREME ADDITION
</h3>
<button onclick="toggleModal('stats', false)" class="text-slate-400 hover:text-white text-lg"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="grid grid-cols-2 gap-3 mb-6">
<div class="bg-slate-950 p-3 rounded-xl border border-slate-850">
<div class="text-[10px] text-slate-400">Total Dimainkan</div>
<div id="stat-total" class="text-xl font-bold font-orbitron text-blue-400 mt-1">0</div>
</div>
<div class="bg-slate-950 p-3 rounded-xl border border-slate-850">
<div class="text-[10px] text-slate-400">Benar / Salah</div>
<div id="stat-ratio" class="text-xl font-bold font-orbitron text-green-400 mt-1">0 / 0</div>
</div>
<div class="bg-slate-950 p-3 rounded-xl border border-slate-850">
<div class="text-[10px] text-slate-400">Rasio Akurasi</div>
<div id="stat-accuracy" class="text-xl font-bold font-orbitron text-purple-400 mt-1">0%</div>
</div>
<div class="bg-slate-950 p-3 rounded-xl border border-slate-850">
<div class="text-[10px] text-slate-400">Maksimum Streak</div>
<div id="stat-max-streak" class="text-xl font-bold font-orbitron text-orange-400 mt-1">0</div>
</div>
</div>
<div class="space-y-3">
<h4 class="text-[10px] font-bold text-slate-400 uppercase tracking-widest border-b border-slate-800 pb-1">Level Penyelesaian</h4>
<div class="space-y-2">
<div>
<div class="flex justify-between text-xs mb-1">
<span class="text-green-400 font-semibold">Mudah (3x3)</span>
<span id="dist-easy" class="text-slate-300">0</span>
</div>
<div class="w-full h-1.5 bg-slate-950 rounded-full overflow-hidden"><div id="bar-easy" class="h-full bg-green-500 rounded-full" style="width: 0%"></div></div>
</div>
<div>
<div class="flex justify-between text-xs mb-1">
<span class="text-blue-400 font-semibold">Normal (6x6)</span>
<span id="dist-normal" class="text-slate-300">0</span>
</div>
<div class="w-full h-1.5 bg-slate-950 rounded-full overflow-hidden"><div id="bar-normal" class="h-full bg-blue-500 rounded-full" style="width: 0%"></div></div>
</div>
<div>
<div class="flex justify-between text-xs mb-1">
<span class="text-amber-500 font-semibold">Sulit (12x12)</span>
<span id="dist-hard" class="text-slate-300">0</span>
</div>
<div class="w-full h-1.5 bg-slate-950 rounded-full overflow-hidden"><div id="bar-hard" class="h-full bg-amber-500 rounded-full" style="width: 0%"></div></div>
</div>
<div>
<div class="flex justify-between text-xs mb-1">
<span class="text-red-500 font-semibold">Ekstrem (20x20)</span>
<span id="dist-extreme" class="text-slate-300">0</span>
</div>
<div class="w-full h-1.5 bg-slate-950 rounded-full overflow-hidden"><div id="bar-extreme" class="h-full bg-red-600 rounded-full" style="width: 0%"></div></div>
</div>
</div>
</div>
<div class="mt-6 flex gap-3">
<button onclick="resetStats()" class="flex-1 py-2 bg-slate-950 hover:bg-red-950/20 text-red-400 hover:text-red-300 border border-slate-850 hover:border-red-900 rounded-xl transition-all text-xs font-semibold">
<i class="fa-solid fa-trash-can mr-1.5"></i> Reset Data
</button>
<button onclick="toggleModal('stats', false)" class="flex-1 py-2 bg-slate-800 hover:bg-slate-700 text-white rounded-xl transition-all text-xs font-semibold">
Tutup
</button>
</div>
</div>
</div>
</div>
<!-- Modal: Cara Bermain -->
<div id="modal-how" class="fixed inset-0 bg-black/80 backdrop-blur-md flex items-center justify-center p-4 z-50 hidden transition-all duration-300 opacity-0">
<div class="bg-slate-900 border border-slate-800 w-full max-w-md rounded-2xl overflow-hidden relative">
<div class="absolute top-0 left-0 right-0 h-1.5 bg-gradient-to-r from-red-500 to-orange-500"></div>
<div class="p-6">
<div class="flex justify-between items-center mb-6">
<h3 class="text-sm font-black font-orbitron text-white tracking-widest flex items-center gap-2">
<i class="fa-solid fa-gamepad text-red-500"></i> ATURAN EXTREME ADDITION
</h3>
<button onclick="toggleModal('how', false)" class="text-slate-400 hover:text-white text-lg"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="space-y-4 text-xs text-slate-300 leading-relaxed max-h-[350px] overflow-y-auto pr-1">
<div class="bg-slate-950 p-3 rounded-lg border border-slate-800">
<p class="font-bold text-red-400 mb-1">🧮 Cara Bermain</p>
<p>Jumlahkan setiap angka tunggal di dalam kotak/grid yang ditampilkan dari kiri ke kanan, baris demi baris, lalu masukkan hasil total penjumlahannya pada kotak jawaban.</p>
</div>
<div class="bg-slate-950 p-3 rounded-lg border border-slate-800">
<p class="font-bold text-amber-400 mb-1"><i class="fa-solid fa-highlighter mr-1"></i> Mode Fitur Highlight Baris</p>
<p>Klik tombol <span class="text-white font-bold">Highlight: ON</span>. Ketika aktif, klik baris mana saja di dalam tabel angka untuk mewarnai baris tersebut. Ini sangat membantu mata agar tidak salah baris saat melakukan kalkulasi massal.</p>
</div>
<div>
<p class="font-bold text-white mb-2 uppercase tracking-widest text-[10px]">Ukuran Grid Angka:</p>
<ul class="space-y-2 pl-2">
<li class="flex items-start gap-2">
<span class="text-green-500 mt-0.5"><i class="fa-solid fa-circle-dot"></i></span>
<div><strong class="text-green-400">MUDAH:</strong> Grid $3 \times 3$ (Total 9 angka)</div>
</li>
<li class="flex items-start gap-2">
<span class="text-blue-500 mt-0.5"><i class="fa-solid fa-circle-dot"></i></span>
<div><strong class="text-blue-400">NORMAL:</strong> Grid $6 \times 6$ (Total 36 angka)</div>
</li>
<li class="flex items-start gap-2">
<span class="text-amber-500 mt-0.5"><i class="fa-solid fa-circle-dot"></i></span>
<div><strong class="text-amber-400">SULIT:</strong> Grid $12 \times 12$ (Total 144 angka)</div>
</li>
<li class="flex items-start gap-2">
<span class="text-red-500 mt-0.5"><i class="fa-solid fa-circle-dot"></i></span>
<div><strong class="text-red-400">EKSTREM:</strong> Grid $20 \times 20$ (Total 400 angka!)</div>
</li>
</ul>
</div>
<div class="bg-slate-950 p-3 rounded-lg border border-slate-800">
<p class="font-bold text-blue-400 mb-1"><i class="fa-solid fa-arrows-rotate mr-1"></i> Fitur Acak Angka</p>
<p>Jika Anda sudah menyelesaikan tantangan saat ini atau ingin mengubah kumpulan angkanya, cukup klik <span class="text-white font-semibold">Acak Angka</span> di pojok kanan atas tabel. Angka akan berganti instan dan siap dihitung kembali.</p>
</div>
</div>
<div class="mt-6">
<button onclick="toggleModal('how', false)" class="w-full py-2.5 bg-gradient-to-r from-red-600 to-orange-600 text-white font-bold rounded-xl transition-all text-xs uppercase tracking-widest font-orbitron">
MULAI BERLATIH
</button>
</div>
</div>
</div>
</div>
<!-- Footer -->
<footer class="border-t border-slate-900 bg-slate-950/60 text-center py-3.5 px-4 z-10 text-[10px] text-slate-500">
<div class="max-w-5xl mx-auto flex flex-col sm:flex-row justify-between items-center gap-2">
<div>© 2026 EKSTREM EDITION. Dikembangkan untuk simulasi kemampuan mental-aritmetika ekstrem.</div>
<div class="flex gap-4">
<span>Versi 1.1.0-CoC</span>
<span class="hover:text-slate-300 transition-colors cursor-help">Tingkat Akurasi 100%</span>
</div>
</div>
</footer>
<!-- Interactive Game Engine JS -->
<script>
// Game State Management
const state = {
level: 'easy', // easy, normal, hard, extreme
gridSize: 3, // column & row size
score: 0,
streak: 0,
maxStreak: 0,
totalAnswered: 0,
correctCount: 0,
wrongCount: 0,
levelStats: {
easy: 0,
normal: 0,
hard: 0,
extreme: 0
},
currentGrid: [], // 2D array representing rows & cells
totalSum: 0,
highlightModeActive: false,
timerInterval: null,
secondsElapsed: 0,
millisecondsElapsed: 0
};
const levelMetadata = {
easy: {
size: 3,
colorClass: 'text-green-400 border-green-500/20 bg-green-500/10',
badgeText: 'MUDAH (3x3)',
accentColor: '#22c55e',
shadowClass: 'neon-border-green'
},
normal: {
size: 6,
colorClass: 'text-blue-400 border-blue-500/20 bg-blue-500/10',
badgeText: 'NORMAL (6x6)',
accentColor: '#3b82f6',
shadowClass: 'neon-border-blue'
},
hard: {
size: 12,
colorClass: 'text-amber-500 border-amber-500/20 bg-amber-500/10',
badgeText: 'SULIT (12x12)',
accentColor: '#f59e0b',
shadowClass: 'neon-border-amber'
},
extreme: {
size: 20,
colorClass: 'text-red-500 border-red-500/20 bg-red-500/10',
badgeText: 'EKSTREM (20x20)',
accentColor: '#ef4444',
shadowClass: 'neon-border-red'
}
};
// Window load initialization
window.onload = function() {
loadStatsFromStorage();
changeLevel('easy');
startTimer();
setupKeyboardSupport();
};
function setupKeyboardSupport() {
document.getElementById('btn-stats').addEventListener('click', () => toggleModal('stats', true));
document.getElementById('btn-how').addEventListener('click', () => toggleModal('how', true));
document.addEventListener('keydown', function(e) {
if (e.key >= '0' && e.key <= '9') {
pressKey(e.key);
} else if (e.key === 'Backspace') {
backspace();
} else if (e.key === 'Enter') {
submitAnswer();
} else if (e.key === 'Escape') {
clearAnswer();
}
});
}
// Live high-accuracy timer
function startTimer() {
clearInterval(state.timerInterval);
let startTime = Date.now();
state.timerInterval = setInterval(() => {
let diff = Date.now() - startTime;
state.secondsElapsed = Math.floor(diff / 1000);
state.millisecondsElapsed = Math.floor((diff % 1000) / 100);
const mins = Math.floor(state.secondsElapsed / 60).toString().padStart(2, '0');
const secs = (state.secondsElapsed % 60).toString().padStart(2, '0');
const ms = state.millisecondsElapsed;
document.getElementById('hud-timer').innerText = `${mins}:${secs}.${ms}`;
}, 100);
}
function resetTimer() {
clearInterval(state.timerInterval);
state.secondsElapsed = 0;
state.millisecondsElapsed = 0;
document.getElementById('hud-timer').innerText = `00:00.0`;
startTimer();
}
// Change level tab
function changeLevel(level) {
state.level = level;
state.gridSize = levelMetadata[level].size;
// Update Level Tabs active state
['easy', 'normal', 'hard', 'extreme'].forEach(lvl => {
const tab = document.getElementById(`tab-${lvl}`);
if (lvl === level) {
tab.className = `py-2 text-[11px] font-bold rounded-lg transition-all uppercase tracking-wider duration-300 ${levelMetadata[lvl].colorClass} border border-current`;
} else {
tab.className = `py-2 text-[11px] font-bold rounded-lg transition-all uppercase tracking-wider duration-300 bg-transparent text-slate-500 hover:text-slate-300`;
}
});
// Update board styles
const config = levelMetadata[level];
const container = document.getElementById('puzzle-container');
const badge = document.getElementById('level-badge');
container.className = container.className.split(' ').filter(c => !c.includes('neon-border')).join(' ');
container.classList.add(config.shadowClass);
badge.className = `px-2.5 py-0.5 rounded text-[9px] font-black uppercase tracking-widest font-orbitron ${config.colorClass}`;
badge.innerText = config.badgeText;
// Generate puzzle grid
clearAnswer();
regenerateGrid();
resetTimer();
}
// Generate matrix of random digits
function regenerateGrid(isManual = false) {
const size = state.gridSize;
const gridContainer = document.getElementById('numbers-grid');
gridContainer.innerHTML = ''; // Clear output
// Configure CSS grid columns dynamically
gridContainer.style.gridTemplateColumns = `repeat(${size}, minmax(0, 1fr))`;
// Choose cell font sizing based on grid density
let cellSizeClass = "w-11 h-11 text-lg";
if (size === 6) cellSizeClass = "w-8 h-8 sm:w-10 sm:h-10 text-sm sm:text-base";
if (size === 12) cellSizeClass = "w-5 h-5 sm:w-7 sm:h-7 text-[10px] sm:text-xs";
if (size === 20) cellSizeClass = "w-[16px] h-[16px] sm:w-[22px] sm:h-[22px] text-[8px] sm:text-[10px]";
// Setup new matrix
state.currentGrid = [];
state.totalSum = 0;
let explanationRows = [];
for (let r = 0; r < size; r++) {
const rowArray = [];
let rowSum = 0;
for (let c = 0; c < size; c++) {
// Generate random digit 1-9 (avoid too many 0s or keep single digits to match CoC style)
const digit = Math.floor(Math.random() * 9) + 1;
rowArray.push(digit);
rowSum += digit;
state.totalSum += digit;
// Create cell element
const cell = document.createElement('div');
cell.className = `grid-cell flex items-center justify-center font-bold font-orbitron border border-slate-800 bg-slate-950 text-slate-300 rounded-[2px] cursor-pointer ${cellSizeClass}`;
cell.innerText = digit;
cell.dataset.row = r;
cell.dataset.col = c;
// Add click handler to toggle entire row coloring
cell.addEventListener('click', function() {
if (state.highlightModeActive) {
toggleRowHighlight(parseInt(this.dataset.row));
}
});
gridContainer.appendChild(cell);
}
state.currentGrid.push(rowArray);
explanationRows.push(`Baris ${r+1}: ` + rowArray.join(" + ") + ` = <strong>${rowSum}</strong>`);
}
// Create educational hint content
const hintContent = document.getElementById('hint-content');
hintContent.innerHTML = `
<div class="mb-2 text-white font-semibold">Solusi & Penjumlahan per baris:</div>
<div class="space-y-1 text-slate-400">
${explanationRows.join("<br>")}
</div>
<div class="mt-3 pt-2 border-t border-slate-800 text-red-400 font-bold font-orbitron text-center">
TOTAL KESELURUHAN = ${state.totalSum}
</div>
`;
if (isManual) {
showFeedback("Grid angka berhasil diacak!", "text-yellow-400");
resetTimer();
}
}
// Highlight whole row to aid user focus
function toggleRowHighlight(rowIdx) {
const cells = document.querySelectorAll('.grid-cell');
cells.forEach(cell => {
const cellRow = parseInt(cell.dataset.row);
if (cellRow === rowIdx) {
cell.classList.toggle('highlighted-row');
}
});
}
// Toggle row helper mode
function toggleHighlightMode() {
state.highlightModeActive = !state.highlightModeActive;
const btn = document.getElementById('btn-highlight-toggle');
const statusText = document.getElementById('highlight-status-text');
if (state.highlightModeActive) {
btn.className = "px-2 py-1 bg-red-600 hover:bg-red-500 text-white rounded text-[10px] font-semibold flex items-center gap-1 transition-all";
statusText.innerText = "ON";
showFeedback("Mode Highlight ON: Klik baris mana saja pada tabel untuk menandainya.", "text-blue-400");
} else {
btn.className = "px-2 py-1 bg-slate-800 hover:bg-slate-700 text-slate-300 rounded text-[10px] font-semibold flex items-center gap-1 transition-all";
statusText.innerText = "OFF";
// Reset all current highlights
const cells = document.querySelectorAll('.grid-cell');
cells.forEach(c => c.classList.remove('highlighted-row'));
}
}
// Virtual Custom Keypad inputs
function pressKey(num) {
const txt = document.getElementById('answer-text');
const placeholder = document.getElementById('answer-placeholder');
if (txt.classList.contains('hidden')) {
txt.classList.remove('hidden');
placeholder.classList.add('hidden');
}
// Prevent extremely long inputs
if (txt.innerText.length >= 7) return;
txt.innerText += num;
}
function backspace() {
const txt = document.getElementById('answer-text');
if (txt.innerText.length > 0) {
txt.innerText = txt.innerText.substring(0, txt.innerText.length - 1);
}
checkEmptyInput();
}
function clearAnswer() {
document.getElementById('answer-text').innerText = '';
checkEmptyInput();
}
function checkEmptyInput() {
const txt = document.getElementById('answer-text');
const placeholder = document.getElementById('answer-placeholder');
if (txt.innerText === '') {
txt.classList.add('hidden');
placeholder.classList.remove('hidden');
}
}
// Toggle Hint Drawer
function toggleHint() {
const content = document.getElementById('hint-content');
const chevron = document.getElementById('hint-chevron');
const isHidden = content.classList.contains('hidden');
if (isHidden) {
content.classList.remove('hidden');
chevron.classList.add('rotate-180');
} else {
content.classList.add('hidden');
chevron.classList.remove('rotate-180');
}
}
// Score & Verification
function submitAnswer() {
const txt = document.getElementById('answer-text');
const userResponse = txt.innerText;
if (!userResponse) {
showFeedback("Harap input angka jawaban terlebih dahulu!", "text-yellow-500");
return;
}
const parsedVal = parseInt(userResponse);
const isCorrect = parsedVal === state.totalSum;
state.totalAnswered++;
if (isCorrect) {
// Earn points based on grid size multiplied by speed factor!
const baseReward = state.gridSize * 15;
const speedBonus = Math.max(5, Math.round(300 / (state.secondsElapsed + 1)));
const pointsGained = baseReward + speedBonus;
state.score += pointsGained;
state.streak++;
state.correctCount++;
state.levelStats[state.level]++;
if (state.streak > state.maxStreak) {
state.maxStreak = state.streak;
}
showFeedback(`BENAR! +${pointsGained} Poin (${state.secondsElapsed}.${state.millisecondsElapsed}s)`, "text-green-500");
animateStreakBadge(true);
updateHUD();
saveStatsToStorage();
// Automatically load next grid after success transition
setTimeout(() => {
clearAnswer();
regenerateGrid();
resetTimer();
}, 1200);
} else {
state.streak = 0;
state.wrongCount++;
showFeedback(`SALAH! Jawaban Anda: ${parsedVal}. Jawaban yang benar adalah ${state.totalSum}`, "text-red-500");
animateStreakBadge(false);
updateHUD();
saveStatsToStorage();
}
}
function showFeedback(msg, colorClass) {
const el = document.getElementById('feedback-msg');
el.innerText = msg;
el.className = `text-center text-xs font-bold min-h-[16px] transition-all opacity-100 ${colorClass}`;
setTimeout(() => {
el.className = `text-center text-xs font-semibold min-h-[16px] opacity-0 transition-all duration-300`;
}, 4000);
}
function animateStreakBadge(correct) {
const card = document.getElementById('streak-card');
const glow = document.getElementById('streak-glow');
if (correct && state.streak >= 3) {
glow.style.opacity = "1";
card.classList.add('border-orange-500', 'neon-border-amber');
} else {
glow.style.opacity = "0";
card.classList.remove('border-orange-500', 'neon-border-amber');
}
}
function updateHUD() {
document.getElementById('hud-score').innerText = state.score;
document.getElementById('hud-streak').innerText = state.streak;
}
// Modals management
function toggleModal(id, show) {
const modal = document.getElementById(`modal-${id}`);
if (show) {
if (id === 'stats') renderStats();
modal.classList.remove('hidden');
setTimeout(() => modal.classList.remove('opacity-0'), 50);
} else {
modal.classList.add('opacity-0');
setTimeout(() => modal.classList.add('hidden'), 300);
}
}
function renderStats() {
document.getElementById('stat-total').innerText = state.totalAnswered;
document.getElementById('stat-ratio').innerText = `${state.correctCount} / ${state.wrongCount}`;
const accuracy = state.totalAnswered > 0 ? Math.round((state.correctCount / state.totalAnswered) * 100) : 0;
document.getElementById('stat-accuracy').innerText = `${accuracy}%`;
document.getElementById('stat-max-streak').innerText = state.maxStreak;
// Bar statistics distribution
['easy', 'normal', 'hard', 'extreme'].forEach(lvl => {
const count = state.levelStats[lvl] || 0;
document.getElementById(`dist-${lvl}`).innerText = count;
const percent = state.correctCount > 0 ? (count / state.correctCount) * 100 : 0;
document.getElementById(`bar-${lvl}`).style.width = `${percent}%`;
});
}
// Persistence storage
function saveStatsToStorage() {
const payload = {
score: state.score,
maxStreak: state.maxStreak,
totalAnswered: state.totalAnswered,
correctCount: state.correctCount,
wrongCount: state.wrongCount,
levelStats: state.levelStats
};
localStorage.setItem('extreme_addition_coc_stats', JSON.stringify(payload));
}
function loadStatsFromStorage() {
const saved = localStorage.getItem('extreme_addition_coc_stats');
if (saved) {
try {
const parsed = JSON.parse(saved);
state.score = parsed.score || 0;
state.maxStreak = parsed.maxStreak || 0;
state.totalAnswered = parsed.totalAnswered || 0;
state.correctCount = parsed.correctCount || 0;
state.wrongCount = parsed.wrongCount || 0;
state.levelStats = parsed.levelStats || { easy: 0, normal: 0, hard: 0, extreme: 0 };
updateHUD();
} catch(e) {
console.error("Gagal mengurai statistik simpanan peramban.", e);
}
}
}
function resetStats() {
localStorage.removeItem('extreme_addition_coc_stats');
state.score = 0;
state.streak = 0;
state.maxStreak = 0;
state.totalAnswered = 0;
state.correctCount = 0;
state.wrongCount = 0;
state.levelStats = { easy: 0, normal: 0, hard: 0, extreme: 0 };
updateHUD();
renderStats();
showFeedback("Seluruh data permainan berhasil di-reset!", "text-amber-450");
}
</script>
</body>
</html>
```
Game Source: Extreme Addition - Ekstrem Edition
Creator: EpicPanda80
Libraries: none
Complexity: complex (834 lines, 43.7 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: extreme-addition-ekstrem-edition-epicpanda80" to link back to the original. Then publish at arcadelab.ai/publish.