Programmierwettbewerb für
Schülerinnen und Schüler
Oktober 2025 – Juni 2026

Los geht's!

Hier findest du eine Anleitung, wie du deinen eigenen Bot programmieren und starten kannst. Du benötigst dafür zwei Dinge:

  1. Den Runner, der das Spiel steuert und deinen Bot ausführt
  2. Deinen Bot, also das Programm, das du selbst schreibst und das die Entscheidungen trifft

Du kannst deinen Bot unter Linux, macOS oder Windows entwickeln. Dafür benötigst du Git, Ruby und Node.js. Wenn du möchtest, kannst du auch den Hackschule Workspace verwenden, in dem du online arbeiten kannst und in dem alle nötigen Pakete bereits installiert sind (frage einfach nach einer Einladung). Wähle hier dein Betriebsystem:

Du siehst einen einfachen Random Walker, der sich zufällig durch die Arena bewegt.

Tipp: Drücke Q oder Strg+C, um den Runner zu beenden.

Programmiere deinen Bot

Um deinen eigenen Bot zu programmieren und einzureichen, musst du uns Zugriff auf ein Git-Repository geben, in dem sich der Code deines Bots befindet. Du kannst dafür z. B. GitHub, GitLab oder Bitbucket verwenden. Wir empfehlen dir jedoch Codeberg zu verwenden, da es eine freie und datenschutzfreundliche Alternative zu Microsoft's Github ist, die von einem gemeinnützigen Verein in Berlin angeboten wird.

Es gibt viele Angebote für Entwickler:innen, die ihren Programmcode verwalten möchten. Manche werden von kommerziellen Firmen angeboten, andere von gemeinnützigen Vereinen, und manche kann man sogar selber betreiben. Kommerzielle Unternehmen wollen immer auch Geld mit ihren kostenlosen Angeboten verdienen, und damit ihr nicht selber Geld bezahlen müsst, sammeln und verkaufen sie eure Daten. Codeberg ist ein Verein aus Berlin, der keinen Gewinn machen muss und deshalb auch eure Daten nicht weiterverwendet oder verkauft.

Wir haben zwei Tutorials für dich vorbereitet – wähle hier deine bevorzugte Plattform:

Um deinen eigenen Bot zu programmieren, kannst du eine der folgenden Vorlagen verwenden:

Wähle einen Namen für dein Repository:

Wenn du bis hierher gekommen bist, sollte dein Bot ab morgen in den Scrim-Bestenlisten auftauchen. Wenn du ihn nicht veränderst, wird er unten in der Liste bei den Baseline-Bots stehen, da er noch nicht besonders intelligent ist.

Repository klonen

Als nächstes solltest du dein Repository klonen, damit du die Dateien bearbeiten kannst. Wenn du das noch nie gemacht, findest du im Internet viele Anleitungen dazu, z. B. hier:

Es ist am einfachsten, wenn du deinen Bot in dein Runner-Repository klonst. Wenn dein Runner also z. B. unter /home/alice/hidden-gems liegt, und dein Bot-Repository my-awesome-bot heisst, solltest du deinen Bot in das Verzeichnis /home/alice/hidden-gems/my-awesome-bot klonen.

Deinen Bot lokal starten

Du kannst deinen Bot im Runner starten, indem du den Pfad zu deinem Bot-Verzeichnis als Argument übergibst:

 my-awesome-bot
Achte immer darauf, dass der Runner aktuell ist. Du kannst ihn mit dem Befehl git pull aktualisieren.

Überblick verschaffen

In deinem Verzeichnis befinden sich folgende Dateien:

  • bot.rb (bzw. bot.py, bot.js, ...): der Code deines Bots (Dateiname egal)
  • bot.yaml: eine Datei, in der du Informationen über deinen Bot hinterlegst (Name und Emoji)
  • start.sh: ein ausführbares Shell-Skript, das deinen Bot unter Linux oder macOS startet
  • start.bat (optional): eine ausführbare Batch-Datei, die deinen Bot unter Windows startet, falls du unter Windows entwickeln möchtest

Passe als erstes den Namen und das Emoji deines Bots an, committe die Änderung und lade sie zu GitHub hoch (git push). Wenn du die Veränderung dann auch bei GitHub siehst, weißt du, dass alles funktioniert.

Herzlichen Glückwunsch, wenn du es bis hier hin geschafft hast! Du hast nun die Grundvoraussetzungen geschaffen, um deinen eigenen Bot zu programmieren und zu starten. Lies weiter, um zu erfahren, wie du deinen Bot programmieren kannst.


Dokumentation

In diesem Abschnitt erfährst du, wie du deinen Bot programmieren kannst.

Grundprinzip des Bots

Das Spiel läuft in sogenannten Ticks ab. In jedem Tick bekommt der Bot Informationen über seine Umgebung (z. B. wo sich Wände und Gems befinden) und muss darauf basierend eine Aktion auswählen (z. B. »gehe nach Norden«). Der Bot läuft also in einer Endlosschleife, in der die folgenden Schritte passieren:

  1. Der Bot liest eine Zeile von der Standardeingabe (stdin)
  2. Der Bot verarbeitet die Informationen und wählt eine Aktion aus
  3. Der Bot schreibt die ausgewählte Aktion auf die Standardausgabe (stdout)
  4. Optional: Der Bot gibt Kommentare auf der Standardfehlerausgabe aus (stderr)

Schritt 1: Lesen der Eingabedaten

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "config": {
    "stage_key": "stage-0@0.1",
    "width": 19,
    "height": 19,
    "generator": "cellular",
    "max_ticks": 1000,
    "vis_radius": 5,
    "max_gems": 1,
    "gem_spawn_rate": 0.05,
    "gem_ttl": 300,
    "bot_seed": 3851583338
  },
  "tick": 0,
  "bot": [13, 17],
  "wall": [[12, 14], [13, 14], ... ],
  "floor": [[12, 15], [13, 15], ... ],
  "visible_gems": [
    {
        "position": [13, 15],
        "ttl": 100
    }
  ]
}

Die Informationen, die der Bot erhält, werden im JSON-Format übermittelt (eine Zeile, ohne Zeilenumbrüche). Verwende die Möglichkeiten deiner Sprache, um die JSON-Daten zu parsen. Eine Nachricht könnte z. B. so aussehen wie hier abgebildet (hier wurde die Nachricht für bessere Lesbarkeit formatiert).

Unter config findest du die Konfigurationsparameter des Runners – diese Werte werden nur im 1. Tick übermittelt. Hier erfährst du z. B., wie groß die Arena ist (width und height) und wie weit dein Bot sehen kann (vis_radius). In bot_seed findest du einen Seed, mit dem du den Zufallszahlengenerator deines Bots initialisiert kannst, wenn du möchtest. Du erfährst auch, wie viele Ticks eine Runde dauert (max_ticks). Der Seed, mit dem die Arena generiert wurde, ist geheim und wird nicht übermittelt.

Die Zahl in tick gibt an, in welchem Tick sich der Runner gerade befindet (beginnend bei 0).

Unter bot findest du die aktuelle Position deines Bots als [x, y]-Koordinaten – die linke obere Ecke hat die Koordinaten [0, 0], die rechte untere Ecke die Koordinaten [width-1, height-1].

In wall und floor findest du die Positionen der Wände und des Bodens, die dein Bot von seiner Position aus sehen kann (abhängig von vis_radius und von Wänden, die die Sicht verdecken).

In visible_gems findest du die Gems, die dein Bot momentan sehen kann (nach denselben Regeln wie bei Wänden und dem Boden). Jedes Gem hat eine Position position und eine Lebensdauer (ttl, time to live), die angibt, für wie viele Ticks das Gem noch auf der Karte bleiben wird. Wenn du dich auf ein Feld mit einem Gem bewegst, sammelst du es automatisch ein und bekommst die noch verbleibende TTL als Punkte gutgeschrieben.

Wenn du noch nie mit JSON gearbeitet hast, findest du hier einige Tutorials, die dir den Einstieg erleichtern:

Schritt 2: Verarbeiten der Eingabedaten

Verarbeite die Eingabedaten und wähle eine Aktion aus. Es ist nicht schlimm, wenn du eine Aktion wählst, die nicht möglich ist (z. B. »gehe nach Norden«, obwohl im Norden eine Wand ist) – in diesem Fall passiert einfach nichts und dein Bot bleibt stehen. Die folgenden Aktionen sind möglich:

  • N: Bewegung nach Norden
  • E: Bewegung nach Osten
  • S: Bewegung nach Süden
  • W: Bewegung nach Westen
  • WAIT: Nicht bewegen (stehen bleiben)

Hinweis: Damit dein Bot am Wettbewerb teilnehmen kann, muss er deterministisch sein. Das bedeutet, dass sich dein Bot bei gleichen Karten und gleichen Eingabedaten immer gleich verhalten muss. Du kannst (und solltest) einen Zufallszahlengenerator verwenden, aber dieser darf nicht mit sich ändernden Werten (wie z. B. der aktuellen Uhrzeit oder der Process ID) initialisiert werden. Du kannst für das Seeding z. B. den Seed verwenden, der in bot_seed übermittelt wird, oder eine Konstante, oder einen davon abgeleiteten Wert.

Der Bot-Seed ändert sich in jeder Runde und da alle Bots dieselben Arenen mit denselben Seeds durchlaufen, bekommt jeder Bot denselben rundenspezifischen Bot-Seed. Du kannst ihn auch ignorieren, wenn du möchtest.

Schritt 3: Schreiben der Ausgabedaten

Schreibe die ausgewählte Aktion auf die Standardausgabe (stdout) und füge einen Zeilenumbruch hinzu. Wichtig: Achte darauf, dass du nur die Aktion schreibst und sonst nichts (kein zusätzliches Leerzeichen, keine Debug-Ausgabe).

Hinweis: Achte darauf, dass die Ausgabe deines Bots nicht gepuffert wird, sondern sofort ausgeführt wird, damit der Runner deine Entscheidung lesen kann (ggfs. musst du hierfür flush aufrufen). In den Beispiel-Bots ist das bereits berücksichtigt.

Schritt 4: Debugging (optional)

Wenn du möchtest, kannst du Kommentare auf die Standardfehlerausgabe (stderr) schreiben, z. B. um den aktuellen Status deines Bots zu protokollieren. Diese Kommentare werden vom Runner während einer Runde ausgegeben, aber nicht ausgewertet.

Debugging auf der Karte

Zusätzlich kannst du farbige Markierungen auf der Karte ausgeben, um bestimmte Bereiche hervorzuheben – ideal für Analyse und Fehlersuche. Hierfür kannst du auf der Standardausgabe (stdout) direkt hinter der Aktion ein Leerzeichen und eine spezielle JSON-Nachricht (ohne Zeilenumbruch) ausgeben, die z. B. wie folgt aussehen kann:

1
2
3
4
5
6
{
  "highlight": [
    [2, 2, "#ff0000"],
    [5, 3, "#ff000080"]
  ]
}

Du übergibst also eine Liste von Tiles (egal ob Wand oder Boden), die du markieren möchtest. Dabei kannst du Farben im Format #RRGGBB oder #RRGGBBAA (mit Alpha-Kanal) angeben. Die Markierungen werden für den aktuellen Tick angezeigt und verschwinden im nächsten Tick wieder.

Pausieren des Runners

Dein Bot hat auch die Möglichkeit, den Runner für Debugging-Zwecke zu pausieren. Hierfür übergibst du in einer JSON-Nachricht einfach "command": "pause". Der Key "command" lässt sich auch mit dem Key "highlight" kombinieren.