MiniMax in Delphi

Zweieinhalb Jahre sind nun vergangen, seit das Buch "Schach am PC" erschienen ist. Diese hochinteressante Lektüre stellt die grundlegenden Techniken der Schachprogrammierung auf verständliche Art und Weise vor. MiniMAX, ein kleines didaktisches Schachprogramm, diente dazu die im Buch erläuterten Techniken an einem praktischen Beispiel zu veranschaulichen. Das Programm hatte allerdings einen kleinen Hacken: Es fehlte eine graphische Ansicht des Brettes, es gab keine Mausbedienung, keine Pulldown Menues - mit anderen Worten die Bedienerfreundlichkeit ließ zu wünschen übrig. Außerdem war das Programm für das "Betriebssystem" DOS konzipiert. Daß Windows bezüglich des Komforts einfach mehr zu bieten hat, bestreitet wohl niemand, lediglich der Geschwindigkeitsverlust bereitete den Windows Kritikern etwas Kopfschmerzen. Seit sich aber unter den "großen" der Kommerziellen (Fritz, Chess Genius ) der Trend hin zu Windows eindeutig abzeichnet und diese auch in der Computerrangliste auf den vorderen Plätzen zu finden sind, sollten auch die letzten Kritiker überzeugt sein. Auch MiniMAX sollte den Sprung in die Fensterwelten schaffen - als Entwicklungsumgebung diente dabei ein wahrhaft geniales Programmierwerkzeug: Borland Delphi.

Delphi, was ist das?

Delphi bietet einen sehr bequemen Weg zur Entwicklung von Windows-Anwendungen. Es kombiniert die Geschwindigkeit und die einfache Verwendungsweise einer visuellen Entwicklungsumgebung mit der Leistungsfähigkeit, Flexibilität und der Wiederverwendbarkeit einer vollständig objektorientierten Sprache, dem weltweit schnellsten Compiler und einer führenden Datenbanktechnologie. Visuelle Entwicklung bedeutet dabei, daß ein Großteil der Arbeit mit Delphi nicht darin besteht Programmcode einzutippen, sondern man gestaltet seine Anwendung, also die Fenster mit ihren Windows Elementen wie Buttons, Listboxen, Menues usw, wie mit einem Grafikprogramm. Soll ein Fenster einen neuen Knopf zum anklicken enthalten, so zieht man diesen einfach mit der Maus aus der Werkzeugleiste in das Programmfenster und stellt noch einige Eigenschaften ein wie Breite, Höhe, Beschriftung. Was einmal geschehen soll wenn der Anwender diesen Knopf anklickt, ist zu dieser Zeit noch nicht bekannt und wird erst später festgelegt. Dazu dienen Ereignisse, die sich bei den verschiedenen Elementen ereignen können. Ein Klick auf einen Button löst beispielsweise ein "OnClick" Ereignis aus und es wird der Programmcode ausgeführt, den der Entwickler diesem Ereignis zugeordnet hat. Als Entwickler muß man sich also nicht mehr um das Verhalten der Windowselemente kümmern, Arbeiten wie das Erzeugen von Fenstern, Menues, Scrolling usw. nimmt Delphi dem Entwickler vollkommen ab.

Als Sprache zum Programmieren dient dabei Object-Pascal. Dabei handelt es sich um eine Weiterentwicklung von Turbo-Pascal, welches nun um die Möglichkeiten der Objektorientierten Programmierung (OOP) erweitert worden ist. In MiniMAX wurde allerdings weitgehend darauf verzichtet, spezielle Fähigkeiten von Delphi oder der OOP zu nutzen, den Quellcode sollte also jeder verstehen, der ein bißchen Pascal kann.

Von Basic nach Pascal

Ursprünglich lag MiniMAX in einer C- und in einer Basic-Version vor. Solange man einigermaßen beim Grundwortschatz bleibt sind Basic und Pascal recht ähnlich, deshalb können Basic Programme nahezu 1:1 nach Pascal übersetzt werden. Diesen Umstand habe ich mir bei der Umsetzung auf Windows zunutze gemacht. Als Vorlage diente also die Basic Version, die Prozeduren und Funktionen wurden weitgehend beibehalten, zwar waren einige davon nicht mehr notwendig (PrintLogo, KommandoSchleife, Brettausgabe), dafür kamen aber neue hinzu (ChessDiagram2D1MouseUp zum Erkennen eingegebener Züge, sowie alle Ereignisbehandlungsroutinen). Aus Basic Anweisungen wie z.B.

  IF <Bedingung> THEN <Anweisungen> ENDIF

wurden Pascal Anweisungen:

  IF <Bedingung> THEN BEGIN <Anweisungen> END.

Um in Basic einigermaßen komfortabel und lesbar mit Wahrheitswerten (boolschen Variablen) umzugehen gibt es einen allgemein gebräuchlichen "Trick": Man deklariert zwei Konstanten Wahr und Falsch. Die Konstante Wahr erhält den Wert 1, Falsch den Wert 0. Die Null wird im Gegensatz zu allen anderen Werten vom Compiler als nicht erfüllte Bedingung interpretiert. In Pascal ist für Wahrheitswerte ein elementarer Datentyp namens Boolean vorgesehen. Bei der Übersetzung von Basic nach Pascal wurde dieser Datentyp an allen Stellen eingesetzt, wo Basic mit den Konstanten arbeitete, so daß auf diese Konstanten verzichtet werden konnte.

Das Schachbrett

