'use strict'; // Lista completa con país y siglas según ISO 3166-1 alpha-2 const countryList = [ { name: "España", code: "ES" }, { name: "Francia", code: "FR" }, { name: "Alemania", code: "DE" }, { name: "Italia", code: "IT" }, { name: "Portugal", code: "PT" }, { name: "Reino Unido", code: "GB" }, { name: "Estados Unidos", code: "US" }, { name: "Canadá", code: "CA" }, { name: "México", code: "MX" }, { name: "Brasil", code: "BR" }, { name: "Argentina", code: "AR" }, { name: "Chile", code: "CL" }, { name: "Japón", code: "JP" }, { name: "China", code: "CN" }, { name: "Australia", code: "AU" }, { name: "Rusia", code: "RU" }, { name: "Sudáfrica", code: "ZA" }, { name: "Nueva Zelanda", code: "NZ" }, { name: "India", code: "IN" }, { name: "Egipto", code: "EG" }, { name: "Grecia", code: "GR" }, { name: "Turquía", code: "TR" }, { name: "Ucrania", code: "UA" }, { name: "Suecia", code: "SE" }, { name: "Noruega", code: "NO" }, { name: "Dinamarca", code: "DK" }, { name: "Finlandia", code: "FI" }, { name: "Irlanda", code: "IE" }, { name: "Bélgica", code: "BE" }, { name: "Polonia", code: "PL" }, { name: "Suiza", code: "CH" }, { name: "Países Bajos", code: "NL" } ]; function getFlagEmoji(code) { // Las banderas se generan a partir de letras usando unicode, no por siglas textuales // Solo funcionan para países con código alpha-2 y script latino if (!code || code.length !== 2) return ''; return String.fromCodePoint( ...code.toUpperCase().split('').map(c => 0x1F1E6 + c.charCodeAt(0) - 65) ); } // Elegir N países aleatorios distintos con bandera, sin mutar la lista original function pickRandomCountries(list, n) { const pool = list.slice(); // copia de seguridad const chosen = []; const used = new Set(); while (chosen.length < n && pool.length > 0) { const idx = Math.floor(Math.random() * pool.length); const c = pool[idx]; const flag = getFlagEmoji(c.code); if (flag && !used.has(c.code)) { chosen.push({ name: c.name, code: c.code, flag }); used.add(c.code); } // Eliminar del pool para evitar repetir pool.splice(idx, 1); } return chosen; } // Referencias DOM const flagsDiv = document.getElementById('flags'); const countriesDiv = document.getElementById('countries'); const statusDiv = document.getElementById('status'); const scoreSpan = document.getElementById('score-value'); const scoreTotal = document.getElementById('score-total'); const restartBtn = document.getElementById('restart-btn'); const pairsSelect = document.getElementById('pairs-count'); // Estado let pairs = []; let flags = []; let countries = []; let selectedFlag = null; let selectedCountry = null; let score = 0; let totalPairs = 12; // Utilidades function shuffle(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } } function setStatus(msg) { statusDiv.textContent = msg; } // Renderizado function renderFlags() { // Limpieza segura flagsDiv.textContent = ''; flags.forEach((p, i) => { const d = document.createElement('button'); d.type = 'button'; d.className = 'flag'; d.textContent = p.flag; // seguro (caracter unicode) d.setAttribute('tabindex', '0'); d.setAttribute('role', 'listitem'); d.setAttribute('aria-label', `Bandera de ${p.name}`); d.setAttribute('aria-disabled', p.matched ? 'true' : 'false'); d.setAttribute('aria-selected', selectedFlag === i ? 'true' : 'false'); if (p.matched) d.classList.add('matched'); if (selectedFlag === i) d.classList.add('selected'); d.addEventListener('click', () => selectFlag(i)); d.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); selectFlag(i); } }); flagsDiv.appendChild(d); }); } function renderCountries() { countriesDiv.textContent = ''; countries.forEach((p, i) => { const d = document.createElement('button'); d.type = 'button'; d.className = 'country'; d.textContent = p.name; // seguro d.setAttribute('tabindex', '0'); d.setAttribute('role', 'listitem'); d.setAttribute('aria-label', `País ${p.name}`); d.setAttribute('aria-disabled', p.matched ? 'true' : 'false'); d.setAttribute('aria-selected', selectedCountry === i ? 'true' : 'false'); if (p.matched) d.classList.add('matched'); if (selectedCountry === i) d.classList.add('selected'); d.addEventListener('click', () => selectCountry(i)); d.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); selectCountry(i); } }); countriesDiv.appendChild(d); }); } // Lógica selección function selectFlag(i) { if (flags[i].matched) return; selectedFlag = i; renderFlags(); if (selectedCountry !== null) checkMatch(); } function selectCountry(i) { if (countries[i].matched) return; selectedCountry = i; renderCountries(); if (selectedFlag !== null) checkMatch(); } function checkMatch() { if (selectedFlag === null || selectedCountry === null) return; const flagObj = flags[selectedFlag]; const countryObj = countries[selectedCountry]; if (!flagObj || !countryObj) return; if (flagObj.code === countryObj.code) { flags[selectedFlag].matched = true; countries[selectedCountry].matched = true; score++; scoreSpan.textContent = String(score); setStatus('¡Correcto!'); renderFlags(); renderCountries(); if (score === pairs.length) { setStatus('¡Has emparejado todas las banderas! 🎉'); } } else { setStatus('No es correcto, intenta otra vez.'); // Reset de selección tras breve pausa setTimeout(() => { setStatus(''); selectedFlag = null; selectedCountry = null; renderFlags(); renderCountries(); }, 850); return; } // Reset selección tras acierto selectedFlag = null; selectedCountry = null; } // Inicio/reinicio function startGame() { // Leer número de parejas desde selector, con límites const desired = pairsSelect && Number(pairsSelect.value) ? Number(pairsSelect.value) : 12; totalPairs = Math.max(4, Math.min(desired, countryList.length)); const fullList = countryList.slice(); // copia pairs = pickRandomCountries(fullList, totalPairs); // Si no se pudieron escoger las deseadas (por restricciones), ajustar total if (pairs.length < totalPairs) { totalPairs = pairs.length; } flags = pairs.map(o => ({ ...o })); countries = pairs.map(o => ({ ...o })); shuffle(flags); shuffle(countries); score = 0; scoreSpan.textContent = String(score); scoreTotal.textContent = String(pairs.length); selectedFlag = null; selectedCountry = null; renderFlags(); renderCountries(); setStatus('Empareja todas las banderas con su país'); // Enfocar primera bandera para accesibilidad const firstFlag = flagsDiv.querySelector('.flag'); if (firstFlag) firstFlag.focus(); } // Listeners (evitar handlers inline) restartBtn.addEventListener('click', startGame); if (pairsSelect) { pairsSelect.addEventListener('change', startGame); } // Init startGame();