/** Spielt das originale NIM-Spiel aus dem Film: "Letztes Jahr in Marienbad" * @author H.Peter Gumm * @version 9.2.2007 * * Regeln: Wir beginnen mit drei Reihen von Streichhölzern * Zwei Spieler ziehen abwechselnd * Ein Zug besteht darin, * - eine (nichtleere) Zeile auszuwählen und daraus beliebig viele, * aber mindestens ein Streichholz zu entfernen * Verloren hat, wer am Zug ist, obwohl kein Streichholz mehr vorhanden ist. */ public class NIM{ /** berechnet, ob der Ziehende, eine Gewinnstrategie hat * @param z1 Streichhölzer in Reihe 1 * @param z2 Streichhölzer in Reihe 2 * @param z3 Streichhölzer in Reihe 3 * @return true, falls der Spieler am Zug eine Gewinnstrategie hat */ static boolean win(int z1, int z2, int z3){ return (z1+z2+z3 > 0) && ( win1(z1,z2,z3) || win2(z1,z2,z3) || win3(z1,z2,z3) ); } /** Kann der der am Zug ist, gewinnen, indem er aus der * ersten Zeile einige Streichhölzer wegnimmt ? */ private static boolean win1(int z1, int z2, int z3){ for(int i=z1; i>0; i--){ if( ! win(z1-i,z2,z3)) return true; // Achtung: win(...) nicht win1(...) !!! } return false; } // Diese könnte man sich sparen, wenn man die Aufrufe gleich in win(...) einsetzt private static boolean win2(int z1, int z2, int z3){ return win1(z2,z1,z3); } private static boolean win3(int z1, int z2, int z3){ return win1(z3,z2,z1); } /** * @param z1 Anzahl der Streichhölzer in Reihe 1 * @param z2 Anzahl der Streichhölzer in Reihe 2 * @param z3 Anzahl der Streichhölzer in Reihe 3 * @return Zug oder Aufgabe, falls Gegner Strategie hat. */ static String ziehe(int z1, int z2, int z3){ for (int i=z1; i>0; i--) if( ! win(z1-i,z2,z3) ) return "Ziehe "+i+" aus Reihe 1"; for (int i=z2; i>0; i--) if( ! win(z1,z2-i,z3) ) return "Ziehe "+i+" aus Reihe 2"; for (int i=z3; i>0; i--) if( ! win(z1,z2,z3-i) ) return "Ziehe "+i+" aus Reihe 3"; return "Ich habe keine Lust mehr"; } }