Skip to content

Instantly share code, notes, and snippets.

@fernandezmm
Created November 12, 2025 02:48
Show Gist options
  • Save fernandezmm/dfe0e4864b076dbb3cca8bebe3c4fee5 to your computer and use it in GitHub Desktop.
Save fernandezmm/dfe0e4864b076dbb3cca8bebe3c4fee5 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculadora Grupo A</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
margin: 20px;
background-color: #f9f9f9;
color: #333;
}
.container {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 30px;
max-width: 1200px;
margin: auto;
}
@media (max-width: 900px) {
.container {
grid-template-columns: 1fr;
}
}
h2 {
border-bottom: 2px solid #007bff;
padding-bottom: 5px;
color: #007bff;
}
table {
width: 100%;
border-collapse: collapse;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
background-color: #fff;
}
th, td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
th {
background-color: #f2f2f2;
font-size: 0.9em;
text-transform: uppercase;
}
td:first-child, th:first-child {
text-align: center;
font-weight: bold;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
.match {
display: grid;
grid-template-columns: 1fr 50px 20px 50px 1fr;
gap: 5px;
align-items: center;
margin-bottom: 12px;
background-color: #fff;
padding: 10px;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.match-label {
font-size: 0.95em;
}
.home-label { text-align: right; }
.away-label { text-align: left; }
.match input {
width: 100%;
height: 30px;
text-align: center;
font-size: 1.1em;
font-weight: bold;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box; /* Importante para que el padding no afecte el width */
}
.separator {
text-align: center;
font-weight: bold;
color: #888;
}
#calculateBtn {
width: 100%;
padding: 12px;
font-size: 1.2em;
font-weight: bold;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-top: 10px;
transition: background-color 0.2s;
}
#calculateBtn:hover {
background-color: #218838;
}
</style>
</head>
<body>
<div class="container">
<div id="matches-simulator">
<h2>Simular Resultados</h2>
<p>Ingresa los goles de los partidos relevantes del Grupo A.</p>
<div id="matchesContainer">
</div>
<button id="calculateBtn">Calcular Tabla</button>
</div>
<div id="standings">
<h2>Tabla de Posiciones</h2>
<div id="standingsContainer">
</div>
</div>
</div>
<script>
// --- 1. DATOS INICIALES (BASADOS EN TU TABLA) ---
// (Tomamos tu tabla como el punto de partida)
const initialData = [
{ pos: 1, name: "Boca Jrs.", pts: 26, pj: 15, g: 7, e: 5, p: 3, gf: 26, gc: 12, dg: 14 },
{ pos: 2, name: "Unión", pts: 24, pj: 15, g: 6, e: 6, p: 3, gf: 20, gc: 13, dg: 7 },
{ pos: 3, name: "Central Córdoba", pts: 23, pj: 15, g: 5, e: 8, p: 2, gf: 16, gc: 10, dg: 6 },
{ pos: 4, name: "Tigre", pts: 22, pj: 15, g: 5, e: 7, p: 3, gf: 14, gc: 11, dg: 3 },
{ pos: 5, name: "Barracas", pts: 22, pj: 15, g: 5, e: 7, p: 3, gf: 18, gc: 16, dg: 2 },
{ pos: 6, name: "Racing", pts: 22, pj: 15, g: 6, e: 4, p: 5, gf: 15, gc: 13, dg: 2 },
{ pos: 7, name: "Argentinos Jrs.", pts: 21, pj: 15, g: 6, e: 3, p: 6, gf: 16, gc: 12, dg: 4 },
{ pos: 8, name: "Estudiantes", pts: 21, pj: 15, g: 6, e: 3, p: 6, gf: 16, gc: 16, dg: 0 },
{ pos: 9, name: "Banfield", pts: 20, pj: 15, g: 6, e: 2, p: 7, gf: 14, gc: 20, dg: -6 },
{ pos: 10, name: "Belgrano", pts: 19, pj: 15, g: 4, e: 7, p: 4, gf: 13, gc: 11, dg: 2 },
{ pos: 11, name: "Defensa", pts: 19, pj: 15, g: 5, e: 4, p: 6, gf: 14, gc: 17, dg: -3 },
{ pos: 12, name: "Huracán", pts: 19, pj: 15, g: 5, e: 4, p: 6, gf: 9, gc: 14, dg: -5 },
{ pos: 13, name: "Aldosivi", pts: 15, pj: 15, g: 4, e: 3, p: 8, gf: 9, gc: 16, dg: -7 },
{ pos: 14, name: "Newell's", pts: 14, pj: 15, g: 3, e: 5, p: 7, gf: 13, gc: 22, dg: -9 },
{ pos: 15, name: "Ind. Rivadavia Mza", pts: 13, pj: 15, g: 2, e: 7, p: 6, gf: 12, gc: 17, dg: -5 }
];
// --- 2. PARTIDOS A SIMULAR (FILTRADOS DE TU LISTA) ---
// (Solo los que involucran a equipos del Grupo A)
const matches = [
{ home: "Boca Jrs.", away: "Tigre" },
{ home: "Central Córdoba", away: "Banfield" },
{ home: "Estudiantes", away: "Argentinos Jrs." },
{ home: "Newell's", away: "Racing" },
{ home: "Barracas", away: "Huracán" },
{ home: "Belgrano", away: "Unión" },
{ home: "Defensa", away: "Ind. Rivadavia Mza" },
{ home: "Aldosivi", away: "San Martín SJ" } // "San Martín SJ" no está en la tabla, solo se actualizará Aldosivi.
];
// --- 3. FUNCIONES DE LA CALCULADORA ---
/**
* Renderiza la tabla de posiciones en el HTML
*/
function renderStandings(teamData) {
const container = document.getElementById('standingsContainer');
let html = '<table>';
html += '<tr><th>Pos.</th><th>Equipo</th><th>PTS</th><th>PJ</th><th>G</th><th>E</th><th>P</th><th>GF</th><th>GC</th><th>DG</th></tr>';
teamData.forEach(team => {
html += `
<tr>
<td>${team.pos}</td>
<td>${team.name}</td>
<td><strong>${team.pts}</strong></td>
<td>${team.pj}</td>
<td>${team.g}</td>
<td>${team.e}</td>
<td>${team.p}</td>
<td>${team.gf}</td>
<td>${team.gc}</td>
<td>${team.dg}</td>
</tr>
`;
});
html += '</table>';
container.innerHTML = html;
}
/**
* Renderiza los inputs para los partidos
*/
function renderMatches() {
const container = document.getElementById('matchesContainer');
let html = '';
matches.forEach((match, index) => {
html += `
<div class="match">
<label class="match-label home-label" for="home_${index}">${match.home}</label>
<input type="number" id="home_${index}" min="0" max="99">
<span class="separator">-</span>
<input type="number" id="away_${index}" min="0" max="99">
<label class="match-label away-label" for="away_${index}">${match.away}</label>
</div>
`;
});
container.innerHTML = html;
}
/**
* Calcula los nuevos stats basado en los inputs
*/
function calculateResults() {
// 1. Crea una copia profunda de los datos iniciales para no modificar el original
let calculatedData = JSON.parse(JSON.stringify(initialData));
// 2. Itera sobre cada partido
matches.forEach((match, index) => {
const homeScoreEl = document.getElementById(`home_${index}`);
const awayScoreEl = document.getElementById(`away_${index}`);
// Si los inputs están vacíos, los trata como 0
const homeScore = parseInt(homeScoreEl.value || 0);
const awayScore = parseInt(awayScoreEl.value || 0);
// Solo procesa si se ingresó algún valor (o se cambió)
if (homeScoreEl.value !== "" || awayScoreEl.value !== "") {
// 3. Busca los equipos en nuestros datos
let homeTeam = calculatedData.find(t => t.name === match.home);
let awayTeam = calculatedData.find(t => t.name === match.away); // Puede ser undefined (ej: San Martín SJ)
// 4. Actualiza stats del equipo LOCAL (si existe en la tabla)
if (homeTeam) {
homeTeam.pj++;
homeTeam.gf += homeScore;
homeTeam.gc += awayScore;
if (homeScore > awayScore) { // Gana Local
homeTeam.pts += 3;
homeTeam.g++;
} else if (homeScore === awayScore) { // Empate
homeTeam.pts += 1;
homeTeam.e++;
} else { // Pierde Local
homeTeam.p++;
}
}
// 5. Actualiza stats del equipo VISITANTE (si existe en la tabla)
if (awayTeam) {
awayTeam.pj++;
awayTeam.gf += awayScore;
awayTeam.gc += homeScore;
if (awayScore > homeScore) { // Gana Visitante
awayTeam.pts += 3;
awayTeam.g++;
} else if (homeScore === awayScore) { // Empate
awayTeam.pts += 1;
awayTeam.e++;
} else { // Pierde Visitante
awayTeam.p++;
}
}
}
});
// 6. Recalcula la Diferencia de Gol (DG) para todos
calculatedData.forEach(team => {
team.dg = team.gf - team.gc;
});
// 7. Ordena la tabla
calculatedData.sort((a, b) => {
if (b.pts !== a.pts) return b.pts - a.pts; // 1. Por Puntos (desc)
if (b.dg !== a.dg) return b.dg - a.dg; // 2. Por Dif. Gol (desc)
if (b.gf !== a.gf) return b.gf - a.gf; // 3. Por Goles a Favor (desc)
return a.name.localeCompare(b.name); // 4. Alfabético (asc)
});
// 8. Asigna las nuevas posiciones
calculatedData.forEach((team, index) => {
team.pos = index + 1;
});
// 9. Renderiza la tabla actualizada
renderStandings(calculatedData);
}
// --- 4. INICIALIZACIÓN ---
// Espera a que el DOM esté cargado
document.addEventListener('DOMContentLoaded', () => {
renderMatches();
renderStandings(initialData); // Muestra la tabla inicial
// Asigna el evento al botón
document.getElementById('calculateBtn').addEventListener('click', calculateResults);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment