Tic Tac Toe in Java

Programmieren des Spiels "Tic Tac Toe" in Java

Screenshot Tic Tac Toe

Das Javaprogramm "Tic Tac Toe" dient der Vertiefung und Anwendung von

  1. Java AWT
  2. Interfaces
  3. Event Handling
  4. Exceptions
  5. File I/O

Es wurde an der Technischen Berufsschule in Zürich während eines Unterrichtspraktikums im Sommer 2000 bei den Applikationsinformatikern im 2. Lehrjahr erprobt und hat stark zur Motivation der Schüler beigetragen.
Die oben erwähnten Techniken von Java wurden schrittweise während einer Woche eingeführt und das neue Wissen in Zweiergruppen zur Erweiterung des Programmgerüstes von "Tic Tac Toe" verwendet. Nach zehn Stunden Unterricht mit integrierten Programmierübungen hatte jede Gruppe eine lauffähige Version entwickelt.

Vorgehen

Allgemeines zum Spiel Tic Tac Toe:

Zwei Spieler setzen abwechslungsweise eine Null (nought) bzw. ein Kreuz (cross) in ein noch leeres Feld. Wer zuerst drei seiner Symbole in einer Linie (horizontal, vertikal oder diagonal) angeordnet hat, gewinnt. Sind alle neun Felder des 3x3 Spielfeldes besetzt, dann ist unentschieden.

Bereitgestellte Materialien:

Die hier bereitgestellten Materialien sind für Lehrzwecke frei verwendbar; kommerzielle Verwendung nur mit schriftlicher Einwilligung des Autors. Die Materialien dienen primär der Ergänzung einer theoretischen Einführung der erwähnten Programmierthemen im Unterricht.

Technische Voraussetzungen:

Die Schüler haben zu zweit einen Computer mit installiertem Java Runtime Environment 1.2.x und Java SDK 2.0 zur Verfügung.

Bemerkungen zur Implementierung des Spiels Tic Tac Toe:

Das Spiel wurde modular aufgebaut und umfasst folgende Klassen:

TTT Hauptklasse für Tic Tac Toe (u.a. GUI ohne Spielfeld)
TTTBoard Klasse, die das Spielfeld GUI als 3x3 Buttons anlegt und auf Buttonklicks reagiert, um Spielzüge auszuführen
TTTDialog Klasse, die eine Dialogbox darstellt mit einem vorgegebenen Titel, einem Meldungs-Text und einem Button mit vorgegebenem Labeltext. Der Dialog schliesst sich bei Klick auf den Button selbständig.
TTTDialogTest Klasse zum Testen von TTTDialog, losgelöst von anderen Klassen (wird für Tic Tac Toe nicht benötigt)
TTTFileIO Klasse zum Laden und Speichern von Tic Tac Toe Spielständen
TTTComputerPlayer Klasse mit der Logik eines einfachen Tic Tac Toe Computerspielers mit minimaler Intelligenz

Ausgehend vom Tic Tac Toe Programmgerüst wird in den Programmierübungen die fertige Version von Tic Tac Toe entwickelt:

Eine kompakte Darstellung mit sämtlichem Javacode aller verwendeten Klassen ist ebenfalls verfügbar:

Der Zustand des Spieles ist gespeichert in:

  • status (BEREIT oder FERTIG),
  • aktuellerSpieler (SPIELER_O oder SPIELER_X),
  • anzahlGespielteZuege und
  • spielfeld[0..8].

In int spielfeld[0..8] wir die Belegung der Felder von links oben nach rechts unten zeilenweise gespeichert als LEER (=0), SPIELER_O (=1) oder SPIELER_X (=10). Diese Belegung mit konstanten Werten erlaubt effiziente Tests, ob einer der Spieler in einer Linie drei seiner Symbole hat (bei einer Summe von 3 ist es SPIELER_O, bei einer Summe von 30 ist es SPIELER_X).

Die aktuelle Gewinnsituation wird von istSpielFertig() als UNKLAR (d.h. Spiel ist noch nicht fertig), SPIELER_X, SPIELER_O oder UNENTSCHIEDEN ermittelt.

1. GUI für Tic Tac Toe mit Java AWT

Theorie:

Die wichtigsten GUI Komponenten im Java 1.2 AWT (abstract windowing toolkit) wie Frames, Label, List, Button und Menu werden vorgestellt. Swing, das auf AWT basiert, muss für die Übung nicht eingeführt werden.

  • Arbeitsblatt GUI 1 (Word, PDF) zur Einführung des AWTs: Frames, Label, List.
  • Folie mit allen GUI Beispielen von Arbeitsblatt GUI 1 und 2 (Word, PDF)

Die Layout Manager von Java und die Verschachtelung der Container wird erklärt.

  • Arbeitsblatt GUI 2 (Word, PDF) mit einem umfangreichen Beispiel mit vielen verschiedenen AWT Komponenten.

Übung:

a) Das in Zweiergruppen zu programmierende GUI von Tic Tac Toe wird anhand eines Screenshots vorbesprochen.
Die Schüler schlagen vor, wie sie die GUI Komponenten mit Layout Managern anordnen wollen und die Lehrperson erstellt eine Skizze dazu. Diese Skizze dient als Grundlage für die Programmierung des GUIs ausgehend vom Tic Tac Toe Programmgerüst.
Der Konstruktur von TTT wird um die GUI Elemente ohne Ereignisbehandlung ergänzt gemäss den Kommentaren in der Datei TTT.java.

  • Folie mit Screenshots des GUIs von Tic Tac Toe (Word, PDF) als Programmgerüst und als fertige Version

b) In der Klasse TTTDialog, einer Hilfsklasse zur Anzeige von einfachen Meldungsdialogen wie "Spieler X hat gewonnen" inklusive ok-Button, werden die GUI Elemente gemäss den Kommentaren in TTTDialog.java ergänzt, jedoch ohne Ereignisbehandlung. Der Dialog kann mit der vorgegebenen Klasse TTTDialogTest getestet werden.

2. Interfaces (Schnittstellen)

Bevor die Ereignisbehandlung eingeführt wird, sollte als Grundlage das Konzept der Schnittstellen in Java eingeführt werden.
Das "Monsterbeispiel" mit einer Einteilung von Monstern in verschiedene überlappende Gruppen zeigt auf einfache Weise, wieso gewisse Hierarchien von Objekten in Java nur mittels Interfaces (nicht jedoch mittels Vererbung von Klassen) sauber implementiert werden können.

  • Arbeitsblatt Interfaces A (Word, PDF): Mengendiagramm
  • Arbeitsblatt Interfaces B (Word, PDF): UML-Diagramm
  • Arbeitsblatt Interfaces C (Word, PDF): Implementierung in Java

3. Event Handling (Ereignisbehandlung)

Theorie:
Sobald folgende Lernziele erreicht sind, kann die Ereignisverarbeitung zu Tic Tac Toe implementiert werden:
Jeder Schüler

  • kann Beispiele von Ereignissen aufzählen und diese in Low Level und semantische Ereignisse einteilen
  • kann einem Java-Anfänger erklären, wie Ereignisse in Java umgesetzt wurden (u.a. Klasse AWTEvent)
  • weiss, wie eine Klasse über Ereignisse informiert werden kann (u.a. Listener Interfaces)
  • kann zusammen mit der Java online Dokumentation eine Ereignisbehandlung implementieren

Übung:
In der Klasse TTT und TTTDialog soll im Konstruktor und in der Prozedur actionPerformed(...) die Ereignisbehandlung implementiert werden. In in der Klasse TTTBoard soll die Ereignisbehandlung für den ok-Button ergänzt werden.

4. Exceptions (Ausnahmen) und Errors

Theorie:
Da beim File I/O Exceptions auftreten können, empfiehlt es sich, nun die Exceptions einzuführen. Die Schüler sollten danach die Unterschiede zwischen Error und Exception kennen und Exceptions in checked und non-checked Exceptions einteilen können. Die Schlüsselwörter try, catch, throw und finally sowie die Deklaration mit throws bilden die Grundlage zur erfolgreichen Anwendung von Exceptions.

Übung "Münzen aufteilen":
Als Aufgabe wird eine bestimmte Anzahl Münzen auf eine Gruppe von Personen fair aufgeteilt. Da eine einzelne Münze nicht zerteilt werden kann und da keine Münzen übrig bleiben sollen, werden in gewissen Fällen Exceptions geworfen. Dazu wird eine eigene Exception mit Namen "BadValueException" programmiert und in einem Testprogramm verwendet:

Bemerkung: Es mag interessant sein zu wissen, dass bei einer Division von a / b mit a und b vom Typ float oder double (d.h. Fliesskommazahl) und b= 0.0 keine ArithmeticException auftaucht wie bei der im Beispiel verwendeten Integerdivision. Der Grund ist im von Java weitgehend implementierten Fliesskommastandard IEEE-754-1985 zu finden, welcher 1.0 / 0.0 als plus unendlich repräsentiert.

5. File I/O (Dateiein- und Ausgabe)

Theorie:

Die Kapselung, welche Java bei der Ein- und Ausgabe verwendet, soll vorgestellt und anhand verschiedener Javacode Beispiele erklärt werden. Die Konzepte von "physikalischer Schicht", Stream (als Folge von Bytes) und semantischer Schicht können leicht anhand der Abhängigkeiten von Klassen wie FileInputStream, BufferedInputStream und DataInputStream aufgezeigt werden.
Javacode Beispiele zu File I/O:

Übung:
Nun werden die neuen Kenntnisse zu Exceptions und File I/O angewendet. In der Klasse TTTFileIO wird die Prozedur spielSpeichern(...) gemäss den Kommentaren im Javacode ausprogrammiert. Dadurch kann ein Tic Tac Toe Spiel jederzeit abgespeichert und später wieder geladen und weitergespielt werden.

6. Abschluss

Nun fehlt nur noch wenig zum fertigen Tic Tac Toe. In der Klasse TTT muss nur noch die Prozedur istSpielFertig() gemäss den Kommentaren im Javacode ergänzt werden. Wenn dann noch Zeit bleibt, können die Schüler versuchen, eine Spielstrategie gegen den Computergegner zu finden, welche ihnen eine 100% Gewinnchance einbringt (was aber wegen Verwendung von Zufallsteilentscheiden nicht gelingen wird). Diese Übung lässt die Schüler verstehen, wie einfach die Logik eines Computergegners formuliert werden kann und wie schwierig dagegen die Strategie beim Spielen gegen den Computer zu durchschauen ist. Wer lieber programmiert, kann einen stärkeren Computergegner implementieren, der zum Beispiel gewisse Eröffnungstaktiken verwendet oder der durch Verwendung von Alpha-Beta-Pruning so stark wird, dass er nie geschlagen werden kann.

Viel Spass beim Einsatz von Tic Tac Toe als längere unterrichtsbegleitende Übung!