Zielgruppe: Anfänger mit Grundkenntnissen in Java — keine Vorkenntnisse in 3D oder KI nötig

Projekt auf GitHub     ← Zurück

1. Was ist Backgammon?

Backgammon ist eines der ältesten Brettspiele der Welt (über 5.000 Jahre alt). Zwei Spieler (Weiß und Schwarz) ziehen je 15 Steine über ein Brett mit 24 Feldern (sogenannte „Points“).

Grundregeln in Kürze

Keine Backgammon-Kenntnisse? Kein Problem. Das Spiel erklärt sich beim Spielen von selbst — einfach starten und ausprobieren!

2. Was macht dieses Projekt?

Backgammon3D ist ein vollständiges Backgammon-Spiel mit 3D-Grafik (JavaFX) und einer echten KI (künstliche Intelligenz), die selbstständig lernt zu spielen.

FeatureBeschreibung
3D-SpielbrettDas Brett wird in echter 3D-Grafik mit JavaFX dargestellt — Steine, Würfel und Positionen sind räumlich sichtbar
3 SpielertypenMensch, Zufalls-KI (RandomPlayer) und lernende KI (TDPlayer)
TD-Gammon KINachbildung des berühmten TD-Gammon-Algorithmus von Gerald Tesauro (1992) — lernt durch Selbstspiel
KI-TrainingDie KI kann direkt in der Anwendung trainiert werden (z.B. 10.000 Partien gegen sich selbst)
Modell speichernDas trainierte neuronale Netzwerk wird als Datei gespeichert und beim nächsten Start geladen
SpielgeschwindigkeitBei KI vs. KI kann die Geschwindigkeit per Schieberegler reguliert werden

3. Voraussetzungen & Setup

Was wird benötigt?

SoftwareVersionZweck
Java JDK21 oder höherLaufzeitumgebung und Compiler
Maven3.6+Build-Tool (baut das Projekt)
GitbeliebigQuellcode herunterladen
IntelliJ IDEAbeliebig (empfohlen)IDE zum Lesen und Bearbeiten des Codes
Was ist Java JDK? Das JDK (Java Development Kit) enthält alles, was man braucht, um Java-Programme zu schreiben und auszuführen. Download unter adoptium.net — einfach die neueste Version für dein Betriebssystem wählen und installieren.

Quellcode herunterladen

# Repository klonen (herunterladen)
git clone https://github.com/CavdarKemal/Backgammon3D.git

# In das Verzeichnis wechseln
cd Backgammon3D
Was ist git clone? Das ist wie ein "Download" des gesamten Projekts inklusive der gesamten Änderungsgeschichte. Nach dem Klonen hast du den vollständigen Quellcode auf deinem Rechner.

4. Projekt bauen und starten

Schritt 1: Bauen

Das Bauen übersetzt den Java-Quellcode in ausführbaren Code:

# Mit ci.cmd (Windows, empfohlen)
ci.cmd 17

# Oder direkt mit Maven
mvn clean package -DskipTests

Schritt 2: Starten

# Über Maven JavaFX Plugin starten
mvn javafx:run
Was passiert beim Bauen? Maven liest die pom.xml-Datei, lädt alle benötigten Bibliotheken (JavaFX, DeepLearning4J) aus dem Internet, übersetzt den Java-Code und packt alles zusammen. Beim ersten Mal kann das länger dauern.

Häufige Fehler beim Start

FehlerUrsacheLösung
Java version mismatchFalsches JDKJDK 21+ installieren und JAVA_HOME setzen
BUILD FAILURE (Download)Kein InternetInternetverbindung prüfen; beim ersten Mal werden ~500 MB Bibliotheken geladen
JavaFX not foundFalsches StartkommandoImmer mvn javafx:run verwenden, nicht direkt die JAR starten

5. Spielmodi erklärt

Beim Start erscheint ein Dialog, in dem man für Weiß und Schwarz jeweils einen Spielertyp auswählt:

SpielertypKlasseBeschreibung
HumanHumanPlayerDu spielst selbst — klick auf deine Steine und dann auf das Zielfeld
RandomRandomPlayerWählt alle gültigen Züge zufällig — gut zum Testen
TD-GammonTDPlayerDie lernende KI — wählt den Zug, den das neuronale Netzwerk am besten bewertet

