og-chaos
v0.0.5
Published
Algoritmo que analiza los incidents de un partido de fútbol y calcula el **marcador limpio** — el resultado que habría existido sin goles caóticos — junto con una serie de indicadores sobre el impacto del caos en el partido.
Readme
analyzeMatch
Algoritmo que analiza los incidents de un partido de fútbol y calcula el marcador limpio — el resultado que habría existido sin goles caóticos — junto con una serie de indicadores sobre el impacto del caos en el partido.
Instalación
const { analyzeMatch } = require('./analyzeMatch.js');Uso
const { analyzeMatch } = require('./analyzeMatch.js');
const data = require('./incidentes.json');
const result = analyzeMatch(data);
console.log(result);Definiciones
Gol limpio
Un gol que cumple ambas condiciones:
incidentType === "goal"
incidentClass === "regular"Gol no limpio
Cualquier gol que no sea incidentClass: "regular":
| incidentClass | Descripción |
|---|---|
| penalty | Gol de penal |
| ownGoal | Autogol |
Regla del autogol
isHome en un ownGoal indica quién lo cometió, y el gol cuenta para el equipo contrario:
| isHome | Lo cometió | Cuenta para |
|---|---|---|
| false | Local | Visitante |
| true | Visitante | Local |
Respuesta
{
"realScore": {
"home": 2,
"away": 2,
"result": "draw"
},
"cleanScore": {
"home": 1,
"away": 0,
"result": "home"
},
"resultChanged": true,
"chaosIndex": 75,
"dirtyGoalsCount": {
"total": 3,
"benefitsHome": 2,
"benefitsAway": 1
},
"mostBenefited": "away",
"dirtyGoals": [...],
"cleanGoals": [...],
"penaltiesFromCards": {...}
}Campos
realScore
Marcador final del partido, leído del periodo FT. Si no existe, se toma del último gol ordenado cronológicamente.
| Campo | Tipo | Descripción |
|---|---|---|
| home | number | Goles del local |
| away | number | Goles del visitante |
| result | string | "home" | "away" | "draw" |
cleanScore
Marcador que habría existido contando solo goles limpios (incidentClass: "regular").
| Campo | Tipo | Descripción |
|---|---|---|
| home | number | Goles limpios del local |
| away | number | Goles limpios del visitante |
| result | string | "home" | "away" | "draw" |
resultChanged
boolean — indica si el marcador limpio habría producido un resultado diferente al real.
realScore: 2-2 draw
cleanScore: 1-0 home
resultChanged: true ✓ el caos cambió el ganadorchaosIndex
Porcentaje de goles no limpios sobre el total de goles del partido.
3 goles no limpios / 4 totales = 75%| Rango | Interpretación | |---|---| | 0% | Partido sin caos | | 1–33% | Caos bajo | | 34–66% | Caos moderado | | 67–100% | Partido muy caótico |
dirtyGoalsCount
Conteo de goles no limpios por equipo beneficiado (no por quién los cometió).
| Campo | Tipo | Descripción |
|---|---|---|
| total | number | Total de goles no limpios |
| benefitsHome | number | Goles no limpios que sumaron al local |
| benefitsAway | number | Goles no limpios que sumaron al visitante |
mostBenefited
Equipo que más mejoró su situación gracias al caos, comparando el marcador limpio (escenario base) con el marcador real.
Se calcula como la diferencia de goles aportados por el caos a cada equipo:
chaosGainHome = realHome - cleanHome → 2 - 1 = +1
chaosGainAway = realAway - cleanAway → 2 - 0 = +2
mostBenefited: "away" ← el visitante ganó 2 goles del caos vs 1 del local| Valor | Descripción |
|---|---|
| "home" | El local se benefició más |
| "away" | El visitante se benefició más |
| "both" | Ambos se beneficiaron por igual |
| "none" | Sin goles no limpios |
dirtyGoals
Array con el detalle de cada gol no limpio, ordenado cronológicamente.
{
"minute": 61,
"addedTime": null,
"player": "Bruno Fernandes",
"type": "penalty",
"committedBy": "away",
"benefitsTeam": "away",
"score": { "home": 0, "away": 1 }
}| Campo | Tipo | Descripción |
|---|---|---|
| minute | number | Minuto del gol |
| addedTime | number \| null | Tiempo añadido, si aplica |
| player | string \| null | Jugador que lo ejecutó o cometió |
| type | string | "penalty" | "ownGoal" |
| committedBy | string | Equipo que lo ejecutó/cometió ("home" | "away") |
| benefitsTeam | string | Equipo que recibió el gol ("home" | "away") |
| score | object | Marcador tras el gol |
En un
ownGoal,committedByybenefitsTeamson siempre equipos opuestos.
cleanGoals
Array con el detalle de cada gol limpio (incidentClass: "regular"), ordenado cronológicamente.
{
"minute": 67,
"addedTime": null,
"player": "Ryan Christie",
"team": "home",
"score": { "home": 1, "away": 1 }
}| Campo | Tipo | Descripción |
|---|---|---|
| minute | number | Minuto del gol |
| addedTime | number \| null | Tiempo añadido, si aplica |
| player | string \| null | Jugador que anotó |
| team | string | Equipo que anotó ("home" | "away") |
| score | object | Marcador tras el gol |
penaltiesFromCards
Indicador que detecta penales convertidos que fueron precedidos por una tarjeta del equipo contrario dentro de una ventana de 5 minutos.
Reglas:
- Solo penales convertidos (
incidentType: "goal"+incidentClass: "penalty") - La tarjeta debe ser del equipo contrario al ejecutor del penal
- Ventana de tiempo: entre
minuto_penal - 5yminuto_penal - Tipos de tarjeta válidos:
red,yellow,yellowRed
{
"total": 2,
"triggeredByCard": 2,
"detail": [
{
"minute": 81,
"addedTime": null,
"player": "Eli Junior Kroupi",
"executedBy": "home",
"benefitsTeam": "home",
"score": { "home": 2, "away": 2 },
"triggeredByCard": {
"minute": 78,
"addedTime": null,
"player": "Harry Maguire",
"cardType": "red",
"reason": "Professional foul last man",
"sanctionedTeam": "away"
}
},
{
"minute": 61,
"addedTime": null,
"player": "Bruno Fernandes",
"executedBy": "away",
"benefitsTeam": "away",
"score": { "home": 0, "away": 1 },
"triggeredByCard": {
"minute": 59,
"addedTime": null,
"player": "Álex Jiménez",
"cardType": "yellow",
"reason": "Foul",
"sanctionedTeam": "home"
}
}
]
}| Campo | Tipo | Descripción |
|---|---|---|
| total | number | Total de penales convertidos en el partido |
| triggeredByCard | number | Penales con tarjeta previa detectada |
| detail | array | Detalle de cada penal |
| detail[].triggeredByCard | object \| null | Tarjeta vinculada, o null si no hubo |
| detail[].triggeredByCard.cardType | string | "red" | "yellow" | "yellowRed" |
| detail[].triggeredByCard.reason | string \| null | Motivo de la tarjeta |
| detail[].triggeredByCard.sanctionedTeam | string | Equipo sancionado ("home" | "away") |
