Aufgabenblatt Nr. 5 Generizität und TicTacToe 1 Generische Sortier-Methode 1.1 Aufgabe: Entwickeln einer generischen Sortiermethode für Objekte mit der Schnittstelle Comparable Ihnen ist aus der Vorlesung GOOP der Sortieralgorithmus Bubble-Sort bekannt. Zur Erinnerung, hier die Variante zum Sortieren eines Arrays über int. 1 public static void bubblesort(int[] xs) { 2 boolean unsorted=true; 3 while (unsorted) { 4 unsorted = false; 5 for (int i=0; i < xs.length-1; i++) { 6 if (!(xs[i] < xs[i+1])) { 7 int dummy = xs[i]; 8 xs[i] = xs[i+1]; 9 xs[i+1] = dummy; 10 unsorted = true; 11 } 12 } 13 } 14 } Ihre Aufgabe ist es nun, den oben stehenden Bubble-Sort als generische Methode zu implementieren. Der generische BubbleSort soll alle Objekte sortieren können, die die Schnittstelle Comparable implementiert haben. Schlagen Sie bitte hierzu die genaue Funktionsweise der Schnittstelle Comparable in der JAVA-API nach: http://download.oracle.com/javase/6/docs/api/java/lang/comparable.html Es ist eine Klasse SortableElement gegeben, welches die Comparable Schnittstelle wie folgt implementiert. 1 class SortableElement implements Comparable<SortableElement> { 2 int data1 = 0; 3 int data2 = 0; 4 5 public SortableElement(int i, int j) { 6 data1 = i; 7 data2 = j; 8 } 9 10 public int compareto(sortableelement o) { 11 return data1 - o.data1; 1
1 Generische Sortier-Methode 2 12 } 13 14 public String tostring() { 15 return "(" + data1 + ", " + data2 + ")"; 16 } 17 } Bestimmen Sie nun die zu generalisierenden Anteile in der Methode bubblesort und schreiben Sie bubblesort so in eine generische Methode um, dass Sie alle Arrays über Klassen mit dem Interface Comparable sortieren kann. Testen Sie Ihre Methode mit folgenden Codezeilen: 1 SortableElement[] ys = { 2 new SortableElement(1, 2), 3 new SortableElement(4, 2), 4 new SortableElement(3, 5), 5 new SortableElement(1, 6) 6 }; 7 bubblesort(ys); 8 for (SortableElement y : ys) 9 System.out.println(y); Diese Zeilen sollten folgende Ausgabe produzieren (da TestElemente nach dem data1 Datenfeld sortiert werden): (1,2) (1,6) (3,5) (4,2) Schreiben Sie anschließend die Klasse TestElement so um, dass folgende Reihung durch bubblesort entsteht (also nach data2 sortiert wird): (1,2) (4,2) (3,5) (1,6) 1.2 Aufgabe: Sortieren von Figuren nach Fläche Erweitern Sie nun die Lösung des Aufgabenblatts 4 so, dass die abstrakte Klasse FigMZLA die Schnittstelle Comparable derart implementiert, dass Figuren nach Flächengrößen sortiert werden können. Nutzen Sie Ihre Implementierung von bubblesort aus Aufgabe 1.1. Wenn Sie diese richtig implementiert haben, müssen Sie nun endlich nicht mehr, für jeden neuen Datentyp eine neue Sortierroutine schreiben. Endlich können Sie wiederverwenden! Testen Sie Ihre Methode mit den folgenden Codezeilen: 1 FigMZLA[] figuren = { 2 new Rechteck(5, 5, -10, 10, 20), 3 new RWDreieck(30, 2, 80, 3, 4), 4 new Ellipse(4, 10, 31, 10, 20), 5 new Kreis(10, 10, 31, 5), 6 new Quadrat(100, 200, 13, 35), 7 new Quadrat(100, 200, 5, 35) 8 };
2 Aufgabe: Entwicklen einer eigenen generischen Klasse (Bsp. Stack) 3 9 10 bubblesort(figuren); 11 12 for (FigMZLA f : figuren) System.out.println(f); Diese sollten die folgenden Ergebniszeilen produzieren: Rechteck an Position (?,?,?) mit einer Fläche von? Flächeneinheiten Ellipse an Position (?,?,?) mit einer Fläche von? Flächeneinheiten Die? bezeichnen, die durch Sie hoffentlich korrekt berechneten bzw. ausgegebenen Werte. 2 Aufgabe: Entwicklen einer eigenen generischen Klasse (Bsp. Stack) Ihnen ist die Klasse Stack aus der Vorlesung GOOP bekannt. Ihre Aufgabe ist es nun, unter Nutzung der Klasse Stack eine generische Klasse GenStack zu entwickeln (nutzen Sie hierzu nicht, die generische Variante der Stack- Klasse der JAVA-5/6 Umgebung sondern implementieren Sie eine generischen Stack selber, um das Prinzip generischer Klassen zu verstehen). Die Klasse GenStack soll die Methoden push(), pop(), peek() und isempty() implementieren und generisch für alle Typ-Parameter T gelten. GenStack soll nicht von Stack abgeleitet (keine Subklasse) sein, sondern einen Stack kapseln (sogenannte Wrapper-Klasse). Schlagen Sie bitte hierzu die genaue Funktionalität oben genannter Methoden in der JAVA-API nach und implementieren Sie diese analog. http://download.oracle.com/javase/6/docs/api/java/util/stack.html Prüfen Sie ihre Implementierung mit folgenden Codezeilen: 1 // Instanziieren eines aktuell parametrisierten Stacks mit konkreten Typ-Parameter 2 GenStack<Figur> mystack = new GenStack<Figur>(); 3 4 // Ein wenig Testcode, um die Logik zu testen 5 System.out.prinltn(mystack.push(new Kreis(10, 10, 2, 25)); 6 System.out.println(mystack.push(new Quadrat(5, 5, 4, 37)); 7 System.out.println(mystack.push(new RWDreick(5, 7, 4, 10, 13)); 8 System.out.println(mystack.peek()); 9 System.out.println(mystack.pop()); 10 System.out.println(mystack.pop()); 11 System.out.println(mystack.pop()); 12 13 } 14 } Diese Zeilen sollten die folgenden Ergebniszeilen produzieren:
3 TicTacToe 4 3 TicTacToe Im Rahmen der Vorlesung werden Ihnen objektorientierte Entwurfsprinzipien am Beispiel des Spiels Tic Tac Toe veranschaulicht. Bitte bearbeiten Sie diese Aufgabe unbedingt vor dem Aufgabenblatt Nr. 6. Nutzen Sie hierzu auch die Zeit, die Ihnen im Rahmen des Tutoriums ergänzend ermöglicht wird. Befolgen Sie bitte die folgenden Schritte: 1. Laden Sie sich die Tic Tac Toe Engine von folgender Seite herunter (a) http://praktische-informatik.fh-luebeck.de/sites/default/files/oop-tictactoe.zip 2. Importieren Sie dieses Projektarchiv wie gewohnt in Ihre Eclipse Programmierumgebung 3. Fügen Sie in ihrem Projekt, welches Sie für dieses Aufgabenblatt angelegt haben, nun die Tic Tac Toe Engine zu Ihrem Buildpath hinzu. (a) Selektieren Sie Ihr Projekt im Package Explorer anschließend Rechte Maustaste -> Properties (b) Selektieren Sie JAVA Build Path -> Projects (c) Klicken Sie anschließend auf Add und fügen Sie ihr Tic Tac Toe Project hinzu In der T3 Engine gibt es eine sogenannte T3Starter Klasse im Paket de.fhl.oop.tictactoe.engine. Diese dient dazu ein Spiel zwischen zwei Tic Tac Toe Spielern zu starten. Die T3 Engine bietet im Paket de.fhl.oop.tictactoe.player weiterhin die folgenden Spieler an: CrazySpieler -dieserspielersuchtzeilenweiseeinleeresfeldundsetztaufdaserstedaserfindet Katastrophenspieler - dieser teilt bei jedem Spielzeug durch null und verliert daher immer (wurde nur für Testzwecke benötigt) Zufallsspieler -diesersetztzufälligauffreiefelder und der abstrakte Spieler T3VersierterSpieler erweitert den T3Spieler, umzweizusätzlichemethoden leere_felder und gewinnfelder, dieesihmermöglichen,leerefelderundsolchefelderzubestimmen,die im nächsten Zug für einen der Spieler den Gewinn bringen würden. Diese beide Methoden machen es Ihnen einfacher intelligentere Strategien zu entwickeln. In dieser Übung sollen Sie vorerst nur herausfinden, welche von den beiden Strategien des CrazySpieler und des ZufallsSpieler die bessere ist. Lassen Sie hierzu beide Spieler eine Partie mit jeweils 1000 Spielen durchspielen und schauen Sie, welche Spieler mehr Spiele gewonnen hat.
3 TicTacToe 5 1 import de.fhl.oop.tictactoe.engine.t3starter; 2 import de.fhl.oop.tictactoe.player.*; 3 4 public class Testspiel { 5 6 public static void main(string[] args) { 7 T3Starter.starte_partie(1000, new CrazySpieler("Crazy"), new ZufallsSpieler("Zufall")); 8 } 9 } Welches ist die bessere Strategie? Auf das erste leere Feld zu setzen? Oder zufällig zu setzen? Entwickeln Sie nun zu Hause und im Tutorium Ihre eigene Strategie. Entwickeln Sie Ihre eigene Spielklasse, in dem Sie diese von T3VersierterSpieler ableiten. Bringen Sie diese Klasse zur nächsten Übung mit. Dort sollen Sie gemeinsam eine Logik implementieren, die es ermöglicht, alle Ihre Spieler gegeneinander spielen zu lassen, um in Ihrer Übungsgruppe den Tic Tac Toe Meister zu ermitteln.