Eine Initiative des Fakultätentags Informatik
Autor
Jochen Könemann, University of Waterloo

14. Algorithmus der Woche
Gewinnstrategie für ein Streichholzspiel

Ich bin gerade ein bisschen verärgert und, zugegeben, auch etwas verwirrt. Gestern Abend kommt mein Bruder freudestrahlend auf mich zu - und das alleine ist schon mal kein gutes Zeichen - um mir von einem sehr interessanten neuen Intelligenztest zu erzählen. Natürlich erwarte ich nach dieser Ankündigung nichts Gutes. Aber irgendwie bin auch ein bisschen neugierig, von was er mir da berichten will. Dann lass mal hören!

Prima!, sagt er und kramt in seiner Hosentasche, nur um Sekunden später eine kleine Streichholzschachtel hervorzuzaubern, die er umgehend vor mir entleert. Jetzt liegen 18 Streichhözer zwischen mir und ihm auf dem Tisch. Die Spielregeln sind nun denkbar einfach: der erste Spieler nimmt 1, 2 oder 3 der auf dem Tisch liegenden Streichhölzer vom Tisch, danach nimmt der zweite Spieler entweder 1, 2 oder 3 der verbleibenden Hölzer usw. Verloren hat der Spieler, der das letzte Streichholz vom Tisch nimmt.

Verstanden?, fragt er mich. Er muss auch wirklich immer den großen Bruder raushängen lassen. Na klar! Ist ja nun auch wirklich kein sehr kompliziertes Spiel. Er grinst und sagt: Na schön. Dann kann's ja los gehen und ich fang' auch gleich mal an. Bin ja schließlich der ältere von uns beiden. Mit diesen Worten nimmt er ein Streichholz vom Tisch; es verbleiben somit 17 Hölzer.

Klasse, also verlieren kann ich in diesem Zug schon mal nicht, denn egal ob ich 1, 2 oder 3 Streichhölzer wegnehme, es verbleiben auf jeden Fall mindestens 14 auf dem Tisch. Also schnappe ich mir 2 der Hölzer und mein Bruder ist am Zug mit 15 verbleibenden Streichhölzern. Der grinst immer noch (warum nur?) und lässt 2 weitere Hölzer verschwinden, womit 13 auf dem Tisch verbleiben. Die linke Spalte der folgenden Tabelle zeigt die augenblickliche Spielsituation. Die rechte Spalte enthält die darauf folgenden Spielzüge.

Spielsituation Spielzug
(13) Ich nehme 3 Hölzer.
(10) Mein Bruder nimmt 1 Holz.
(9) Ich nehme 2 Hölzer.
(7) Mein Bruder nimmt 2 Hölzer.
(5) Ich nehme 1 Holz.
(4) Mein Bruder nimmt 3 Hölzer.

Nach dem letzten Zug meines Bruders verbleibt ein Streichholz auf dem Tisch, was ich nach der Spielregeln nehmen muss. Somit habe ich verloren! Das war natürlich nur Glück!, sage ich und fordere eine Revanche. Auch das nächste Spiel und die 2 danach gehen an meinen Bruder und so langsam stellt sich Frustration bei mir ein. Mein Bruder scheint mir in diesem Spiel wirklich überlegen zu sein. Aber wie macht er das?

Lernen anhand kleiner Beispiele

Um das Spiel ein wenig besser zu verstehen, sehe ich mir mal ein paar kleine Beispiele an. Ich weiß, dass ich verloren habe, wenn ich am Zug bin und nur noch ein Holz auf dem Tisch liegt. Aber was soll ich machen, wenn statt einem Holz, zwei vor mir liegen? Na ja, in diesem Fall nehme ich eins der beiden Hölzer und dann ist mein Bruder dran, der das letzte Holz nehmen muss und somit verliert! Das heißt, dass ich in dem Streichholzspiel meines Bruders eine Gewinnstrategie habe, wenn zu irgendeiner Zeit 2 Streichhölzer auf dem Tisch liegen und ich am Zug bin. Jetzt ist es nicht schwer, sich zu überlegen, dass ich auch eine Gewinnstrategie habe, wenn 3 oder 4 Hölzer auf dem Tisch liegen und ich am Zug bin. Im ersten Fall nehme ich 2 und im zweiten Fall 3 Hölzer vom Tisch und überlasse meinem Bruder ein einziges Holz.

Halten wir unsere bisher gewonnen Erkenntnisse fest: wir wissen jetzt also, dass, wenn einer der beiden Spieler des Streichholzspiels 2, 3 oder 4 Hölzer vor sich liegen hat und am Zug ist, der Spieler durch geschicktes Handeln das Spiel für sich entscheiden kann.

