Skip to content

Exercise Duel Services

Exercise - Duel Services

Erstellen Sie ein System zur Simulation von Wettkämpfen.

Das Elo Rating

Das Elo Rating System ist eine Methode zur Berechnung eines relativen Skill-Levels von Spielern in einem Zero-Sum Game. Es wurde vom amerikanischen Physikprofessor Arpad Elo als Verbesserung des Harkness Systems für Schach Wettkämpfe entwickelt und sollte besser abbilden welchen Skill-Level und welchen Rang einzelne Spieler erhalten. Das System wurde aber seitdem für viele andere Bereiche verwendet, unter anderem in Sportarten wie Football, Baseball und Basketball, aber auch in Brettspielen und Videospielen. Es kann immer dann verwendet werden, wenn zwei Kontrahenten gegeneinander antreten und der Gewinn des einen Kontrahenten einen gleich großen Verlust für den anderen Kontrahenten bedeutet.

Das Elo-Rating ist keine absolute Größe für den Skill-Level eines Spielers, sondern nur relativ gültig innerhalb der Gruppe an Spielern die am selben Rating teilnehmen.

Zu Beginn wird das Elo-Rating eines Spielers entweder fix festgelegt oder anhand von Matchmaking-Games, also Duellen, die rein zur Einordnung des Levels dienen, ermittelt.

Danach wird nach jedem Wettkampf das Rating angepasst.

Der Erwartungswert für einen Gewinn von Spieler A (EAE_A) und den Ratings RBR_B für Spieler B und RAR_A für Spieler A lautet: EA=11+10(RBRA)/400E_A = \frac{1}{1 + 10^{(R_B - R_A)/400}}

Der Differenzbetrag, EloDeltaElo_{Delta} der bei einem Gewinn von Spieler A dem Rating von Spieler A hinzugefügt und dem Rating von Spieler B gleichermaßen abgezogen wird berechnet sich durch: K(1EA)K * (1 - E_A)

KK ist dabei ein Faktor der bestimmt wie stark sich ein Sieg bzw. eine Niederlage auf das Rating auswirkt. Bei wenigen Spielen mit großer Auswirkung wird ein geringer Faktor KK verwendet. Bei häufigen Spielen mit schleichender Anpassung des Elo-Ratings wird ein hoher Faktor KK verwendet. Er liegt meist zwischen 10 und 32.

Ein C# Code-Snippet für die Berechnung des EloDeltaElo_{Delta} könnte so aussehen:

private double ExpectationToWin(
int playerOneRating,
int playerTwoRating)
{
return 1 /
(1 + Math.Pow(10, (playerTwoRating - playerOneRating) / 400.0));
}
private int CalculateEloDelta(
int playerOneRating,
int playerTwoRating)
{
int eloK = 32;
return (int)(eloK *
(1 - ExpectationToWin(playerOneRating, playerTwoRating)));
}

Elo Simulation System

Erstellen Sie ein System mithilfe von ASP.NET zur Verwaltung von Spielern, Simulation von Duellen und Mitführen von Statistiken.

Das System besteht aus vier einzelnen Services.

  • Registration Service
  • Matchmaking Service
  • Duel Service
  • Player Statistics Service

Jedes Service ist eigenständig als eigener Prozess ausführbar. Strukturieren Sie Ihre Solution so, dass zumindest ein Projekt je Service angelegt wird.

Die Services kommunizieren untereinander rein durch die Verwendung von REST-Schnittstellen. Die Services bieten für andere Services Endpunkte an, über die Informationen abgefragt werden können und können einen HttpClient verwenden um auf die Endpunkte der anderen Services zuzugreifen.

Service Übersicht

EloExercise.excalidraw.svg

Service Beschreibung

Registration Service

Dieses Service verwaltet alle Spieler die am Rating System teilnehmen. Nur Spieler die in diesem Service angelegt sind können vom Matchmaking für Duelle herangezogen werden. Sollten Spieler entfernt werden, nehmen diese nicht mehr an zukünftigen Duellen teil.

Zu verwaltende Daten pro Spieler:

  • Id
  • Name
  • EloRating

Wird ein neuer Spieler angelegt wird ihm initial der Elo-Wert 1.500 zugewiesen.

Endpunkte:

  • POST /Registration
    • Legt einen neuen Spieler an
    • Name wird im Body des Requests übergeben
    • Id und Elo-Wert wird vom Service vergeben
  • PUT /Registration/{id}
    • Aktualisiert einen vorhandenen Spieler
    • Name und Elo-Wert können aktualisiert werden
  • GET /Players
    • Liefert eine Liste aller eingetragenen Spieler

Matchmaking Service