Empfohlene Kombination für Einsteiger

6. Die Spieloberfläche

Steuerung

KI-Geschwindigkeit

Bei automatischen Spielen (KI vs. KI) steuert der Geschwindigkeits-Schieberegler, wie lange die KI zwischen zwei Zügen pausiert. Ganz links = schnellstmöglich, ganz rechts = langsam (gut zum Zuschauen).

Training starten

Der Button „Train AI“ startet das Training der KI. Es wird automatisch eine bestimmte Anzahl von Partien gespielt, in denen die KI gegen sich selbst lernt. Danach wird das Modell gespeichert.

7. Projektarchitektur

Das Projekt ist in vier klar getrennte Bereiche unterteilt:

Backgammon3D/
├── src/main/java/com/backgammon3d/
│   ├── Main.java              ← Einstiegspunkt, UI-Aufbau, Spielablauf
│   ├── Launcher.java          ← JavaFX-Starthelfer
│   ├── model/                 ← Spiellogik (regelkonform, ohne Grafik)
│   │   ├── GameState.java     ← Aktueller Spielzustand (Brett, Bar, BearOff)
│   │   ├── Move.java          ← Ein einzelner Zug (von → nach)
│   │   ├── MoveGenerator.java ← Alle gültigen Züge berechnen
│   │   ├── BackgammonRules.java← Regelprüfung
│   │   └── Dice.java          ← Würfelmechanik
│   ├── ai/                    ← Spieler-Implementierungen
│   │   ├── Player.java        ← Interface: jeder Spieler hat chooseMove()
│   │   ├── HumanPlayer.java   ← Wartet auf Mausklick
│   │   ├── RandomPlayer.java  ← Wählt zufälligen gültigen Zug
│   │   └── TDPlayer.java      ← KI: benutzt TDNetwork zur Zugbewertung
│   ├── neural/                ← Neuronales Netzwerk
│   │   ├── TDNetwork.java     ← Das Netzwerk (198→80→1)
│   │   ├── TDTrainer.java     ← Trainingslogik (Selbstspiel + TD-Update)
│   │   └── BoardEncoder.java  ← Brett → 198 Zahlen umwandeln
│   └── view/                  ← 3D-Grafik
│       ├── BoardView.java     ← Das gesamte 3D-Brett
│       ├── PointView.java     ← Ein einzelnes Point (Feld) in 3D
│       ├── CheckerView.java   ← Ein einzelner Stein in 3D
│       └── DiceView.java      ← Würfelanzeige
Designprinzip — Model & View trennen: Das model/-Package enthält ausschließlich Spiellogik, keine Grafik. Das view/-Package kümmert sich nur um die Darstellung. Dadurch lässt sich die KI z.B. ohne Grafik trainieren (viel schneller!).

8. Das Spielmodell (GameState)

Der GameState ist das Herzstück der Spiellogik. Er repräsentiert den vollständigen Spielzustand als Zahlen.

Das Brett als Array

Das Brett besteht aus 24 Points. Jeder Point wird durch eine Ganzzahl (int) repräsentiert:

int[] points = new int[24];

// Positive Werte = Weiße Steine auf diesem Point
// Negative Werte = Schwarze Steine auf diesem Point
// Beispiel: points[5] = 3   → 3 weiße Steine auf Point 6
//           points[11] = -5 → 5 schwarze Steine auf Point 12

Startposition

// Standard-Startaufstellung:
points[23] = 2;   // 2 weiße Steine auf Point 24 (feindliches Heimfeld)
points[12] = 5;   // 5 weiße Steine auf Point 13
points[7]  = 3;   // 3 weiße Steine auf Point 8
points[5]  = 5;   // 5 weiße Steine auf Point 6 (eigenes Heimfeld)

points[0]  = -2;  // 2 schwarze Steine auf Point 1 (feindliches Heimfeld)
points[11] = -5;  // 5 schwarze Steine auf Point 12
points[16] = -3;  // 3 schwarze Steine auf Point 17
points[18] = -5;  // 5 schwarze Steine auf Point 19 (eigenes Heimfeld)

Bar und BearOff

int whiteBar = 0;     // Wie viele weiße Steine auf der Bar (wurden geschlagen)
int blackBar = 0;     // Wie viele schwarze Steine auf der Bar