i 1 2 3 4
GS[i] Nein Ja Ja Ja
Die Tabelle links hat eine Spalte für jede der bisher analysierten Spielsituationen. Der Eintrag in der unteren Zeile von Spalte i (den wir mit GS[i] bezeichnen) zeigt an, ob der sich am Zug befindende Spieler eine Gewinnstrategie hat, wenn i Streichhölzer auf dem Tisch liegen.

Soweit so gut, aber was ist, wenn 5 Hölzer auf dem Tisch liegen? Die Antwort auf diese Frage erscheint nicht mehr ganz so einfach, interessiert mich aber sehr, da dies die vorletzte Spielsituation im ersten Spiel gegen meinen Bruder war. Die Spielregeln zwingen mich in dieser Situation mindestens ein und höchstens 3 Streichhölzer vom Tisch zu nehmen. D.h., mein Bruder hat nach meinem Zug entweder 2, 3 oder 4 Streichhölzer vor sich. In jeder dieser 3 Situationen hat mein Bruder eine Gewinnstrategie, wie ich von meinen vorherigen Argumenten weiß! Ich kann also aus dieser Ausgangssituation nicht gewinnen, wenn mein Bruder sich clever verhält. Allgemeiner kann der sich am Zug befindende Spieler aus einer Anfangssituation mit 5 Streichhölzern nicht gewinnen, wenn der Gegenspieler geschickt spielt und somit GS[5]=Nein.

Wenn sich 6 Streichhölzer auf dem Tisch befinden, dann kann ich entweder 1, 2 oder 3 Streichhölzer vom Tisch nehmen und meinem Bruder 3, 4 oder 5 Hölzer zurücklassen. Aus der obigen Tabelle weiß ich, dass mein Bruder aus einer Ausgangssituation mit 3 oder 4 Hölzern einen Gewinn erzwingen kann. Wenn ich ihm allerdings 5 Streichhölzer zurücklasse, dann hat er keine Gewinnstrategie (GS[5]=Nein) und somit kann er nicht gewinnen, wenn ich mich nach seinem Spielzug geschickt verhalte. Das heißt, dass ich eine Gewinnstrategie habe, wenn ich am Zug bin und 6 Streichhölzer vor mir liegen: ich nehme ein Holz vom Tisch! Somit haben wir GS[6]=Ja.

Ein Algorithmus zur Berechnung einer Gewinnstrategie

Die obigen Berechnungen kann ich jetzt problemlos fortführen. Nehmen wir beispielsweise an, ich hätte für alle Ausgangssituationen mit i ∈ {1,...,14} Streichhölzern bereits bestimmt, ob der sich am Zug befindende Spieler aus dieser Lage einen Sieg erzwingen kann. Wenn nun 15 Hölzer vor mir liegen, kann ich entweder 1, 2 oder 3 von diesen vom Tisch entfernen und somit 12, 13 oder 14 Hölzer zurücklassen. Wenn mein Bruder in all diesen Situationen eine Gewinnstrategie hat (GS[12]=GS[13]=GS[14]=Ja) und sich clever verhält, dann habe ich verloren und somit GS[15]=Nein. Andererseits, wenn mein Bruder in mindestens einer dieser Situationen keine Gewinnstrategie hat, dann kann ich durch geschicktes Verhalten einen Sieg herbeiführen (GS[15]=Ja).

Es ergibt sich der folgende Algorithmus zur Berechnung von GS[1] bis GS[X]:

Der obige Algorithmus kann nun dazu verwendet werden, um GS[1] bis GS[18] zu berechnen. Das Ergebnis des Aufrufs GEWINNSTRATEGIE(18) ist in der folgenden Tabelle zusammengefasst, wobei wir Nein mit N und Ja mit J abkürzen:

i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
GS[i] N J J J N J J J N J J J N J J J N J

Sehr schön! Jetzt weiß ich, dass mein Bruder aus der Startposition mit 18 Hölzern als Erstziehender eine Gewinnstrategie hat. Aber was ist diese Strategie?

