Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Where? - Geography Game</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;700;800&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --bg-primary: #0a0a0f; | |
| --bg-secondary: #12121a; | |
| --bg-card: #1a1a24; | |
| --bg-card-hover: #22222e; | |
| --accent-primary: #00d4aa; | |
| --accent-secondary: #7c3aed; | |
| --accent-tertiary: #f59e0b; | |
| --text-primary: #ffffff; | |
| --text-secondary: #9ca3af; | |
| --text-muted: #6b7280; | |
| --success: #10b981; | |
| --error: #ef4444; | |
| --border: rgba(255, 255, 255, 0.08); | |
| --glow: 0 0 40px rgba(0, 212, 170, 0.3); | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Outfit', sans-serif; | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| background-image: | |
| radial-gradient(ellipse at 20% 20%, rgba(124, 58, 237, 0.15) 0%, transparent 50%), | |
| radial-gradient(ellipse at 80% 80%, rgba(0, 212, 170, 0.1) 0%, transparent 50%), | |
| linear-gradient(180deg, var(--bg-primary) 0%, var(--bg-secondary) 100%); | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| /* Header */ | |
| header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 20px 0; | |
| border-bottom: 1px solid var(--border); | |
| margin-bottom: 40px; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| } | |
| .logo-icon { | |
| width: 48px; | |
| height: 48px; | |
| background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary)); | |
| border-radius: 12px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 24px; | |
| box-shadow: var(--glow); | |
| } | |
| .logo h1 { | |
| font-size: 1.8rem; | |
| font-weight: 800; | |
| background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| .built-with { | |
| font-family: 'Space Mono', monospace; | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| text-decoration: none; | |
| padding: 8px 16px; | |
| border: 1px solid var(--border); | |
| border-radius: 20px; | |
| transition: all 0.3s ease; | |
| } | |
| .built-with:hover { | |
| border-color: var(--accent-primary); | |
| color: var(--accent-primary); | |
| } | |
| /* Game Mode Selection */ | |
| .game-modes { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| gap: 20px; | |
| margin-bottom: 40px; | |
| } | |
| .mode-card { | |
| background: var(--bg-card); | |
| border: 1px solid var(--border); | |
| border-radius: 20px; | |
| padding: 30px; | |
| cursor: pointer; | |
| transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .mode-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 3px; | |
| background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary)); | |
| transform: scaleX(0); | |
| transition: transform 0.4s ease; | |
| } | |
| .mode-card:hover { | |
| transform: translateY(-5px); | |
| border-color: var(--accent-primary); | |
| background: var(--bg-card-hover); | |
| } | |
| .mode-card:hover::before { | |
| transform: scaleX(1); | |
| } | |
| .mode-icon { | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 16px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 28px; | |
| margin-bottom: 20px; | |
| } | |
| .mode-card:nth-child(1) .mode-icon { | |
| background: linear-gradient(135deg, rgba(0, 212, 170, 0.2), rgba(0, 212, 170, 0.05)); | |
| border: 1px solid rgba(0, 212, 170, 0.3); | |
| } | |
| .mode-card:nth-child(2) .mode-icon { | |
| background: linear-gradient(135deg, rgba(124, 58, 237, 0.2), rgba(124, 58, 237, 0.05)); | |
| border: 1px solid rgba(124, 58, 237, 0.3); | |
| } | |
| .mode-card:nth-child(3) .mode-icon { | |
| background: linear-gradient(135deg, rgba(245, 158, 11, 0.2), rgba(245, 158, 11, 0.05)); | |
| border: 1px solid rgba(245, 158, 11, 0.3); | |
| } | |
| .mode-card:nth-child(4) .mode-icon { | |
| background: linear-gradient(135deg, rgba(239, 68, 68, 0.2), rgba(239, 68, 68, 0.05)); | |
| border: 1px solid rgba(239, 68, 68, 0.3); | |
| } | |
| .mode-card h3 { | |
| font-size: 1.3rem; | |
| margin-bottom: 10px; | |
| font-weight: 600; | |
| } | |
| .mode-card p { | |
| color: var(--text-secondary); | |
| font-size: 0.9rem; | |
| line-height: 1.6; | |
| } | |
| /* Game Area */ | |
| .game-area { | |
| display: none; | |
| animation: fadeIn 0.5s ease; | |
| } | |
| .game-area.active { | |
| display: block; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .game-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 30px; | |
| flex-wrap: wrap; | |
| gap: 20px; | |
| } | |
| .score-display { | |
| display: flex; | |
| gap: 30px; | |
| } | |
| .score-item { | |
| text-align: center; | |
| } | |
| .score-label { | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| margin-bottom: 5px; | |
| } | |
| .score-value { | |
| font-family: 'Space Mono', monospace; | |
| font-size: 1.8rem; | |
| font-weight: 700; | |
| color: var(--accent-primary); | |
| } | |
| .score-value.wrong { | |
| color: var(--error); | |
| } | |
| /* Map Container */ | |
| .map-container { | |
| background: var(--bg-card); | |
| border: 1px solid var(--border); | |
| border-radius: 20px; | |
| padding: 30px; | |
| margin-bottom: 30px; | |
| position: relative; | |
| overflow: hidden; | |
| min-height: 400px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .question-text { | |
| text-align: center; | |
| margin-bottom: 30px; | |
| } | |
| .question-text h2 { | |
| font-size: 1.5rem; | |
| margin-bottom: 10px; | |
| } | |
| .question-text p { | |
| color: var(--text-secondary); | |
| } | |
| .country-shape { | |
| width: 200px; | |
| height: 200px; | |
| background: var(--bg-secondary); | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 4rem; | |
| position: relative; | |
| animation: pulse 2s ease-in-out infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| } | |
| /* Answer Options */ | |
| .options-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| gap: 15px; | |
| margin-bottom: 30px; | |
| } | |
| .option-btn { | |
| background: var(--bg-card); | |
| border: 2px solid var(--border); | |
| border-radius: 12px; | |
| padding: 18px 24px; | |
| color: var(--text-primary); | |
| font-family: 'Outfit', sans-serif; | |
| font-size: 1rem; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| } | |
| .option-btn:hover:not(:disabled) { | |
| border-color: var(--accent-primary); | |
| background: rgba(0, 212, 170, 0.1); | |
| transform: translateY(-2px); | |
| } | |
| .option-btn.correct { | |
| border-color: var(--success); | |
| background: rgba(16, 185, 129, 0.2); | |
| animation: correctPulse 0.5s ease; | |
| } | |
| .option-btn.wrong { | |
| border-color: var(--error); | |
| background: rgba(239, 68, 68, 0.2); | |
| animation: shake 0.5s ease; | |
| } | |
| @keyframes correctPulse { | |
| 0%, 100% { transform: scale(1); } | |
| 50% { transform: scale(1.02); } | |
| } | |
| @keyframes shake { | |
| 0%, 100% { transform: translateX(0); } | |
| 25% { transform: translateX(-5px); } | |
| 75% { transform: translateX(5px); } | |
| } | |
| .option-btn:disabled { | |
| cursor: not-allowed; | |
| opacity: 0.7; | |
| } | |
| .option-flag { | |
| font-size: 1.5rem; | |
| } | |
| /* Controls */ | |
| .controls { | |
| display: flex; | |
| gap: 15px; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| } | |
| .btn { | |
| padding: 14px 32px; | |
| border-radius: 12px; | |
| font-family: 'Outfit', sans-serif; | |
| font-size: 1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| border: none; | |
| } | |
| .btn-primary { | |
| background: linear-gradient(135deg, var(--accent-primary), #00a88a); | |
| color: var(--bg-primary); | |
| box-shadow: 0 4px 20px rgba(0, 212, 170, 0.3); | |
| } | |
| .btn-primary:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 6px 30px rgba(0, 212, 170, 0.4); | |
| } | |
| .btn-secondary { | |
| background: var(--bg-card); | |
| color: var(--text-primary); | |
| border: 1px solid var(--border); | |
| } | |
| .btn-secondary:hover { | |
| border-color: var(--accent-primary); | |
| background: var(--bg-card-hover); | |
| } | |
| /* Results */ | |
| .results-modal { | |
| display: none; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: rgba(0, 0, 0, 0.8); | |
| backdrop-filter: blur(10px); | |
| align-items: center; | |
| justify-content: center; | |
| z-index: 1000; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| .results-modal.active { | |
| display: flex; | |
| } | |
| .results-content { | |
| background: var(--bg-card); | |
| border: 1px solid var(--border); | |
| border-radius: 24px; | |
| padding: 50px; | |
| text-align: center; | |
| max-width: 500px; | |
| animation: slideUp 0.5s ease; | |
| } | |
| @keyframes slideUp { | |
| from { transform: translateY(50px); opacity: 0; } | |
| to { transform: translateY(0); opacity: 1; } | |
| } | |
| .results-icon { | |
| font-size: 5rem; | |
| margin-bottom: 20px; | |
| } | |
| .results-title { | |
| font-size: 2rem; | |
| margin-bottom: 10px; | |
| font-weight: 700; | |
| } | |
| .results-score { | |
| font-family: 'Space Mono', monospace; | |
| font-size: 3rem; | |
| font-weight: 700; | |
| color: var(--accent-primary); | |
| margin: 20px 0; | |
| } | |
| .results-message { | |
| color: var(--text-secondary); | |
| margin-bottom: 30px; | |
| } | |
| /* Responsive */ | |
| @media (max-width: 768px) { | |
| header { | |
| flex-direction: column; | |
| gap: 20px; | |
| text-align: center; | |
| } | |
| .game-header { | |
| flex-direction: column; | |
| align-items: stretch; | |
| } | |
| .score-display { | |
| justify-content: center; | |
| } | |
| .map-container { | |
| padding: 20px; | |
| min-height: 300px; | |
| } | |
| .options-grid { | |
| grid-template-columns: 1fr; | |
| } | |
| .results-content { | |
| padding: 30px; | |
| margin: 20px; | |
| } | |
| } | |
| /* Progress Bar */ | |
| .progress-container { | |
| width: 100%; | |
| height: 6px; | |
| background: var(--bg-secondary); | |
| border-radius: 3px; | |
| margin-bottom: 30px; | |
| overflow: hidden; | |
| } | |
| .progress-bar { | |
| height: 100%; | |
| background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary)); | |
| border-radius: 3px; | |
| transition: width 0.5s ease; | |
| } | |
| /* Hint System */ | |
| .hint-btn { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| background: transparent; | |
| border: 1px solid var(--border); | |
| color: var(--text-secondary); | |
| padding: 10px 20px; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-family: 'Outfit', sans-serif; | |
| transition: all 0.3s ease; | |
| margin-bottom: 20px; | |
| } | |
| .hint-btn:hover { | |
| border-color: var(--accent-tertiary); | |
| color: var(--accent-tertiary); | |
| } | |
| .hint-text { | |
| background: rgba(245, 158, 11, 0.1); | |
| border: 1px solid rgba(245, 158, 11, 0.3); | |
| padding: 15px; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| color: var(--accent-tertiary); | |
| display: none; | |
| } | |
| .hint-text.visible { | |
| display: block; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| /* Streak Counter */ | |
| .streak-display { | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| background: var(--bg-card); | |
| border: 1px solid var(--accent-tertiary); | |
| border-radius: 12px; | |
| padding: 10px 20px; | |
| display: none; | |
| align-items: center; | |
| gap: 10px; | |
| z-index: 100; | |
| animation: slideIn 0.3s ease; | |
| } | |
| .streak-display.active { | |
| display: flex; | |
| } | |
| @keyframes slideIn { | |
| from { transform: translateX(100px); opacity: 0; } | |
| to { transform: translateX(0); opacity: 1; } | |
| } | |
| .streak-fire { | |
| font-size: 1.5rem; | |
| } | |
| .streak-count { | |
| font-family: 'Space Mono', monospace; | |
| font-weight: 700; | |
| color: var(--accent-tertiary); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <div class="logo"> | |
| <div class="logo-icon">🌍</div> | |
| <h1>Where?</h1> | |
| </div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">Built with anycoder</a> | |
| </header> | |
| <div class="game-modes" id="gameModes"> | |
| <div class="mode-card" onclick="startGame('flags')"> | |
| <div class="mode-icon">🚩</div> | |
| <h3>Guess the Country</h3> | |
| <p>Identify countries by their flags and name as many as you can!</p> | |
| </div> | |
| <div class="mode-card" onclick="startGame('capitals')"> | |
| <div class="mode-icon">🏛️</div> | |
| <h3>Capital Cities</h3> | |
| <p>Match countries with their capital cities around the world.</p> | |
| </div> | |
| <div class="mode-card" onclick="startGame('continents')"> | |
| <div class="mode-icon">🌎</div> | |
| <h3>Continent Quiz</h3> | |
| <p>Learn which continent each country belongs to.</p> | |
| </div> | |
| <div class="mode-card" onclick="startGame('shapes')"> | |
| <div class="mode-icon">🗺️</div> | |
| <h3>Shape Challenge</h3> | |
| <p>Identify countries by their unique shapes on the map.</p> | |
| </div> | |
| </div> | |
| <div class="game-area" id="gameArea"> | |
| <div class="streak-display" id="streakDisplay"> | |
| <span class="streak-fire">🔥</span> | |
| <span class="streak-count" id="streakCount">0</span> | |
| </div> | |
| <div class="game-header"> | |
| <div class="score-display"> | |
| <div class="score-item"> | |
| <div class="score-label">Score</div> | |
| <div class="score-value" id="scoreValue">0</div> | |
| </div> | |
| <div class="score-item"> | |
| <div class="score-label">Round</div> | |
| <div class="score-value" id="roundValue">1/10</div> | |
| </div> | |
| <div class="score-item"> | |
| <div class="score-label">Best</div> | |
| <div class="score-value" id="bestScore">0</div> | |
| </div> | |
| </div> | |
| <button class="btn btn-secondary" onclick="showMenu()">← Back to Menu</button> | |
| </div> | |
| <div class="progress-container"> | |
| <div class="progress-bar" id="progressBar" style="width: 10%"></div> | |
| </div> | |
| <div class="question-text"> | |
| <h2 id="questionTitle">Which country does this flag belong to?</h2> | |
| <p id="questionSubtitle">Select the correct answer from the options below</p> | |
| </div> | |
| <div class="map-container"> | |
| <div class="country-shape" id="countryShape">🏳️</div> | |
| </div> | |
| <button class="hint-btn" id="hintBtn" onclick="showHint()"> | |
| <span>💡</span> Need a hint? (<span id="hintsLeft">2</span> left) | |
| </button> | |
| <div class="hint-text" id="hintText"></div> | |
| <div class="options-grid" id="optionsGrid"></div> | |
| <div class="controls"> | |
| <button class="btn btn-primary" id="nextBtn" onclick="nextQuestion()" style="display: none;"> | |
| Next Question → | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="results-modal" id="resultsModal"> | |
| <div class="results-content"> | |
| <div class="results-icon" id="resultsIcon">🎉</div> | |
| <h2 class="results-title" id="resultsTitle">Game Complete!</h2> | |
| <div class="results-score" id="finalScore">0/10</div> | |
| <p class="results-message" id="resultsMessage">Great job!</p> | |
| <div class="controls"> | |
| <button class="btn btn-secondary" onclick="showMenu()">Main Menu</button> | |
| <button class="btn btn-primary" onclick="restartGame()">Play Again</button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Game Data | |
| const countries = [ | |
| { name: "United States", capital: "Washington D.C.", continent: "North America", flag: "🇺🇸", shape: "🗽" }, | |
| { name: "United Kingdom", capital: "London", continent: "Europe", flag: "🇬🇧", shape: "🏰" }, | |
| { name: "France", capital: "Paris", continent: "Europe", flag: "🇫🇷", shape: "🗼" }, | |
| { name: "Germany", capital: "Berlin", continent: "Europe", flag: "🇩🇪", shape: "🏰" }, | |
| { name: "Japan", capital: "Tokyo", continent: "Asia", flag: "🇯🇵", shape: "🗻" }, | |
| { name: "China", capital: "Beijing", continent: "Asia", flag: "🇨🇳", shape: "🐉" }, | |
| { name: "India", capital: "New Delhi", continent: "Asia", flag: "🇮🇳", shape: "🏯" }, | |
| { name: "Brazil", capital: "Brasília", continent: "South America", flag: "🇧🇷", shape: "🦜" }, | |
| { name: "Argentina", capital: "Buenos Aires", continent: "South America", flag: "🇦🇷", shape: "⚽" }, | |
| { name: "Canada", capital: "Ottawa", continent: "North America", flag: "🇨🇦", shape: "🍁" }, | |
| { name: "Australia", capital: "Canberra", continent: "Oceania", flag: "🇦🇺", shape: "🦘" }, | |
| { name: "Italy", capital: "Rome", continent: "Europe", flag: "🇮🇹", shape: "🏛️" }, | |
| { name: "Spain", capital: "Madrid", continent: "Europe", flag: "🇪🇸", shape: "💃" }, | |
| { name: "Mexico", capital: "Mexico City", continent: "North America", flag: "🇲🇽", shape: "🌮" }, | |
| { name: "Russia", capital: "Moscow", continent: "Europe/Asia", flag: "🇷🇺", shape: "🧊" }, | |
| { name: "South Korea", capital: "Seoul", continent: "Asia", flag: "🇰🇷", shape: "🥢" }, | |
| { name: "South Africa", capital: "Pretoria", continent: "Africa", flag: "🇿🇦", shape: "🦁" }, | |
| { name: "Egypt", capital: "Cairo", continent: "Africa", flag: "🇪🇬", shape: "🐫" }, | |
| { name: "Nigeria", capital: "Abuja", continent: "Africa", flag: "🇳🇬", shape: "🥁" }, | |
| { name: "Turkey", capital: "Ankara", continent: "Europe/Asia", flag: "🇹🇷", shape: "🕌" }, | |
| { name: "Thailand", capital: "Bangkok", continent: "Asia", flag: "🇹🇭", shape: "🐘" }, | |
| { name: "Vietnam", capital: "Hanoi", continent: "Asia", flag: "🇻🇳", shape: "🎋" }, | |
| { name: "Greece", capital: "Athens", continent: "Europe", flag: "🇬🇷", shape: "🏛️" }, | |
| { name: "Sweden", capital: "Stockholm", continent: "Europe", flag: "🇸🇪", shape: "🏔️" }, | |
| { name: "Norway", capital: "Oslo", continent: "Europe", flag: "🇳🇴", shape: "❄️" }, | |
| { name: "Netherlands", capital: "Amsterdam", continent: "Europe", flag: "🇳🇱", shape: "🌷" }, | |
| { name: "Portugal", capital: "Lisbon", continent: "Europe", flag: "🇵🇹", shape: "⚓" }, | |
| { name: "Switzerland", capital: "Bern", continent: "Europe", flag: "🇨🇭", shape: "⏰" }, | |
| { name: "Poland", capital: "Warsaw", continent: "Europe", flag: "🇵🇱", shape: "🦅" }, | |
| { name: "Indonesia", capital: "Jakarta", continent: "Asia", flag: "🇮🇩", shape: "🦎" } | |
| ]; | |
| // Game State | |
| let currentMode = ''; | |
| let currentQuestion = 0; | |
| let score = 0; | |
| let bestScore = 0; | |
| let streak = 0; | |
| let hints = 2; | |
| let gameData = []; | |
| let answered = false; | |
| // DOM Elements | |
| const gameModes = document.getElementById('gameModes'); | |
| const gameArea = document.getElementById('gameArea'); | |
| const optionsGrid = document.getElementById('optionsGrid'); | |
| const scoreValue = document.getElementById('scoreValue'); | |
| const roundValue = document.getElementById('roundValue'); | |
| const bestScoreEl = document.getElementById('bestScore'); | |
| const progressBar = document.getElementById('progressBar'); | |
| const countryShape = document.getElementById('countryShape'); | |
| const questionTitle = document.getElementById('questionTitle'); | |
| const questionSubtitle = document.getElementById('questionSubtitle'); | |
| const nextBtn = document.getElementById('nextBtn'); | |
| const resultsModal = document.getElementById('resultsModal'); | |
| const streakDisplay = document.getElementById('streakDisplay'); | |
| const streakCount = document.getElementById('streakCount'); | |
| const hintBtn = document.getElementById('hintBtn'); | |
| const hintText = document.getElementById('hintText'); | |
| const hintsLeft = document.getElementById('hintsLeft'); | |
| // Initialize Game | |
| function startGame(mode) { | |
| currentMode = mode; | |
| currentQuestion = 0; | |
| score = 0; | |
| streak = 0; | |
| hints = 2; | |
| answered = false; | |
| // Shuffle and pick 10 questions | |
| gameData = [...countries].sort(() => Math.random() - 0.5).slice(0, 10); | |
| // Update UI | |
| gameModes.style.display = 'none'; | |
| gameArea.classList.add('active'); | |
| updateScore(); | |
| // Set hints | |
| hintsLeft.textContent = hints; | |
| hintBtn.style.display = 'flex'; | |
| hintText.classList.remove('visible'); | |
| // Load first question | |
| loadQuestion(); | |
| } | |
| function loadQuestion() { | |
| const country = gameData[currentQuestion]; | |
| answered = false; | |
| nextBtn.style.display = 'none'; | |
| hintBtn.style.display = 'flex'; | |
| hintText.classList.remove('visible'); | |
| // Update progress | |
| progressBar.style.width = ((currentQuestion + 1) / 10 * 100) + '%'; | |
| roundValue.textContent = `${currentQuestion + 1}/10`; | |
| // Set question based on mode | |
| switch(currentMode) { | |
| case 'flags': | |
| questionTitle.textContent = 'Which country does this flag belong to?'; | |
| questionSubtitle.textContent = 'Look at the flag and choose the correct country'; | |
| countryShape.textContent = country.flag; | |
| break; | |
| case 'capitals': | |
| questionTitle.textContent = `What is the capital of ${country.name}?`; | |
| questionSubtitle.textContent = 'Select the correct capital city'; | |
| countryShape.textContent = '🏛️'; | |
| break; | |
| case 'continents': | |
| questionTitle.textContent = `Which continent is ${country.name} in?`; | |
| questionSubtitle.textContent = 'Select the correct continent'; | |
| countryShape.textContent = country.flag; | |
| break; | |
| case 'shapes': | |
| questionTitle.textContent = 'Which country is this?'; | |
| questionSubtitle.textContent = 'Identify the country by its shape'; | |
| countryShape.textContent = country.shape; | |
| break; | |
| } | |
| // Generate options | |
| generateOptions(country); | |
| } | |
| function generateOptions(correct) { | |
| // Get 3 wrong answers | |
| let wrong = countries | |
| .filter(c => c.name !== correct.name) | |
| .sort(() => Math.random() - 0.5) | |
| .slice(0, 3); | |
| let options = [correct, ...wrong].sort(() => Math.random() - 0.5); | |
| optionsGrid.innerHTML = ''; | |
| options.forEach(option => { | |
| const btn = document.createElement('button'); | |
| btn.className = 'option-btn'; | |
| let displayText = ''; | |
| let icon = ''; | |
| switch(currentMode) { | |
| case 'flags': | |
| displayText = option.name; | |
| icon = option.flag; | |
| break; | |
| case 'capitals': | |
| displayText = option.capital; | |
| icon = '🏛️'; | |
| break; | |
| case 'continents': | |
| displayText = option.continent; | |
| icon = '🌍'; | |
| break; | |
| case 'shapes': | |
| displayText = option.name; | |
| icon = option.flag; | |
| break; | |
| } | |
| btn.innerHTML = `<span class="option-flag">${icon}</span> ${displayText}`; | |
| btn.onclick = () => checkAnswer(option, btn); | |
| optionsGrid.appendChild(btn); | |
| }); | |
| } | |
| function checkAnswer(selected, btn) { | |
| if (answered) return; | |
| answered = true; | |
| const correct = gameData[currentQuestion]; | |
| const isCorrect = selected.name === correct.name || | |
| (currentMode === 'capitals' && selected.capital === correct.capital) || | |
| (currentMode === 'continents' && selected.continent === correct.continent); | |
| // Disable all buttons | |
| const allBtns = optionsGrid.querySelectorAll('.option-btn'); | |
| allBtns.forEach(b => b.disabled = true); | |
| if (isCorrect) { | |
| btn.classList.add('correct'); | |
| score += 10; | |
| streak++; | |
| updateScore(); | |
| // Show streak | |
| if (streak >= 3) { | |
| streakDisplay.classList.add('active'); | |
| streakCount.textContent = streak; | |
| score += streak; // Bonus points for streak | |
| } | |
| } else { | |
| btn.classList.add('wrong'); | |
| streak = 0; | |
| streakDisplay.classList.remove('active'); | |
| // Highlight correct answer | |
| allBtns.forEach(b => { | |
| const text = b.textContent; | |
| if (text.includes(correct.name) || | |
| (currentMode === 'capitals' && text.includes(correct.capital)) || | |
| (currentMode === 'continents' && text.includes(correct.continent))) { | |
| b.classList.add('correct'); | |
| } | |
| }); | |
| } | |
| updateScore(); | |
| nextBtn.style.display = 'inline-block'; | |
| hintBtn.style.display = 'none'; | |
| } | |
| function updateScore() { | |
| scoreValue.textContent = score; | |
| if (score > bestScore) { | |
| bestScore = score; | |
| } | |
| bestScoreEl.textContent = bestScore; | |
| } | |
| function showHint() { | |
| if (hints <= 0 || answered) return; | |
| hints--; | |
| hintsLeft.textContent = hints; | |
| const country = gameData[currentQuestion]; | |
| let hint = ''; | |
| switch(currentMode) { | |
| case 'flags': | |
| hint = `The capital city is ${country.capital}`; | |
| break; | |
| case 'capitals': | |
| hint = `This country is in ${country.continent}`; | |
| break; | |
| case 'continents': | |
| hint = `The capital city is ${country.capital}`; | |
| break; | |
| case 'shapes': | |
| hint = `This country's capital is ${country.capital}`; | |
| break; | |
| } | |
| hintText.textContent = hint; | |
| hintText.classList.add('visible'); | |
| if (hints <= 0) { | |
| hintBtn.style.display = 'none'; | |
| } | |
| } | |
| function nextQuestion() { | |
| currentQuestion++; | |
| if (currentQuestion >= 10) { | |
| showResults(); | |
| } else { | |
| loadQuestion(); | |
| } | |
| } | |
| function showResults() { | |
| const percentage = (score / 100) * 100; | |
| let icon, title, message; | |
| if (percentage >= 80) { | |
| icon = '🏆'; | |
| title = 'Outstanding!'; | |
| message = 'You\'re a geography genius!'; | |
| } else if (percentage >= 60) { | |
| icon = '🌟'; | |
| title = 'Great Job!'; | |
| message = 'You know your way around the world!'; | |
| } else if (percentage >= 40) { | |
| icon = '👍'; | |
| title = 'Good Effort!'; | |
| message = 'Keep exploring the world!'; | |
| } else { | |
| icon = '📚'; | |
| title = 'Keep Learning!'; | |
| message = 'Practice makes perfect!'; | |
| } | |
| document.getElementById('resultsIcon').textContent = icon; | |
| document.getElementById('resultsTitle').textContent = title; | |
| document.getElementById('finalScore').textContent = `${score}/100`; | |
| document.getElementById('resultsMessage').textContent = message; | |
| resultsModal.classList.add('active'); | |
| } | |
| function showMenu() { | |
| gameModes.style.display = 'grid'; | |
| gameArea.classList.remove('active'); | |
| resultsModal.classList.remove('active'); | |
| streakDisplay.classList.remove('active'); | |
| } | |
| function restartGame() { | |
| resultsModal.classList.remove('active'); | |
| startGame(currentMode); | |
| } | |
| // Save best score to localStorage | |
| window.onload = () => { | |
| const saved = localStorage.getItem('whereGameBestScore'); | |
| if (saved) { | |
| bestScore = parseInt(saved); | |
| bestScoreEl.textContent = bestScore; | |
| } | |
| }; | |
| // Update localStorage when best score changes | |
| const originalUpdateScore = updateScore; | |
| updateScore = function() { | |
| originalUpdateScore(); | |
| if (score > bestScore) { | |
| localStorage.setItem('whereGameBestScore', bestScore); | |
| } | |
| }; | |
| </script> | |
| </body> | |
| </html> |