Tic Tac Toe in Java
Programmieren des Spiels "Tic Tac Toe" in Java
Das Javaprogramm "Tic Tac Toe" dient der Vertiefung und Anwendung von
- Java AWT
- Interfaces
- Event Handling
- Exceptions
- 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:
- Tic Tac Toe Programmgerüst ttt_framework.zip (ge-ZIP-ter Java Sourcecode)
- Fertige Version von Tic Tac Toe ttt_final.zip (ge-ZIP-ter Java Sourcecode)
Eine kompakte Darstellung mit sämtlichem Javacode aller verwendeten Klassen ist ebenfalls verfügbar:
- Handout mit Sourcecode zum Tic Tac Toe Programmgerüst (PDF)
- Handout mit Sourcecode zur fertigen Version von Tic Tac Toe (PDF)
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:
- BadValueException.java (Java Sourcecode)
- BadValueExceptionTest.java (Java Sourcecode)
- Code beider Klassen auf einem Blatt (PDF)
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:
- Folien (Word, PDF)
- Kompakte Darstellung zum Verteilen (PDF)
Ü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!