Sehen wir uns noch einmal das erste Spiel zwischen mir und meinem Bruder an: mein Bruder beginnt das Spiel und es liegen 18 Streichhölzer vor ihm. Aus der obigen Tabelle entnehmen wir, dass GS[18]=Ja ist und somit hat mein Bruder eine Gewinnstrategie gegen mich, so lange er alles richtig macht. Wie soll nun sein erster Zug aussehen? Er hat die Wahl 1, 2 oder 3 Streichhölzer vom Tisch zu nehmen und mir somit 15, 16 oder 17 Hölzer zurückzulassen. Was soll er tun? Ein weiterer Blick auf die obige Tabelle verrät es uns: wenn ich am Zug bin und 15 Hölzer vor mir liegen, dann habe ich eine Gewinnstrategie. Das möchte mein Bruder natürlich vermeiden. Also wird er sich wohl nicht dafür entscheiden, 3 Hölzer vom Tisch zu nehmen. Ganz ähnlich verhält es sich, wenn er 2 Hölzer vom Tisch nimmt: mit 16 verbleibenden Streichhölzern habe ich laut Tabelle eine Gewinnstrategie! Die einzig verbleibende Wahl ist, ein Holz vom Tisch zu entfernen. Und tatsächlich: aus der Ausgangssituation mit 17 verbleibenden Hölzern, verliere ich laut Tabelle, wenn mein cleverer Bruder alles richtig macht.

Was habe ich noch gleich gemacht, nachdem mein Bruder 1 Holz vom Tisch genommen hat?, überlege ich. Richtig! Ich habe mir 2 Hölzer genommen und 15 Hölzer zurückgelassen. Die Tabelle verrät, dass mein Bruder aus dieser Lage gewinnen kann. Durch das Entfernen von 1, 2 oder 3 Hölzern kann er mir nun 12, 13 oder 14 Hölzer zurücklassen. Ein Blick auf die Tabelle zeigt, dass einzig und allein das Entfernen von 2 Hölzern eine Verlustsituation für mich erzwingt. Und das ist auch genau, was mein Bruder in seinem nächsten Zug gemacht hat. Von wegen Intelligenztest! Jetzt weiß ich, wie mein Bruder es angestellt hat, immer gegen mich zu gewinnen.

Als ich meinem Bruder von meinen Überlegungen erzähle, verrät er mir, dass es nicht schwer sei, zu beweisen, dass GS[X]=Ja ist wenn der Rest von X geteilt durch 4 ungleich 1 ist. Mit anderen Worten GS[X]=Nein, wenn der Rest von X durch 4 genau 1 ist. Wenn ich es also einmal in eine Gewinnsituation geschafft habe, dann geht's total einfach weiter: mein Gegenspieler nimmt y Hölzer, ich nehme 4-y, so dass als Summme 4 herauskommt. Diese handliche Formel deckt sich mit der obigen Tabelle und erklärt auch, warum mein Bruder keine Tabelle bzw. keinen Computer gebraucht hat, um gegen mich zu gewinnen.

Erweiterungen und Hintergrundinformationen

Das vorgestellte Spiel lässt sich beinahe beliebig erweitern und verkomplizieren. Eine Variante, die als Nim bekannt ist, funktioniert wie folgt: anstatt einer Reihe liegen mehrere Reihen von Streichhölzern auf dem Tisch. Wieder spielen 2 Spieler, die sich abwechseln. Der sich am Zug befindende Spieler wählt zuerst eine der Reihen mit verbleibenden Hölzern aus und entnimmt ihr mindestens ein und beliebig viele Streichhölzer. Wie zuvor verliert der Spieler, der das letzte Streichholz vom Tisch nimmt. Dieses Spiel kann in ganz ähnlicher Weise analysiert werden und auch für dieses Spiel existiert eine geschlossene Formel, die die Gewinnstrategie beschreibt.

Das Spiel Nim ist sehr alt und stammt wahrscheinlich aus China (es ähnelt dem dort existierenden Spiel Tsyanshidzi). In Europa ist das Spiel wohl zuerst im 16. Jahrhundert aufgetaucht. Seinen Namen Nim erhielt das Spiel von Charles Bouton, der im Jahr 1901 auch zuerst die vollständige Analyse dieses Spiels veröffentlichte.

Unser Algorithmus zur Berechnung von GS[X] ist ein einfaches Beispiel für eine Verfahren, das man als dynamische Programmierung bezeichnet. Dieses Verfahren wurde in den 1940er Jahren von dem Amerikaner Richard Bellman entwickelt und ermöglicht das Lösen von Optimierungsproblemen, die sich in gleichartige Teilprobleme zerlegen lassen. In unserem Streichholzspiel lässt sich beispielsweise die Frage, ob ein Spieler aus einer Ausgangssituation mit X Streichhölzern eine Gewinnstrategie hat, auf die Antwort auf diese Frage aus einer Ausgangslage mit X-3, X-2 und X-1 Streichhölzern zurückführen.

Autor: Materialien: Externe Links: Für Inhalte und Verfügbarkeit der externen Links übernehmen wir keine Gewähr. (Haftungsausschluss)