Dieses Service ermittelt die nächsten Duelle die zwischen den registrierten Spielern stattfinden sollen. Die registrierten Spieler werden vom Registration Service bezogen. Jeder Spieler mit einem anderen Spieler gematcht werden, der dem eigenen Elo-Wert möglichst nahe ist. Duelle sind dann am interessantesten, wenn sich die Spieler möglichst gleich auf sind. Außerdem soll die Reihenfolge der Duelle berücksichtigen, dass zuerst Duelle von Spielern ausgetragen werden, die entweder noch nie ein Duell gespielt haben, oder dessen letztes Duell bereits weiter in der Vergangenheit liegt. Die Daten zum letzten Spielzeitpunkt können vom Statistics Service bezogen werden.

Zu verwaltende Daten:

  • Geordnete Liste an bevorstehenden Duellen

Endpunkte:

  • GET /Matchmaking
    • Liefert eine geordnete Liste aller bevorstehenden Duelle

Duel Service

Dieses Service ist für die Simulation der Duelle verantwortlich. Es bezieht die Liste der bevorstehenden Duelle vom Matchmaking Service. Alle 10 Sekunden wird eine Reihe von Duellen ausgetragen. Der Gewinner wird zufällig ermittelt und der Elo-Wert der Spieler aktualisiert. Duelle können in einem Unentschieden oder in einem Sieg für einen der beiden Spieler enden. Bei einem Unentschieden wird das Elo-Rating nicht verändert. Der aktualisierte Elo-Wert muss dem Registration Service übermittelt werden. Allgemeine Daten zum Spielausgang werden dem Statistics Service übermittelt.

Anmerkung: Streng genommen müsste auch bei einem Unentschieden der Elo-Wert angepasst werden, wenn das Elo-Rating der Spieler verschieden ist. Der Spieler mit geringerem Rating bekommt Punkte vom höher bewerteten Spieler. In unserem Beispiel verzichten wir auf eine Anpassung der Werte bei einem Unentschieden und passen den Wert nur an wenn es einen Sieger und einen Verlierer gibt. Verwende einen KK Faktor von 32.

Zu verwaltende Daten:

  • Dieses Service hält selbst keine Daten dauerhaft.

Endpunkte:

  • Dieses Service bietet selbst keine Endpunkte an. Legen Sie das Service trotzdem als WebApplication an, damit ein einheitliches Setup für alle Services besteht und später das Service leicht um Endpunkte erweitert werden kann, sollte dies nötig sein.

Statistics Service

Das Service verwaltet Statistiken zu Spielern. Die Statistiken werden nach jedem Duellausgang aktualisiert. Die Daten dafür werden vom Duel Service übermittelt.

Zu verwaltende Daten pro Spieler:

  • PlayerId
  • PlayerName
  • CurrentEloRating
  • NumberOfDuelsWon
  • NumberOfDuelsLost
  • NumberOfDuelsDraw
  • NumberOfDuelsPlayed
  • AverageDuelDuration
  • LastDuelPlayedAt

Endpunkte:

  • GET /Statistics
    • Liefert eine Liste aller Statistiken (eine pro Spieler)
  • POST /Statistics
    • Der Ausgang eines Duells wird an diesen Endpunkt gesendet woraufhin die Statistiken der betroffenen Spieler aktualisiert wird.

Frontend:
Dieses Service bietet zusätzlich zu den REST-Endpunkten auch ein Blazor-Frontend an. Das soll eine einfache Möglichkeit bieten alle aktuellen Statistiken der Spieler einsehen zu können. Es muss keine automatische Aktualisierung entwickelt werden. Beim erneuten Laden der Seite sollen immer die aktuellen Statistiken angezeigt werden. Das Frontend könnte so oder so ähnlich aussehen: EloExerciseFrontend.png

Allgemeine Hinweise

Datenhaltung

Die einzelnen Services müssen in der Lage sein selbstständig die benötigten Daten zu verwalten. Es ist ausreichend eine In-Memory Datenhaltung zu implementieren, wobei die Daten bei jedem Prozess-Stop verloren gehen. Achten Sie aber darauf, dass geeignete Interfaces für die Datenhaltungsschicht verwendet werden, die es ermöglichen die Datenhaltung später gegen eine persistente Art der Datenhaltung auszutauschen.

Background Services

Damit in einem ASP.NET Projekt wiederkehrende Tätigkeiten ausgeführt werden können, wie beispielsweise beim Duel Service, können Background Services verwendet werden.

Dafür wird eine Klasse definiert die von BackgroundService ableitet und die Methode ExecuteAsync implementiert.

public class DuelBgService : BackgroundService
{
protected override async Task ExecuteAsync(
CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// TODO: implement logic
await Task.Delay(10_000);
}
}
}

Die Klasse kann dann im Program.cs registriert werden.

builder.Services.AddHostedService<DuelBgService>();

Damit beginnt das Background Service direkt nach Start der Anwendung zu laufen und es kann auch Dependency Injection innerhalb des Background Services verwendet werden.