← Alle Anleitungen

Eine Fantasy-MotoGP-Liga auswerten

Verwandeln Sie Rennergebnisse mit eigenen Wertungsregeln in Fantasy-Punkte und ranken Sie die Teams Ihrer Liga nach jeder Runde.

10 Min. Lesezeit

Fantasy-Spiele gehören zu den besten Einsatzzwecken für Renndaten: Spieler wählen Fahrer, und jedes Ergebnis bewegt die Ligatabelle. Diese Anleitung wertet eine Liga in JavaScript mit Regeln aus, die Sie selbst kontrollieren.

Die Regeln

Jedes Fantasy-Team wählt drei Fahrer. Nach jeder Runde erhält jeder Fahrer:

EreignisFantasy-Punkte
Im Rennen erzielte Meisterschaftspunkte1 pro Punkt
Sieg+10 Bonus
Podium (P1–P3)+5 Bonus
Nicht im Ziel−5

Halten Sie Regeln als Daten statt als Code vor, damit Sie sie zwischen den Saisons anpassen können.

// 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;
}

Eine Runde auswerten

GET /races/seasons/{year}/round/{round}/results liefert eine Zeile pro Fahrer mit position, points, status, rider_name und einer stabilen rider_id. Indizieren Sie die Zeilen nach Fahrer und summieren Sie die Picks jedes Teams:

// 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));

Dieses Beispiel ordnet Picks der Lesbarkeit halber über den Namen zu. Speichern Sie in der Produktion die rider_id jedes Picks aus GET /riders/seasons/{year}, wenn der Spieler sein Team zusammenstellt, und indizieren Sie die Ergebnisse nach rider_id.

Saisongesamtwerte

Werten Sie jede beendete Runde aus und addieren Sie die Ergebnisse. Eine Runde, die noch nicht gefahren wurde, liefert eine leere Liste und zählt für alle 0:

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);
}

Speichern Sie die Punkte jeder Runde in Ihrer Datenbank, sobald die Ergebnisse vorliegen. Die Punkte ändern sich nach Abschluss einer Runde nie mehr, sodass Sie die API nur für die neueste Runde aufrufen.

Auswahllisten und Preise

  • Wer gewählt werden kann: GET /riders/seasons/{year}?category=MOTOGP listet das Startfeld der Saison.
  • Fahrerpreise: Leiten Sie sie aus der aktuellen Meisterschaft ab – GET /standings/seasons/{year}/riders –, damit Spitzenreiter mehr kosten als Hinterbänkler.