diff --git a/3-en-raya-computer/index.html b/3-en-raya-computer/index.html
index a9f40b8..ddea3cf 100644
--- a/3-en-raya-computer/index.html
+++ b/3-en-raya-computer/index.html
@@ -3,12 +3,27 @@
-
Estoy pensando en un número entre 1 y 100.
-
¿Puedes adivinarlo en 7 intentos?
-
-
-
-
+
¡Adivina el número!
+
+
Estoy pensando en un número entre 1 y 100.
+
¿Puedes adivinarlo en 7 intentos?
+
+
+
+
+
+
+
+
+
+
+
+
+
Intentos restantes: 7
+
Mejor marca: —
+
+
diff --git a/adivina/script.js b/adivina/script.js
index 35b91e7..e685809 100644
--- a/adivina/script.js
+++ b/adivina/script.js
@@ -1,55 +1,156 @@
-let randomNumber;
-let attemptsLeft = 7;
+'use strict';
+const DIFFICULTIES = {
+ normal: { max: 100, attempts: 7 },
+ facil: { max: 50, attempts: 10 },
+ dificil: { max: 200, attempts: 7 },
+ extremo: { max: 1000, attempts: 10 }
+};
+
+let randomNumber = 0;
+let attemptsLeft = 0;
+let attemptsTotal = 0;
+let maxNumber = 100;
+let history = [];
+let currentDifficulty = 'normal';
+
+// DOM refs
const guessInput = document.getElementById('guess-input');
const guessBtn = document.getElementById('guess-btn');
const restartBtn = document.getElementById('restart-btn');
const infoDiv = document.getElementById('info');
const attemptsSpan = document.getElementById('attempts-left');
+const difficultySelect = document.getElementById('difficulty');
+const errorDiv = document.getElementById('error');
+const rangeMaxSpan = document.getElementById('range-max');
+const attemptsTotalSpan = document.getElementById('attempts-total');
+const bestScoreSpan = document.getElementById('best-score');
+const historyList = document.getElementById('history-list');
+
+function getBest(difficulty) {
+ const key = `adivina_best_${difficulty}`;
+ const v = localStorage.getItem(key);
+ return v ? parseInt(v, 10) : null;
+}
+
+function setBest(difficulty, attemptsUsed) {
+ const prev = getBest(difficulty);
+ if (prev === null || attemptsUsed < prev) {
+ localStorage.setItem(`adivina_best_${difficulty}`, String(attemptsUsed));
+ bestScoreSpan.textContent = String(attemptsUsed);
+ }
+}
+
+function updateBestDisplay() {
+ const best = getBest(currentDifficulty);
+ bestScoreSpan.textContent = best !== null ? String(best) : '—';
+}
+
+function renderHistory() {
+ // Safe clear
+ while (historyList.firstChild) historyList.removeChild(historyList.firstChild);
+ history.forEach(item => {
+ const li = document.createElement('li');
+ li.textContent = `${item.guess} → ${item.hint}`;
+ historyList.appendChild(li);
+ });
+}
function startGame() {
- randomNumber = Math.floor(Math.random() * 100) + 1;
- attemptsLeft = 7;
- attemptsSpan.textContent = attemptsLeft;
+ currentDifficulty = (difficultySelect && difficultySelect.value) || 'normal';
+ const conf = DIFFICULTIES[currentDifficulty] || DIFFICULTIES.normal;
+
+ maxNumber = conf.max;
+ attemptsTotal = conf.attempts;
+ attemptsLeft = attemptsTotal;
+ randomNumber = Math.floor(Math.random() * maxNumber) + 1;
+ history = [];
+
+ // Update UI
+ if (rangeMaxSpan) rangeMaxSpan.textContent = String(maxNumber);
+ if (attemptsTotalSpan) attemptsTotalSpan.textContent = String(attemptsTotal);
+ attemptsSpan.textContent = String(attemptsLeft);
+ errorDiv.textContent = '';
infoDiv.textContent = '';
+ renderHistory();
+ updateBestDisplay();
+
+ // Reset input/button state
guessInput.value = '';
guessInput.disabled = false;
+ guessInput.setAttribute('min', '1');
+ guessInput.setAttribute('max', String(maxNumber));
guessBtn.disabled = false;
restartBtn.classList.add('hidden');
+ guessInput.focus();
}
function checkGuess() {
- const guess = Number(guessInput.value);
+ errorDiv.textContent = '';
- if (guess < 1 || guess > 100 || isNaN(guess)) {
- infoDiv.textContent = "Por favor ingresa un número válido entre 1 y 100.";
+ const raw = guessInput.value.trim();
+ if (raw === '') {
+ errorDiv.textContent = 'Introduce un número.';
+ return;
+ }
+
+ const guess = Number(raw);
+ if (!Number.isFinite(guess) || !Number.isInteger(guess)) {
+ errorDiv.textContent = 'El valor debe ser un número entero.';
+ return;
+ }
+ if (guess < 1 || guess > maxNumber) {
+ errorDiv.textContent = `El número debe estar entre 1 y ${maxNumber}.`;
return;
}
attemptsLeft--;
- attemptsSpan.textContent = attemptsLeft;
+ attemptsSpan.textContent = String(attemptsLeft);
if (guess === randomNumber) {
- infoDiv.textContent = "¡Correcto! 🎉 Has adivinado el número.";
- endGame(true);
- } else if (attemptsLeft === 0) {
+ infoDiv.textContent = '¡Correcto! 🎉 Has adivinado el número.';
+ const usedAttempts = attemptsTotal - attemptsLeft;
+ history.push({ guess, hint: '✅ Correcto' });
+ renderHistory();
+ endGame(true, usedAttempts);
+ return;
+ }
+
+ const hint = guess < randomNumber ? '⬇️ Bajo' : '⬆️ Alto';
+ infoDiv.textContent = guess < randomNumber
+ ? 'Demasiado bajo. Intenta nuevamente.'
+ : 'Demasiado alto. Intenta nuevamente.';
+ history.push({ guess, hint });
+ renderHistory();
+
+ if (attemptsLeft === 0) {
infoDiv.textContent = `¡Oh no! Te quedaste sin intentos. El número era ${randomNumber}.`;
- endGame(false);
- } else if (guess < randomNumber) {
- infoDiv.textContent = "Demasiado bajo. Intenta nuevamente.";
- } else {
- infoDiv.textContent = "Demasiado alto. Intenta nuevamente.";
+ endGame(false, attemptsTotal);
}
}
-function endGame(won) {
+function endGame(won, usedAttempts) {
guessInput.disabled = true;
guessBtn.disabled = true;
restartBtn.classList.remove('hidden');
+
+ if (won) {
+ setBest(currentDifficulty, usedAttempts);
+ }
}
-guessBtn.onclick = checkGuess;
-restartBtn.onclick = startGame;
-guessInput.onkeydown = (e) => { if (e.key === "Enter") checkGuess(); };
+// Listeners (avoid inline handlers)
+guessBtn.addEventListener('click', checkGuess);
+restartBtn.addEventListener('click', startGame);
+guessInput.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter') checkGuess();
+});
+guessInput.addEventListener('input', () => {
+ errorDiv.textContent = '';
+});
+if (difficultySelect) {
+ difficultySelect.addEventListener('change', startGame);
+}
+// Init
startGame();
\ No newline at end of file
diff --git a/adivina/styles.css b/adivina/styles.css
index 885cce5..d6ae7e1 100644
--- a/adivina/styles.css
+++ b/adivina/styles.css
@@ -1,43 +1,106 @@
+:root {
+ --bg: #f7f7f7;
+ --text: #222;
+ --muted: #888;
+ --card-bg: #ffffff;
+ --shadow: 0 0 8px #bbb;
+ --accent: #2196f3;
+ --accent-hover: #1769aa;
+ --accent-contrast: #ffffff;
+ --error: #c62828;
+}
+
body {
- background: #f7f7f7;
- font-family: Arial, sans-serif;
+ background: var(--bg);
+ color: var(--text);
+ font-family: 'Montserrat', Arial, sans-serif;
text-align: center;
+ margin: 0;
+ padding: 20px;
}
h1 {
- margin-top: 40px;
- color: #222;
+ margin-top: 20px;
+ color: var(--text);
+ font-weight: 700;
}
#game-box {
- background: white;
+ background: var(--card-bg);
width: 350px;
- margin: 50px auto;
+ max-width: 94vw;
+ margin: 30px auto;
padding: 30px 20px;
border-radius: 12px;
- box-shadow: 0 0 8px #bbb;
+ box-shadow: var(--shadow);
+}
+
+.input-row {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+ flex-wrap: wrap;
+ margin-bottom: 10px;
}
input[type="number"] {
- width: 100px;
+ width: 120px;
font-size: 1.1em;
- padding: 6px;
- margin-right: 12px;
+ padding: 8px 10px;
margin-bottom: 10px;
+ border: 1px solid #ddd;
+ border-radius: 8px;
+ outline: none;
+}
+
+input[type="number"]:focus-visible {
+ border-color: var(--accent);
+ box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.25);
+}
+
+select#difficulty {
+ font-size: 1em;
+ padding: 6px 10px;
+ border-radius: 8px;
+ border: 1px solid #ddd;
+ margin: 8px 0 14px 0;
}
button {
font-size: 1em;
- padding: 7px 20px;
+ padding: 9px 22px;
border: none;
- border-radius: 5px;
- background: #2196f3;
- color: white;
+ border-radius: 44px;
+ background: var(--accent);
+ color: var(--accent-contrast);
cursor: pointer;
margin-bottom: 10px;
+ transition: transform .12s, box-shadow .16s, background .16s;
}
+
button:hover {
- background: #1769aa;
+ background: var(--accent-hover);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 10px rgba(33,150,243,0.3);
+}
+
+button:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 3px rgba(33,150,243,0.35);
+}
+
+button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ transform: none;
+ box-shadow: none;
+}
+
+#error {
+ color: var(--error);
+ font-size: 0.95em;
+ min-height: 1.6em;
}
#info {
@@ -48,21 +111,93 @@ button:hover {
#attempts {
margin-top: 8px;
- color: #888;
+ color: var(--muted);
+}
+
+#best {
+ margin-top: 6px;
+ color: var(--muted);
+}
+
+#history {
+ margin-top: 16px;
+ text-align: left;
+}
+
+#history h2 {
+ font-size: 1.05em;
+ margin: 8px 0;
+ color: var(--text);
+}
+
+#history-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ max-height: 160px;
+ overflow-y: auto;
+ border-top: 1px dashed #ddd;
+ padding-top: 8px;
+}
+
+#history-list li {
+ padding: 6px 0;
+ border-bottom: 1px dashed #eee;
+ color: var(--text);
}
.hidden {
display: none;
}
+.sr-only {
+ position: absolute !important;
+ height: 1px; width: 1px;
+ overflow: hidden;
+ clip: rect(1px, 1px, 1px, 1px);
+ white-space: nowrap;
+}
+
+@media (max-width: 480px) {
+ #game-box {
+ padding: 24px 14px;
+ }
+ .input-row {
+ flex-direction: column;
+ gap: 8px;
+ }
+}
+
@media (min-width: 728px) {
- body,
- #game-box,
- input[type="number"],
- button,
- #info,
- #attempts {
- width: 95%;
- font-size: 130%;
+ #game-box { width: 450px; }
+ body { font-size: 110%; }
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --bg: #0f1222;
+ --text: #eaeaf0;
+ --muted: #a0a3b0;
+ --card-bg: #171a2e;
+ --shadow: 0 0 0 rgba(0,0,0,0);
+ --accent: #3d5afe;
+ --accent-hover: #0a2459;
+ --accent-contrast: #ffffff;
+ --error: #ef5350;
+ }
+ #game-box {
+ box-shadow: 0 6px 24px rgba(61,90,254,0.12);
+ border: 1px solid rgba(255,255,255,0.06);
+ }
+ input[type="number"], select#difficulty {
+ background: #20233a;
+ color: var(--text);
+ border-color: #2c3252;
+ }
+ #history-list {
+ border-top-color: #2c3252;
+ }
+ #history-list li {
+ border-bottom-color: #2c3252;
}
}
\ No newline at end of file
diff --git a/banderas/index.html b/banderas/index.html
index 6e146fc..891ef2c 100644
--- a/banderas/index.html
+++ b/banderas/index.html
@@ -3,18 +3,30 @@
Empareja la Bandera
+
-
Empareja la Bandera
+
Empareja la Bandera
Haz clic en una bandera y después en el país correspondiente. ¿Puedes emparejar todas?
+
+
+
+
+
+
Aciertos: /
-