int whiteBearOff = 0; // Wie viele weiße Steine wurden bereits ausgewurfelt
int blackBearOff = 0; // Wer zuerst 15 erreicht, gewinnt!
Warum negative Zahlen für Schwarz? So lässt sich mit einem einzigen Array das gesamte Brett darstellen. Ein Vorzeichen-Check genügt, um die Farbe eines Steins zu bestimmen: if (points[i] > 0) → Weiß, if (points[i] < 0) → Schwarz.

9. Die KI: TD-Gammon erklärt

Die KI basiert auf dem TD-Gammon-Algorithmus von Gerald Tesauro (IBM, 1992). TD-Gammon war die erste KI, die menschliche Weltklasse-Spieler im Backgammon schlug — und das durch reines Selbstspiel.

Das Grundprinzip: Lernen durch Selbstspiel

Die KI lernt durch unzählige Partien gegen sich selbst. Das neuronale Netzwerk lernt dabei eine einzige Sache: Wie hoch ist die Gewinnwahrscheinlichkeit in dieser Spielposition?

// Was das Netzwerk berechnet:
// Eingabe: Aktuelle Brettposition (als 198 Zahlen)
// Ausgabe: Eine Zahl zwischen 0 und 1
//   → 1.0 = Weiß gewinnt mit Sicherheit
//   → 0.5 = Unentschieden (ausgeglichene Stellung)
//   → 0.0 = Schwarz gewinnt mit Sicherheit

Wie wählt die KI einen Zug?

Gegeben die gewürfelten Zahlen, berechnet die KI alle möglichen Züge. Für jeden möglichen Folgezustand fragt sie das Netzwerk: „Wie gut ist diese Position für mich?“ — und wählt den besten Zug.

// Pseudocode für TDPlayer.chooseMove():
List<Move> gueltigeZuege = moveGenerator.generateMoves(state, dice);

Move besterZug = null;
double bestesBewertung = -1;

for (Move zug : gueltigeZuege) {
    GameState nachfolger = state.applyMove(zug);     // Zug simulieren
    double bewertung = netzwerk.evaluate(nachfolger); // Netzwerk fragen

    if (bewertung > bestesBewertung) {
        bestesBewertung = bewertung;
        besterZug = zug;
    }
}
return besterZug; // Den besten Zug ausführen

Was ist „TD“ in TD-Gammon?

TD steht für Temporal Difference (zeitliche Differenz). Das Lernprinzip: Nach jedem Zug vergleicht die KI ihre aktuelle Schätzung mit der Schätzung im nächsten Zustand. Der Fehler zwischen beiden dient als Lernsignal:

// Vereinfacht:
// Zustand s → Bewertung V(s) = 0.6 (KI schätzt: 60% Gewinnchance)
// Nach einem Zug: Zustand s' → V(s') = 0.7
//
// Der "TD-Fehler" ist: 0.7 - 0.6 = +0.1
// → Das Netzwerk wird so angepasst, dass V(s) näher an 0.7 kommt
// → Die KI lernt: "Diese Position war besser als ich dachte"
Wichtig: Die KI lernt ausschließlich durch Selbstspiel — ohne menschliche Vorgaben, welche Züge gut oder schlecht sind. Sie entdeckt Strategien selbständig.

10. Das neuronale Netzwerk

Das Netzwerk besteht aus drei Schichten und wurde mit der Bibliothek DeepLearning4J implementiert:

Eingabe-Schicht:  198 Neuronen  ← Brettposition als Zahlen
          ↓
Hidden-Schicht:    80 Neuronen  ← Aktivierungsfunktion: Sigmoid
          ↓
Ausgabe-Schicht:    1 Neuron    ← Sigmoid → Gewinnwahrscheinlichkeit [0, 1]

Trainierbare Parameter: 198×80 + 80 + 80×1 + 1 = 16.001 Gewichte

BoardEncoder: Brett → 198 Zahlen

Neuronale Netzwerke verstehen keine Brettstellungen — sie brauchen Zahlen. Die Klasse BoardEncoder wandelt den GameState in genau 198 Zahlen um:

