← Tous les guides

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énementPoints fantasy
Points de championnat marqués en course1 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=MOTOGP liste 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.