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:
| Ereignis | Fantasy-Punkte |
|---|---|
| Im Rennen erzielte Meisterschaftspunkte | 1 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=MOTOGPlistet 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.