FeatureNeuronenBedeutung
24 Points × 4 Bits (Weiß)96Anzahl weißer Steine pro Point (binär codiert)
24 Points × 4 Bits (Schwarz)96Anzahl schwarzer Steine pro Point (binär codiert)
Bar (Weiß & Schwarz)2Normierte Anzahl Steine auf der Bar
BearOff (Weiß & Schwarz)2Normierte Anzahl ausgewurfelter Steine
Spieler am Zug21/0 kodiert, wer gerade dran ist
Warum 4 Bits pro Point? 4 Bits reichen für 0 bis 15 Steine (mehr als die maximalen 15 Steine pro Spieler) — eine klassische Tesauro-Codierung aus dem Original-TD-Gammon-Paper.

11. KI trainieren

Training starten

Klicke in der Anwendung auf „Train AI“. Das Training läuft im Hintergrund — die GUI bleibt während des Trainings bedienbar.

Was passiert beim Training?

  1. Zwei TDPlayer spielen automatisch gegeneinander (ohne Grafik, daher sehr schnell)
  2. Nach jedem Zug wird das Netzwerk per TD-Update angepasst
  3. Nach dem letzten Spiel wird das Modell als Datei gespeichert (td_model.zip)
  4. Beim nächsten Start wird das Modell automatisch geladen

Wie viele Partien benötigt die KI?

TrainingspartienSpielstärkeTrainingszeit (ca.)
1.000Besser als RandomPlayer~1 Minute
10.000Angenehmer Gegner für Anfänger~10 Minuten
100.000Merklich strat. Spielweise~1-2 Stunden
Tipp: Starte mit 1.000 bis 5.000 Partien, um einen ersten Eindruck zu bekommen. Das Original-TD-Gammon wurde mit Millionen von Partien trainiert — der Algorithmus verbessert sich kontinuierlich.

12. Die 3D-Ansicht (BoardView)

Die BoardView-Klasse baut das gesamte 3D-Spielbrett mit JavaFX auf. JavaFX bietet eine eingebaute 3D-Engine mit Lichtern, Kameras und 3D-Formen.

Aufbau der 3D-Szene

// Vereinfachter Aufbau in BoardView:

PerspectiveCamera camera = new PerspectiveCamera(true);
// Kamera leicht von oben schauen lassen
camera.setTranslateZ(-800);
camera.setTranslateY(-200);

// Brett-Fläche
Box brettFlaeche = new Box(700, 20, 400);
brettFlaeche.setMaterial(new PhongMaterial(Color.DARKGREEN));

// 24 Points (Felder) als schmale Dreiecksformen
for (int i = 0; i < 24; i++) {
    PointView point = new PointView(i);
    brett.getChildren().add(point);
}

// Lichtquelle
PointLight licht = new PointLight(Color.WHITE);
licht.setTranslateY(-400);

Wie werden Steine bewegt?

Wenn ein Zug ausgeführt wird, aktualisiert BoardView die 3D-Positionen der CheckerView-Objekte (die Steine). Die Steine werden nicht gelöscht und neu erstellt, sondern per TranslateTransition animiert bewegt.

13. Spielzüge & Regeln

MoveGenerator: Alle gültigen Züge berechnen

Die Klasse MoveGenerator berechnet zu einem gegebenen Spielzustand und Würfelwurf alle möglichen legalen Züge. Diese Aufgabe ist komplizierter als sie klingt:

BackgammonRules: Einzelnen Zug prüfen

BackgammonRules prüft, ob ein konkreter Zug (von Point X nach Point Y) regelkonform ist:

// Beispiel-Prüfung (vereinfacht):
public boolean isValidMove(GameState state, Move move) {
    int from = move.getFrom();
    int to   = move.getTo();
    int distance = Math.abs(to - from);

    // 1. Muss ich erst von der Bar einsetzen?
    if (state.hasBarStone(isWhite)) return false;

    // 2. Eigener Stein auf from?
    if (!state.hasOwnStone(from, isWhite)) return false;

    // 3. Zielfeld nicht blockiert (mehr als 1 gegnerischer Stein)?
    if (state.isBlocked(to, !isWhite)) return false;

    // 4. Distanz entspricht einem Würfelwert?
    return dice.contains(distance);
}

14. Nächste Schritte

Zum Spielen

Zum Weiterentwickeln

Links