Fakultät für Informatik Wintersemester 2008 André Gronemeier, LS 2, OH 14 Raum 307, andre.gronemeier@cs.uni-dortmund.de PIWIN 1 Übung Blatt 5 Ausgabedatum: 19.12.2008 Übungen: 12.1.2009-22.1.2009 Abgabe: Lösungen bitte spätestens einen Werktag vor der Übung per Email abgeben. Achtung: Aufgrund des krankheitsbedingten Ausfalls von Vorlesungen im Dezember finden in der Woche vom 5. Januar bis zum 9. Januar keine Übungen statt. Übungen: Gruppe Mo-ungerade: 12. Januar, 8:30 Uhr, OH 14 Hörsaal E 23 Gruppe Do-ungerade: 15. Januar, 10:15 Uhr, OH 16 Raum 205 Gruppe Di-gerade: 20. Januar, 10:15 Uhr, OH 16 Raum 205 Gruppe Do-gerade: 22. Januar, 10:15 Uhr, OH 16 Raum 205 Aufgabe 5.1: Klassenvariablen, Referenzen, überdeckte Attribute und überladene Methoden In Listing 5.1 ist ein kleines Programm angegeben, das aus insgesamt drei Klassen besteht. In der main-methode sind sieben Zeilen durch Kommentare markiert. Eine dieser Zeilen ist fehlerhaft. Suchen Sie die fehlerhafte Zeile und geben Sie an, worin der Fehler besteht. Geben Sie nun jeweils den Wert der folgenden Attribute nach der Ausführung der fehlerfreien markierten Zeilen tabellarisch an: a.x a.y a.z b.x b.y b.z c.x c.y c.z Begründen Sie Ihre Ergebnisse kurz stichwortartig.
class C1 public int x ; public static int y ; private int z ; Listing 1: Listing 5.1 public C1( int i, int j, int k ) x = i ; y = j ; z = k ; public void m1( int y, int z ) x = y ; y = z ; public void m2( int x, int z ) y = x ; this. x = z ; this. z += z ; class C2 public static int x ; public int y ; public static int z ; public C2 ( ) x = y = z = 0 ; public void m1( C1 a ) x = a. y++; y = a. x ; z += a. x ; public void m1( C1 a, int z ) x += a. y ; y = a. x ; z = this. z ; class Main public static void main ( S t r i n g [ ] args ) C1 a, b ; C2 c ; a = new C1 ( 1, 2, 3 ) ; c = new C2 ( ) ; b = new C1 ( 4, 5, 6 ) ; // B e f e h l 1 a.m2( 7, 8 ) ; // B e f e h l 2 b.m1( 9, 1 0 ) ; // B e f e h l 3 b = a ; // B e f e h l 4 c.m1( a ) ; // B e f e h l 5 c.m1(b, 1 1 ) ; // B e f e h l 6 b.m2( b. x, a. z ) ; // B e f e h l 7
Aufgabe 5.2: Objekte und Referenzen Ein Wörterbuch Variablen speichern nur eine Referenz auf ein Objekt, nicht das Objekt selbst. Daher kann die folgende Klasse namens Node auch problemlos Attribute vom Typ Node enthalten: class Node public Node next ; public Node ( ) next = null ; Dies ist nicht nur zulässig, sondern auch sehr praktisch, denn auf diese Weise kann man Objekte zu einer Liste verketten: Angenommen wir haben eine Variable head vom Typ Node. Dann kann head.next auf ein weiteres Objekt vom Typ Node zeigen, welches wiederum auf ein Node-Objekt zeigt, und so weiter. Das Ende dieser Kette wird durch eine null-referenz markiert. Graphisch lässt sich die Situation folgendermaßen darstellen: head next next next Durch das Verfolgen der next-referenzen lassen sich von der Variable head aus alle Objekte dieser Kette erreichen. Vergrößern lässt sich die Liste durch das Anhängen neuer Node-Objekte, die man einfach mit dem new-operator erzeugen kann. Erweitern Sie die Klasse Node so, dass in den zugehörigen Objekten ein Deutscher und ein Englischer Begriff als String gespeichert wird und nutzen Sie die oben beschriebene Konstruktion von Listen, um damit ein Deutsch-Englisch-Wörterbuch als Klasse Dictionary zu implementieren. Sie sollten die folgenden Methoden unterstützen: class Dictionary public static void main ( S t r i n g [ ] args ) // Test der Dictionary Klasse public D ictionary ( ) // Legt l e e r e s Woerterbuch an public void i n s e r t ( S t r i n g german, S t r i n g e n g l i s h ) // Eintragen von Übersetzung public S t r i n g lookup ( S t r i n g german ) // Nachschlagen. Ergebnis i s t e n g l i s c h e Uebersetzung // oder n u l l, f a l l s k e i n e Uebersetzung gefunden wurde Natürlich dürfen (und müssen) Sie eventuell weitere Methoden und Attribute hinzufügen, um die gewünschte Funktionalität zu realisieren. In der main-methode soll die Klasse getestet werden. Hier sollten Sie selbst sinnvolle Tests finden.
Aufgabe 5.3: Eine Anwendung Tic Tac Toe In der objektorientierten Programmierung benutzt man Klassen, um die für die Anwendung wichtigen Objekte und Konzepte zu realisieren. Angenommen wir wollen ein Tic-Tac-Toe-Spiel implementieren. Die Regeln dieses Spiels findet man zum Beispiel in der Wikipedia: http://de.wikipedia.org/wiki/tic Tac Toe Ein wichtiges Konzept dieses Spiels ist offensichtlich das Spielfeld. Wir wollen in dieser Aufgabe das Tic-Tac-Toe-Spielfeld als Java-Klasse modellieren: class TicTacToe public TicTacToe ( )... public TicTacToe ( TicTacToe t )... public void p r i n t ( )... public Boolean zug ( int s p i e l e r, int z e i l e, int s p a l t e )... public int gewinner ( )... Der parameterlose Konstruktor soll ein leeres Spielfeld anlegen. Zusätzlich implementieren wir einen Konstruktor, der als Argument ein Tic-Tac-Toe-Spielfeld erhält und von diesem eine Kopie erstellt. Die Methode print soll das Spielfeld auf dem Bildschirm ausgeben. Die Zeilen und Spalten sollen in der Ausgabe nummeriert sein. Nach einigen Spielzügen könnte die Ausgabe folgendermaßen aussehen: 123 1.oo 2.x. 3.xx Mittels der Methode zug kann einer der Spieler sein Zeichen auf das Spielfeld zeichnen. Hier soll Spieler 1 das Zeichen x zugeordnet sein, während Spieler 2 mit dem Zeichen o spielt. Sollte der Zug nicht möglich sein, da z.b. die Parameter unzulässig sind oder das Feld bereits besetzt ist, soll false zurückgegeben werden, anderenfalls wird der Zug ausgeführt und das Ergebnis ist true. Mit der Methode sieg kann schließlich überprüft werden, ob einer der Spieler gewonnen hat. Das Ergebnis 1 oder 2 zeigt an, dass der entsprechende Spieler gewonnen hat, bei dem Rückgabewert 0 ist das Spiel noch unentschieden. Sollten beide Spieler drei Zeichen in einer Reihe haben (in einem normalen Spiel kann dies natürlich nicht vorkommen), so kann die Funktion entweder 1 oder 2 ausgeben. Ihre Aufgabe ist es nun, diese Klasse zu implementieren. Dazu müssen Sie zunächst eine passende Datenstruktur für die Repräsentation des Spielfelds wählen und anschließend die oben beschriebenen Operationen für diese Datenstruktur implementieren.
Aufgabe 5.4: Kooperierende Klassen Ein Tic-Tac-Toe-Spiel Nun wollen wir das Tic-Tac-Toe-Spielfeld aus der letzten Aufgabe benutzen, um ein Tic-Tac- Toe-Spiel für zwei Spieler zu implementieren. Das Spiel soll als Klasse TicTacToeGame umgesetzt werden. Hierzu muss das Spielfeld dargestellt werden, die Eingabe des Spielers, der gerade am Zug ist, muss eingelesen werden und nach dem Zug muss geprüft werden, ob der Spieler gewonnen hat. Da Eingaben nicht in der Vorlesung behandelt wurden und Sprachelemente erfordern, die noch nicht aus der Vorlesung bekannt sind, stellen wir auf der PIWIN-Webseite eine Klasse Eingabe zur Verfügung, die passende Methoden zur Eingabe von Zeichenketten und Spielzügen enthält: class Eingabe public static int z e i l e ; public static int s p a l t e ; public static S t r i n g s t r i n g L e s e n ( )... public static Boolean zuglesen ( int s p i e l e r )... Die Klassenmethode Eingabe.stringLesen() liest eine Benutzereingabe und gibt diese als String zurück. Mit der Klassenmethode Eingabe.zugLesen kann ein Tic-Tac-Toe-Zug eingelesen werden. Parameter ist die Nummer des Spielers, der am Zug ist. Nach dem Aufruf wird zunächst die Nummer des Spielers und ein kleiner Hilfstext ausgegeben. Der Spieler kann dann entweder die Zeile und die Spalte seines Zugs durch Leerzeichen getrennt eingeben oder er kann das Spiel durch die Eingabe von e abbrechen. Im ersten Fall ist der Rückgabewert true, im zweiten Fall false. Wenn ein Zug eingegeben wurde, kann man anschließend Zeile und Spalte aus den Klassenvariablen Eingabe.zeile und Eingabe.spalte auslesen. Die Datei Eingabe.java kann man zusammen mit einer eigenen Eingabedatei nutzen, indem man beide Dateien gleichzeitig in der Entwicklungsumgebung DrJava öffnet. Sind mehrere Dateien geöffnet, so kann man durch einen Rechtsklick auf den Dateinamen im linken Bereich des Fensters mit dem Menüpunkt Run File s Main Method auswählen, in welcher Datei die main-methode enthalten ist. Freiwillige Bonusaufgabe: Wer möchte, kann einen computergesteuerten Gegenspieler implementieren. Wie man dies umsetzen kann, ist auf den folgenden Seiten beschrieben: http://www.iti.fh-flensburg.de/lang/algorithmen/graph/spielbaum.htm http://de.wikipedia.org/wiki/minmax-algorithmus