151 lines
4.4 KiB
JavaScript
151 lines
4.4 KiB
JavaScript
'use strict';
|
|
|
|
const userScoreSpan = document.getElementById('user-score');
|
|
const computerScoreSpan = document.getElementById('computer-score');
|
|
const resultDiv = document.getElementById('result');
|
|
const choiceButtons = document.querySelectorAll('#choices button');
|
|
const resetBtn = document.getElementById('reset-btn');
|
|
|
|
const bestSelect = document.getElementById('best-of');
|
|
const roundSpan = document.getElementById('round');
|
|
const roundsTotalSpan = document.getElementById('rounds-total');
|
|
|
|
const choices = ['piedra', 'papel', 'tijera'];
|
|
|
|
let userScore = 0;
|
|
let computerScore = 0;
|
|
let roundNumber = 1;
|
|
let bestOf = 3;
|
|
let targetWins = 2;
|
|
let gameOver = false;
|
|
|
|
function computerPlay() {
|
|
const idx = Math.floor(Math.random() * choices.length);
|
|
return choices[idx];
|
|
}
|
|
|
|
function emoji(choice) {
|
|
if (choice === 'piedra') return '🪨';
|
|
if (choice === 'papel') return '📄';
|
|
if (choice === 'tijera') return '✂️';
|
|
return '';
|
|
}
|
|
|
|
function capitalize(word) {
|
|
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
}
|
|
|
|
function updateHUD() {
|
|
if (userScoreSpan) userScoreSpan.textContent = String(userScore);
|
|
if (computerScoreSpan) computerScoreSpan.textContent = String(computerScore);
|
|
if (roundSpan) roundSpan.textContent = String(roundNumber);
|
|
if (roundsTotalSpan) roundsTotalSpan.textContent = String(bestOf);
|
|
}
|
|
|
|
function setBestOf() {
|
|
const v = bestSelect && bestSelect.value ? parseInt(bestSelect.value, 10) : 3;
|
|
bestOf = Number.isInteger(v) ? Math.max(1, Math.min(v, 9)) : 3;
|
|
targetWins = Math.floor(bestOf / 2) + 1;
|
|
roundsTotalSpan.textContent = String(bestOf);
|
|
resetGame(); // reinicia con la nueva configuración
|
|
}
|
|
|
|
function endMatchIfNeeded() {
|
|
// Fin anticipado si alguien alcanza las victorias necesarias
|
|
if (userScore >= targetWins) {
|
|
gameOver = true;
|
|
resultDiv.textContent = `Has ganado la partida ${userScore}-${computerScore} (mejor de ${bestOf}). 🎉`;
|
|
return true;
|
|
}
|
|
if (computerScore >= targetWins) {
|
|
gameOver = true;
|
|
resultDiv.textContent = `La máquina gana la partida ${computerScore}-${userScore} (mejor de ${bestOf}). 🤖`;
|
|
return true;
|
|
}
|
|
// Fin por alcanzar el número máximo de rondas
|
|
if (roundNumber > bestOf) {
|
|
gameOver = true;
|
|
if (userScore > computerScore) {
|
|
resultDiv.textContent = `Has ganado la partida ${userScore}-${computerScore} (mejor de ${bestOf}). 🎉`;
|
|
} else if (computerScore > userScore) {
|
|
resultDiv.textContent = `La máquina gana la partida ${computerScore}-${userScore} (mejor de ${bestOf}). 🤖`;
|
|
} else {
|
|
resultDiv.textContent = `Empate global ${userScore}-${computerScore} (mejor de ${bestOf}).`;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function playRound(userChoice) {
|
|
if (gameOver) return;
|
|
|
|
const computerChoice = computerPlay();
|
|
|
|
let msg = `Tu elección: ${emoji(userChoice)} ${capitalize(userChoice)}\n` +
|
|
`Máquina: ${emoji(computerChoice)} ${capitalize(computerChoice)}\n`;
|
|
|
|
if (userChoice === computerChoice) {
|
|
msg += 'Resultado: ¡Empate!';
|
|
// Empate cuenta como ronda consumida
|
|
roundNumber += 1;
|
|
} else if (
|
|
(userChoice === 'piedra' && computerChoice === 'tijera') ||
|
|
(userChoice === 'papel' && computerChoice === 'piedra') ||
|
|
(userChoice === 'tijera' && computerChoice === 'papel')
|
|
) {
|
|
userScore += 1;
|
|
msg += 'Resultado: ¡Ganaste esta ronda! 🎉';
|
|
// Avanza ronda tras cada ronda jugada
|
|
roundNumber += 1;
|
|
} else {
|
|
computerScore += 1;
|
|
msg += 'Resultado: La máquina gana esta ronda.';
|
|
roundNumber += 1;
|
|
}
|
|
|
|
// Mostrar resultado de la ronda (usamos textContent para evitar HTML)
|
|
resultDiv.textContent = msg;
|
|
|
|
updateHUD();
|
|
|
|
// Comprobar fin anticipado o por límite de rondas
|
|
if (endMatchIfNeeded()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
function handleChoice(choice) {
|
|
playRound(choice);
|
|
}
|
|
|
|
function resetGame() {
|
|
userScore = 0;
|
|
computerScore = 0;
|
|
roundNumber = 1;
|
|
gameOver = false;
|
|
resultDiv.textContent = '';
|
|
updateHUD();
|
|
}
|
|
|
|
// Listeners (evitar handlers inline)
|
|
choiceButtons.forEach((btn) => {
|
|
btn.addEventListener('click', () => handleChoice(btn.getAttribute('data-choice')));
|
|
// Accesibilidad extra: Enter y Espacio activan el botón
|
|
btn.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
e.preventDefault();
|
|
handleChoice(btn.getAttribute('data-choice'));
|
|
}
|
|
});
|
|
});
|
|
|
|
resetBtn.addEventListener('click', resetGame);
|
|
|
|
if (bestSelect) {
|
|
bestSelect.addEventListener('change', setBestOf);
|
|
}
|
|
|
|
// Init
|
|
setBestOf();
|
|
updateHUD(); |