Calculer les scores d'une ligue fantasy MotoGP
Transformez les résultats de course en points fantasy avec vos propres règles de score, et classez les équipes de votre ligue après chaque manche.
10 min de lecture
Les jeux fantasy comptent parmi les meilleurs usages des données de course : les joueurs choisissent des pilotes, et chaque résultat fait bouger le classement de la ligue. Ce guide calcule les scores d’une ligue en JavaScript avec des règles que vous maîtrisez.
Les règles
Chaque équipe fantasy choisit trois pilotes. Après chaque manche, chaque pilote gagne :
| Événement | Points fantasy |
|---|---|
| Points de championnat marqués en course | 1 par point |
| Victoire | +10 de bonus |
| Podium (P1–P3) | +5 de bonus |
| Abandon | −5 |
Gardez les règles sous forme de données, pas de code, pour pouvoir les ajuster entre les saisons.
// scoring.js
export const RULES = Object.freeze({
perPoint: 1,
win: 10,
podium: 5,
dnf: -5,
});
/** Fantasy points for one rider's race result. Pure: same input, same output. */
export function scoreResult(result, rules = RULES) {
let score = result.points * rules.perPoint;
if (result.status === "FINISHED") {
if (result.position === 1) score += rules.win;
if (result.position <= 3) score += rules.podium;
} else if (result.status === "DNF") {
score += rules.dnf;
}
return score;
}
Calculer une manche
GET /races/seasons/{year}/round/{round}/results renvoie une ligne par pilote avec position,
points, status, rider_name et un rider_id stable. Indexez les lignes par pilote et additionnez
les choix de chaque équipe :
// round.js
import { scoreResult } from "./scoring.js";
const HOST = "motogp-api-championship-data-statistics.p.rapidapi.com";
const headers = { "X-RapidAPI-Key": process.env.RAPIDAPI_KEY, "X-RapidAPI-Host": HOST };
async function get(path) {
const res = await fetch(`https://${HOST}${path}`, { headers });
if (!res.ok) throw new Error(`${path}: ${res.status}`);
return (await res.json()).data;
}
export async function scoreRound(year, round, teams) {
const results = await get(`/races/seasons/${year}/round/${round}/results?category=MOTOGP`);
const byRider = new Map(results.map((r) => [r.rider_name, r]));
return teams
.map((team) => ({
name: team.name,
points: team.riders.reduce((sum, rider) => {
const result = byRider.get(rider);
return sum + (result ? scoreResult(result) : 0); // didn't start: 0
}, 0),
}))
.sort((a, b) => b.points - a.points);
}
const league = [
{ name: "Late Brakers", riders: ["Marco Bezzecchi", "Raúl Fernández", "Fabio Di Giannantonio"] },
{ name: "Apex Hunters", riders: ["Marc Márquez", "Jorge Martín", "Pedro Acosta"] },
];
console.table(await scoreRound(2026, 1, league));
Cet exemple associe les choix par nom pour la lisibilité. En production, stockez le rider_id de
chaque choix depuis GET /riders/seasons/{year} quand le joueur compose son équipe, et indexez les
résultats par rider_id.
Totaux de saison
Calculez chaque manche terminée et additionnez les résultats. Une manche pas encore courue renvoie une liste vide et vaut 0 pour tout le monde :
export async function seasonTable(year, teams, lastRound) {
const totals = new Map(teams.map((t) => [t.name, 0]));
for (let round = 1; round <= lastRound; round++) {
for (const { name, points } of await scoreRound(year, round, teams)) {
totals.set(name, totals.get(name) + points);
}
}
return [...totals].map(([name, points]) => ({ name, points })).sort((a, b) => b.points - a.points);
}
Stockez les scores de chaque manche dans votre base une fois les résultats connus. Les scores ne changent jamais après la validation d’une manche : vous n’appelez donc l’API que pour la manche la plus récente.
Listes de choix et prix
- Qui peut être choisi :
GET /riders/seasons/{year}?category=MOTOGPliste la grille de la saison. - Prix des pilotes : déduisez-les du championnat en cours —
GET /standings/seasons/{year}/riders— pour que les leaders coûtent plus cher que les derniers.