Viele Schachspieler ziehen es bei einer ernsten Partie gegen den Computer zwar vor, die Züge auf ein herkömmliches Schachbrett zu übertragen, aber wenn man nur mal so spielen oder eine Veränderung am Programm testen will ist diese Methode etwas umständlich. Einer der größten Mängel von MiniMAX war die fehlende graphische Ausgabe des Schachbretts. Auch hier bietet Delphi ein gut durchdachtes Konzept: Die Komponenten. Komponenten sind meist visuelle Objekte, die man der Delphi VCL (Visual Component Libary) der Werkzeugleiste hinzufügen kann. Diese können dann immer wieder auch mehrfach in den Programmen eingesetzt werden, ohne diese jedesmal neu zu programmieren. Einige Entwickler sind sogar so nett und stellen ihre selbst geschriebenen Komponenten anderen Delphi - Programmierern kostenlos zur Verfügung. So auch Michael Leahy der ein graphisches Schachbrett als Delphi Komponente entwickelt hat, das sich immer da, wo man ein Schachbrett braucht, mit einem Mausklick in die eigene Anwendung integrieren läßt. Natürlich funktioniert nach dem bloßen Einfügen noch nicht all zu viel. Die Komponente stellt die Zugeingabe zur Legalitätsprüfung zur Verfügung, falls man der Komponente mitteilt, daß der Zug legal war, wird dieser auf dem Brett ausgeführt. Um das Gleiten der Figuren, das Aufnehmen und Absetzen der Figuren mit der Maus braucht sich der Entwickler nicht zu kümmern, diese Funktionalität stellt die Komponente bereit. Auch das Drehen des Brettes ist denkbar einfach, man setzt lediglich die Eigenschaft "WhiteIsAtBottom" auf den Wert TRUE oder FALSE.

Die Stellungseingabe

Die meiste eigene Arbeit steckt wohl in der Stellungseingabe. Hier bietet MiniMAX nun einigen Komfort, wie die "Großen". Man wählt sich eine Figur zum Setzen aus, nun kann man mit der linken Maustaste durch klicken auf das entsprechende Feld setzen, mit der rechten Maustaste die gleiche Figur in der anderen Farbe. Wird die Stellungseingabe aufgerufen, so wird zunächst einmal die Stellung vom MiniMAX Brett übernommen. Die Legalität der Stellung wird grob überprüft, der OK-Knopf läßt sich also erst dann anklicken, wenn folgende Bedingungen erfüllt sind:

Verantwortlich für die Stellungseingabe ist die Funktion GetPosition in der Unit SetBrett. Zur Übergabe bzw. Rückgabe einiger Daten dient der folgende record:

TSetBrett = record
  Brett : TBrett;        {Das Schachbrett}
  AmZug : Integer;       {1 falls Weiß am Zug, -1 sonst}
  Weiss00,               {kleine Rochade Weiß}
  Weiss000,              {große Rochade Weiß}
  Schwarz00,             {kleine Rochade Schwarz}
  Schwarz000 : Boolean;  {große Rochade Schwarz}
  Abgebrochen : Boolean; {TRUE falls abgebrochen, FALSE sonst}
  EPLinie : Char;        {en passant Linie, noch nicht implementiert}
end;

MiniMAX in Aktion

Natürlich zählt MiniMAX nicht zu den Spitzenprogrammen im PC Bereich, selbst für die besseren Sharewareprogramme dürfte es nicht ganz reichen. Aber ich hab auch schon schlechtere Programme gesehen und erstrangiges Ziel von MiniMAX ist auch nicht die Spielstärke sondern das Veranschaulichen von grundlegenden Schach - Programmiertechniken. Dieses Ziel wurde mit MiniMAX auch erreicht, ich kenne kein zweites Programm, das so gut strukturiert und kommentiert ist. Trotzdem macht es Spaß MiniMAX auch einmal in der Praxis auszuprobieren. Es folgt eine Partie gegen Fritz 4.01, um die Programme wenigstens einigermaßen vergleichbar zu machen wurden Fritz etwas die Handschellen angelegt. Als Spielstufe wurde ebenso wie bei MiniMAX eine feste Suchtiefe von fünf Zügen eingestellt. Das Permanent Brain wurde abgeschaltet, ebenso wie das Eröffnungsbuch. So suchten beide Programme in etwa gleich tief, Fritz auf Grund der Selektivität in einigen Varianten weit tiefer. Genug der Worte:

MiniMAX vs Fritz 4.01 (1-0)

Hoppala, spielt MiniMAX besser als Fritz? Wohl nicht, der Vergleich hinkt gewaltig, denn Fritz braucht für die Rechentiefe von fünf Zügen wesentlich weniger Zeit als MiniMAX. Außerdem ist Fritz nicht dahin ausgelegt nur 5 Züge tief zu rechnen und zugegeben, es hat auch nicht auf Anhieb geklappt, daß MiniMAX gewinnt.

Was kann man noch tun um MiniMAX weiter zu verbessern? Einige sehr ausführlich beschriebene Tips liefert das oben genannte Buch, diese kann ich an dieser Stelle nicht alle wiederholen. Darüber hinaus würde es die Spielstärke sicherlich enorm verbessern, wenn man bei der Zugberechnung die dreimalige Stellungswiederholung berücksichtigen würde. MiniMAX hat schon einige gewonnene Partien durch dreimalige Wiederholung der Stellung zum remis verdorben, da er von dieser Regel noch keine Ahnung hat. Schön wäre es auch, wenn die 50 Züge-Regel noch eingebaut würde, dann wäre MiniMAX wenigstens im Hinblick auf die Schachregeln komplett.