Tutorial: Deinen Bot startklar machen
Damit dein Bot bei GoGoGo mitspielen kann, muss er sich am Ende in einem
Docker-Image starten lassen, das über stdin/stdout
GTP
(Go Text Protocol) spricht. Die Programmiersprache ist dabei komplett egal, solange am Ende
ein Docker-Image dabei rauskommt, das GTP kann.
1. Was dein Bot können muss
Das Protokoll ist zeilenbasiert: Die Plattform schickt einen Befehl, dein Bot antwortet mit
= <ergebnis> (Erfolg) oder ? <fehler> (Fehler), gefolgt von einer
Leerzeile. Beispiel (die Pfeile zeigen, von welcher Seite die Nachricht kommt):
-> genmove black <- = D4 <- -> play white pass <- = <-
Folgende Kommandos müssen unterstützt werden:
| Kommando | Bedeutung |
|---|---|
name | Name des Bots |
version | Version im Format Major.Minor (z.B. 1.0) |
boardsize N | Brettgröße setzen (9 oder 13) |
komi X | Komi setzen (bei uns 6.5, muss aber generell einstellbar sein und auf .5 enden) |
clear_board | Neues, leeres Brett |
play B|W COORD | Zug des Gegners eintragen, COORD z.B. D4 oder pass |
genmove B|W | Eigenen Zug berechnen und zurückgeben (Koordinate, pass oder resign) |
quit | Sauber beenden |
final_score (Endergebnis wie W+7.5) wird zusätzlich vom System aufgerufen,
wenn beide Seiten hintereinander passen. Dein Bot sollte es also idealerweise auch beherrschen.
2. Koordinaten
Zug-Koordinaten bestehen aus Buchstabe (Spalte) + Zahl (Reihe), z.B. D4 oder Q16.
Wie im GTP-Standard üblich wird der Buchstabe I übersprungen (Verwechslungsgefahr mit
1): A B C D E F G H J K L M N O P Q R S T. Reihe 1 ist die
unterste Reihe. pass und resign sind jederzeit gültige Antworten auf
genmove.
3. Regeln, die der Server selbst durchsetzt
Du musst diese Fälle in deiner eigenen Zuggenerierung nicht extra behandeln, der Server lehnt sie ohnehin ab:
- Ziehen auf ein besetztes Feld: illegal
- Selbstmord (eigene Gruppe hätte danach keine Freiheit mehr): illegal
- Einfaches Ko: sofortiges Zurückschlagen bei genau einem geschlagenen Stein ist verboten. Achtung: es wird nur dieses einfache Ko geprüft, kein Superko/Positionsko. Verlass dich also nicht darauf, dass Stellungswiederholungen allgemein verhindert werden.
- Geschlagene gegnerische Gruppen (ohne Freiheiten) werden automatisch vom Server vom Brett
genommen. Du musst selbst keine Steine "abräumen", nur den aktuellen Zustand über
play-Nachrichten mitverfolgen.
4. Zeit- und Ressourcen-Limits
Pro Container fest durchgesetzt:
- 15 Sekunden pro
genmove-Aufruf. Danach gilt der Zug als Timeout und du verlierst automatisch dieses Spiel. - 4 GB RAM, 4 CPU-Kerne pro Container
(
docker run --memory 4g --cpus 4.0). - Kein Netzwerk während des Spiels (
--network none): alle Modelle/Gewichte/Daten müssen schon im Image liegen, kein Nachladen zur Laufzeit.
5. Passen & Ergebnis
Nach zwei aufeinanderfolgenden pass fragt der Server ausschließlich den
Bot, der gerade Weiß spielt, nach final_score. Dessen Antwort (z.B.
W+7.5) entscheidet über den Sieger. Da du in unterschiedlichen Spielen mal Schwarz,
mal Weiß bist, solltest du final_score unabhängig von der eigenen Farbe zuverlässig
beantworten.
6. Was bei Fehlern passiert
- Illegaler Zug, GTP-Protokollfehler oder Timeout: du verlierst automatisch nur dieses eine Spiel, nicht das ganze Match.
- Willst du selbst aufgeben:
resignals Antwort aufgenmove. - Ein Absturz deines Prozesses zählt wie ein Protokollfehler (Timeout/Fehlerergebnis). Achte also auf robustes Error-Handling in deinem Bot, damit ein einzelner Bug nicht gleich das ganze Spiel kostet.
7. Ein Dockerfile im Repo-Root
Leg ein Dockerfile in den Root deines Repos. Am saubersten ist ein
Multi-Stage-Build: In der Build-Stage hast du Internet und darfst dir
Pakete ziehen (apt-get, pip, npm, cargo, …).
Der fertige Container, der später die Matches spielt, läuft dagegen ohne Netzwerk,
er braucht also am Ende alles schon an Bord.
8. Beispiel-Dockerfile
Beispiel für einen in C geschriebenen, mit make gebauten Bot:
# ---- Build-Stage: hier ist Internet verfügbar ----
FROM debian:bookworm-slim AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential make && rm -rf /var/lib/apt/lists/*
WORKDIR /src
COPY . .
RUN make -C bot clean release
# ---- Runtime-Stage: läuft beim Match, ohne Netzwerk ----
FROM debian:bookworm-slim
WORKDIR /bot
COPY --from=build /src/bot/bot ./bot
ENTRYPOINT ["./bot"]
Das Prinzip ist für andere Sprachen identisch, nur die Build-Stage sieht anders aus:
| Sprache | Build-Stage installiert | Entrypoint |
|---|---|---|
| Python | pip install -r requirements.txt | ["python3", "bot.py"] |
| Node.js | npm ci | ["node", "bot.js"] |
| Rust | cargo build --release | ["./target/release/bot"] |
| Go | go build -o bot . | ["./bot"] |
9. Lokal testen, bevor du einreichst
docker build -t meinbot . docker run -i meinbot
Danach kannst du von Hand GTP-Kommandos eintippen und die Antworten sehen, z.B.:
boardsize 9 komi 6.5 clear_board genmove B
Wenn das läuft, läuft es auch bei uns.
10. Einreichen
Trag einfach die öffentliche Git-URL deines Repos (mit dem Dockerfile im Root)
unter Bot einreichen ein. Den Rest (Image bauen, freischalten)
übernehmen wir.
Fragen oder hängst irgendwo fest? Meldet euch einfach bei der Orga. Wir helfen gerne beim Dockerfile, GTP-Anbindung oder sonstigen Problemen. Lieber einmal zu viel gefragt als frustriert aufgegeben!