1. Hausaufgabe (Version vom 11. Juli 2017) Allgemeines zu allen Aufgabenblöcken: • Lesen Sie den jeweils einleitenden Aufgabentext und die Aufgabenstellung genau. Damit Sie den erläuternden Text von den Aufgabenstellungen schnell unterscheiden können, sind Aufgaben und Hinweise durch jeweils spezifische Boxen gekennzeichnet • Bearbeiten Sie die Aufgaben zügig. Sollten sich bei der Bearbeitung Schwierigkeiten ergeben, die Sie nicht selber lösen können, so befragen Sie Ihren Betreuer (Hiwi) und bitten Sie ihn um Hilfestellung oder ergänzende Erläuterungen! Sie sollten sich nicht “stundenlang” an einem Problem “festbeißen”! • Lesen Sie in der angegebenen/empfohlenen Literatur und in unserem “Begleittext” nach eigenem Ermessen zu den im Folgenden angegebenen Inhalten des Aufgabenblocks. • Bitte beachten Sie den Netbeansguide und das Glossar. Teilaufgabe 1.1 - Einführung (5%) Nachfolgend sehen sie ein Beispiel für ein Java Programm. /* * @author Tina Turtle , Biotech . , 3. Sem . , Mat . Nr .: 2238968 * @version 21.1.2017 by Tina Turtle * * output of textstring " Hello , World " */ public class Hello { public static void main ( String [] args ) { System . out . println ( " Hello , World ! " ) ; } } Erläuterungen zum oben notierten Java-Quelltext: • Einige Dinge im Java-Quellcode werden Sie aller Voraussicht nach zum jetzigen Zeitpunkt nicht verstehen. Wir erklären sie der Vollständigkeit halber allerdings trotzdem. Im Laufe des Praktikums werden sie nach und nach mehr Verständnis erlangen, also machen Sie sich keine Sorge wenn es auf dem ersten Blick überwältigend wirkt. • Für Java Applikationen muss eine Klasse (class) definiert werden (hier durch: public class Hello). Der Name der Klasse muss identisch mit dem Dateinamen (hier: Hello.java) sein natürlich ohne das .java. Ohne explizites Zugriffsrecht kann eine Klasse nur innerhalb des Pakets, in dem sie definiert ist, genutzt werden. Mit dem Zugriffsrecht public versehene Klassen, sind “öffentlich”, d.h. von beliebigen anderen Programmteilen aus zugreifbar. Zwischen { und } ist der Körper (oder Rumpf) der Klasse notiert. Die (Haupt-)Klasse einer Java Applikation muss (zwingend) die Methode main implementieren: public static void main(String[] args). Bei Ablauf der Applikation wird als erstes automatisch diese Methode aufgerufen. 1 Hinweis Die Methode main wird als void deklariert, da sie zum Ende keinen Wert an eine übergeordnete Klasse zurückgibt. Es gibt für main keine explizite Stelle des Aufrufs. Formal muss sie im Kopf mit String[] args zur Übergabe von string-Parametern versehen sein. Der Modifizierer static besagt, dass sie aufgerufen werden kann ohne dass zuvor eine Instanz (ein Objekt) der Klasse angelegt wurde. In der Methode main wird in diesem Beispiel intern die Methode println aufgerufen. In Klammern steht die an die Methode übergebene Zeichenkette (String), die ausgegeben werden soll. Zeichenketten werden in Java zwischen zwei Anführungszeichen (") notiert, um sie von z.B. Variablennamen zu unterscheiden. Da die Methode println nicht im vorliegenden Programm implementiert ist, sondern von außerhalb aus einer Java Klasse StdPrintStream unseres package eip benutzt wird, muss diese zu Beginn des Programms importiert werden per import eip.*;. • Das Beispielprogramm enthält einen Kommentar (in /* und */ eingeschlossen). Hier benennt er den Autor, die Version und die Funktion des Programms. Mit Kommentaren versucht man einen Programmquelltext für Außenstehende besser erfaßbar zu machen. Kommentare werden beim Übersetzen eines Java-Quelltextes nicht in den Java-Bytecode übernommen. Hinweise . Kommentare können in Java auch mit // eingeleitet werden. Nachfolgender Text gilt dann bis zum Zeilenende als Kommentar. . Auf @author und @version folgen Kommentare, die u.a. ergänzend in eine automatisch generierbare HTML-Dokumentation für Java Klassen laufen. . Mit @param, @return u.a. kann man auch Java-Methoden über den Dokumentationsgenerator javadoc kommentieren (wir erstellen solch eine Dokumentation später im Rahmen des Aufgabenblocks 3). • Java ist “case sensitive”, d.h. es erkennt und differenziert groß und klein geschriebene Buchstaben; das gilt für zu bearbeitende Zeichenketten, aber auch für alle Bezeichner von Variablen, Objekten, Klassen, Methoden etc. Zusatzinformationen: Java kann, um auch Schriftzeichen anderer Sprachen darzustellen, Unicode verarbeiten. Der UnicodeZeichensatz, bei dem jedes Zeichen mit 16 Bit (= 2 Byte) dargestellt wird, ist eine Obermenge des ASCIIZeichensatzes. Die Zeichen des ASCII-Zeichensatzes werden im Unicode mit denselben Codewerten wie in ASCII dargestellt. Jedoch wird das “höherwertige” Byte stets Null gesetzt und das “niederwertige” Byte aus ASCII übernommen. Im Unicode sind alle europäischen nationalen Sonderzeichen, arabische, japanische etc. Schriftzeichen darstellbar: eine unabdingbare Voraussetzung für die weltweite Nutzung von Java im Internet. Mit der escape-Sequenz \u und darauf folgender Hexadezimalzahl können die im eigenen Computer nicht realisierten Zeichen-Codes eingegeben werden. Aufgabe 1 1. Gehen sie den Guide “Einrichtung von Netbeans und importieren der EIP-Klassen” durch und verwenden sie bei unklaren Begriffen das Glossar und/oder fragen sie einen der Tutoren. 2. Informieren sie sich über das Begleitheft. In diesem werden viele Aspekte ausführlicher erläutert, als es in den Aufgabenblättern vom Umfang her möglich ist. 3. Tippen Sie die obige “Hello, World!” Applikation ab und führen Sie diese anschließend aus. 2 4. Verändern sie nun die “Hello, World!” Applikation so, dass Sie von der Applikation bei ihrer Ausführung mit ihrem Namen begrüßt werden. Teilaufgabe 1.2 - Turtle “Tina” (5%) Die Aufgaben dieses Aufgabenblocks befassen sich mit den ersten Versuchen, Algorithmen zu entwerfen. Die Teilaufgabe soll ferner das Prinzip verdeutlichen, aus einer Folge von Einzelschritten eine “kleine” Aufgabe zu lösen. Sie soll auch zeigen, wie aus der bekannten Sequenz einer solchen Lösung eine andere/ähnliche Aufgabe abgeleitet werden kann, die allein durch leichtes Modifizieren der Anweisungen des Bestehenden gewonnen wird. Bitte kopieren sie die vorangegangen Aufgaben nicht, sondern entwerfen sie angelehnt an diese eine neue Lösung. Zudem soll sie das Programmierprinzip des “bottom up” (d.h. aus kleinen, bereits existierenden Lösungen durch Kombinieren größere/komplexere Aufgabenstellungen zu bewältigen) verdeutlichen. Anmerkungen zum folgenden Beispielprogramm TurtleDemo: • In Java können mehrere Klassen zu Paketen zusammengefasst werden. Solche Pakete können intern hierarchisch gegliedert sein, d.h. selbst aus “Unterpaketen” bestehen, die wiederum untergliedert sein dürfen. Zum Importieren von Klassen aus bereits vorliegenden Paketen in eigene Programme dient die Anweisung import. In unserem Beispielprogramm werden per import eip.* alle im Paket eip gesammelten Klassen verfügbar gemacht und können im Programm genutzt werden. Dies gilt nicht für die Unterpakete der verfügbar gemachten Paketen, diese müssen Sie bei Bedarf selbstständig importieren. Das Paket eip wurde von uns erstellt und liegt unter www.wire.tu-bs.de/lehre/static/programming/eip_tools/eipclasses.zip • Im eip-package liegt u.a. die Klasse TurtleScreen. Eine Instanz dieser Klasse ist ein Fenster auf dessen Fläche sich die (symbolisierte) Schildkröte (turtle) “Tina” bewegen kann. Unter der Fläche liegt ein Steuerungsfeld, mit dem Tina schrittweise, langsam oder schnell bewegt und gestoppt werden kann oder mit dem letztendlich das Fenster entfernt wird. Der Befehl TurtleScreen turtleScreen = new TurtleScreen() erzeugt eine Instanz (d.h. ein Objekt) turtleScreen dieser Klasse. • Im eip-package liegt ferner die Klasse Turtle. Eine Instanz dieser Klasse ist eine symbolisierte turtle, die sich z.B. auf o.g. Zeichenfläche des TurtleScreen turtleScreen bewegt und dabei ihren Weg (durch Zeichenoperationen) auf ihr hinterlässt (eine Idee nach der Programmiersprache Logo). Turtle tina = new Turtle(turtlescreen); erzeugt eine Instanz (d.h. ein Objekt) dieser Klasse mit dem Namen tina auf dem turtleScreen. • Bezogen auf das Objekt tina (die Turtle auf der Zeichenfläche werden diverse Methoden aus der Klasse eip.Turtle aufgerufen, z.B. penDown oder forward(100) (gehe 100 Schritte vorwärts), rightTurn(90) (drehe die Laufrichtung um 90◦ nach rechts). Im “objektorientierten” Paradigma heißt das: An das Objekt tina (die turtle) wird eine Botschaft gesendet, z.B. tina.forward(100); Die Methode forward implementiert das Verhalten des Objekts auf die Botschaft, nämlich die Turtle 100 Schritte vorwärts zu bewegen. Der Turtle-screen und die Turtle-Grafik - mehr dazu im EIP-Begleittext, Kap. 4 3 Aufgabe 2 1. Führen Sie das Beispielprogramm TurtleDemo aus (diese ist bei den Aufgaben unter Materialien zu finden), Betrachten Sie die grafische Ausgabe der einzelnen Programmanweisungen (d.h. den Weg den Tina geht) und verdeutlichen Sie sich dabei ihre Funktion. 2. Experimentieren Sie mit den Anweisungen, die Tina bewegen (andere Zahlenwerte, andere Reihenfolgen). Einige grundlegende Bewegungen der Turtle sind zudem im Beispielprogramm mit Kommentaren versehen. 3. Erstellen Sie (durch Kopieren und Modifizieren des gegebenen Beispielprogramms ein eigenes Programm, das in Analogie zum “Bewegen der Turtle in Form eines Quadrats” die Turtle in Form eines gleichseitigen Sechsecks (Seitenlänge 50) bewegt. Hinweis: Beim Umlaufen eines Sechsecks müssen 360◦ bewältigt werden; ein gleichseitiges Sechseck hat auch 6 gleich große Innenwinkel bzw. Außenwinkel. /* * @author tturtle , Tina Turtle , Biotech . , 3. Sem . , Mat . Nr .: 2238968 * @version 11.11.2001 by Tina Turtle * some turtle movements */ import eip .*; // import the eip - package with all eip - classes public class TurtleDemo { public static void main ( String args []) { /* * these two statements create a turtlescreen and a turtle in it */ TurtleScreen turtlescreen = new TurtleScreen () ; Turtle tina = new Turtle ( turtlescreen ) ; // moving the turtle across the turtlescreen tina . penDown () ; // turtle pen down tina . rightTurn (90) ; // turtle right turn 90 degrees tina . forward (100) ; // turtle forward 100 steps tina . rightTurn (90) ; tina . forward (100) ; tina . rightTurn (90) ; tina . forward (50) ; tina . leftTurn (90) ; // Turtle left turn 90 degrees tina . backward (50) ; // Turtle backwards 50 steps tina . penUp () ; // Turtle pen up // Attention : the turtle doesn ’t come back to the starting point // and doesn ’t straighten in starting orientation ; // so the sequence is not " state transparent " // choosing a new starting point tina . rightTurn (90) ; tina . forward (200) ; tina . rightTurn (90) ; // turtle in new starting point and orientation 4 // moving the turle along a square ! tina . penDown () ; tina . forward (50) ; tina . rightTurn (90) ; tina . forward (50) ; tina . rightTurn (90) ; tina . forward (50) ; tina . rightTurn (90) ; tina . forward (50) ; tina . rightTurn (90) ; tina . penUp () ; // the turtle comes back to the starting point // and straightens in starting orientation ; // so the sequence is " state transparent " } } Teilaufgabe 1.3 - Schleifen (10%) Statt vielfach die gleiche Sequenz von Anweisungen zu notieren, kann man besser eine Schleife (engl. “loop”) schreiben. Eine Schleife besteht aus dem mehrfach abzuarbeitenden Körper und einer die Anzahl Wiederholungen steuernden Kontrollstruktur. In der for-Schleife wird die Kontrollstruktur durch eine ganzzahlige Zählervariable (Typ: int) realisiert, die zu Beginn der Schleifenbearbeitung initialisiert wird (z.B.: int i = 0) und nach jedem Durchlauf um 1 erhöht wird (Inkrement: i++ ist eine verkürzte Notation für: i = i + 1; d.h. Summe aus dem aktuellen Wert von i und 1, wiederum zugewiesen an die Variable i) bis schließlich die Wiederholungsbedingung nicht mehr greift (z.B.: i < 4). Die Sequenz zum Umlaufen eines Quadrats kann damit einfacher wie folgt notiert werden: // move the turtle along a rectangle by use of a for - loop tina . penDown () ; // the body of the loop is executed 4 times for ( int i = 0; i < 4; i ++) { tina . forward (60) ; tina . rightTurn (90) ; } tina . penUp () ; Hinweise • Die Zählervariable i nimmt in den Durchläufen der Schleife nacheinander die Werte 0, 1, 2 und 3 an. Nach dem letzten Durchlauf wird i auf 4 erhöht, so dass die Bedingung i<4 nicht mehr erfüllt ist und die Schleife abgebrochen wird. • Der Wert der Schleifenvariable i wird hier im Beispiel nicht verwendet, könnte aber benutzt werden um in jedem Durchlauf die Turtle eine andere Strecke weit zu bewegen oder um einen anderen Winkel drehen zu lassen. • Sie hätten den Schleifenkopf auch durch for(int i = 1; i <= 4; i++) ausdrücken können. Die hier gezeigt 0-basierte Version ist aber in Java und ähnlichen Programmiersprachen (z.B. C, C++) üblich und bietet bei fortgeschrittener Programmierung einige Vorteile. Mehr zur “for-Schleife” finden sie im EIP-Begleittext unter Kap. 9.7.3 5 Aufgabe 3 1. Ersetzen Sie im Beispiel TurtleDemo die zweite Programmsequenz (Kommentar: “moving the turtle along a square!” durch o.g. Schleife. 2. Erstellen Sie ein Programm, dass in Analogie zu “moving the turtle along a square” die Turtle mittels Schleife in Form eines gleichseitigen Sechsecks (Seitenlänge 60) bewegt. Teilaufgabe 1.4 - Methoden (20%) Anweisungsblöcke, die eine spezielle oder oft verwendete Aufgabe ausführen, kann man zur besseren Gliederung, Übersichtlichkeit und vor allem zur besseren Wartbarkeit in einer “Einheit” zusammenfassen und diese im Weiteren an beliebigen Stellen im Programm aufrufen. Solch eine “Einheit” wird in den Programmiersprachen “Prozedur”, “Funktion”, “Routine” oder (in objektorientiertem Java) “Methode” genannt. /* * @author tturtle , Tina Turtle * Biotech . , 3. Sem . , Mat . Nr .: 2238968 * @version 11.11.2001 by Tina Turtle * moving the turtle along 3 squares */ import eip .*; public class MethodDemo { /* * a method to move the turtle along a square * of sidelength 50 */ public static void square50 ( Turtle tina ) { for ( int i = 0; i < 4; i ++) { tina . forward (50) ; tina . rightTurn (90) ; } // state transparent } public static void main ( String [] args ) { TurtleScreen turtlescreen = new TurtleScreen () ; Turtle tina = new Turtle ( turtlescreen ) ; // call the method 3 times tina . penDown () ; square50 ( tina ) ; tina . penUp () ; tina . rightTurn (90) ; tina . forward (100) ; tina . penDown () ; square50 ( tina ) ; 6 tina . penUp () ; tina . rightTurn (90) ; tina . forward (100) ; tina . penDown () ; square50 ( tina ) ; tina . penUp () ; tina . home () ; // go to origin of the window } } Hinweis Sie werden im Laufe der Aufgabenblätter häufiger auf den Begriff “state transparent” treffen. Mit diesem Begriff ist gemeint, dass die Turtle im selben Zustand endet, in welchem Sie begonnen hat zu zeichnen. Dies bedeutet im selben Winkel, und auf der selben Position. Die Methode square50 ist in diesem Sinne “state transparent”. Java: Blöcke, sequentielle Anweisungsfolgen, Klassen und Methoden. Mehr dazu in unserem EIP-Begleittext, Kap. 5, 6, 7 und 9 bis 9.4 inkl. Aufgabe 4 1. Kopieren Sie das oben gezeigte Beispielprogramm MethodDemo und lassen Sie es zur Verdeutlichung seiner Funktionen ablaufen. 2. Erstellen Sie ein eigenes Programm, das in Analogie zur Methode für das “Umlaufen eines Quadrats” eine Methode zum “Umlaufen eines gleichseitigen Dreiecks” (Seitenlänge 60) benutzt und rufen Sie die Methode entsprechend 3 mal auf. Geben Sie der Methode hierfür einen sinnvollen neuen Namen. 3. Kombinieren Sie die zwei Methoden für das Quadrat und für das gleichseitige Dreieck in ein weiteres Programm, das durch Aufruf der 2 Methoden an passenden Stellen einen einfachsten Haus-Umriss erstellt. Zeichnen Sie zwei weitere Häuser in einigem Abstand vom ersten. 60 60 60 7 Teilaufgabe 1.5 - Variablen (20%) In der Aufgabe, in der die for-Schleife eingeführt wurde, haben Sie bereits Variablen als sogenannte Zählervariablen kennengelernt. Variablen im Allgemeinen können beliebige Daten wie Zahlen, Buchstaben, Texte (Zeichenketten) usw. beinhalten . Man kann ihnen Werte ihres festgelegten Datentyps zuweisen und diese nach belieben ändern oder ersetzen, hier am Beispiel einer ganzzahligen Variable (int): int a ; // Deklariert die Variable ‘‘a ’’ a = 42; // Weist der Variablen ‘‘a ’’ den neuen Wert 42 zu int b = 42; // Kombination von Deklaration und Initialisierung Für uns interessante Datentypen sind noch double für Fließkommazahlen, char für einzelne Zeichen und String für Zeichenketten. Beispiel: double d = 1.2345; // Beachte : Punkt als Dezimaltrenner char c = ’z ’; // Einfache A nf ue hr un gs str ic he fuer Einzelzeichen String s = " Hello " ; // Doppelte An fu eh ru ng ss tri ch e fuer Zeichenketten Auf Variablen mit Zahlentypen kann man auch Rechenoperationen wie Addition oder Multiplikation anwenden. int a =3; a = a +5; // Der Inhalt von a und 5 werden addiert und das Ergebnis // wieder in a gespeichert ( enthaelt also jetzt 8) double b = a * a ; // b wird mit 8*8 , also 64 , initialisiert Strings können mit + zu längeren Zeichenketten verknüpft werden. Dies funktioniert auch, wenn hinter dem + kein String sondern beispielsweise eine Zahl steht: int x = 9; String s = " Das Quadrat von " + x + " ist " + ( x * x ) + " ! " ; Hinweise • Bei der Deklaration einer Variablen reserviert der Compiler Platz im Hauptspeicher des Computers, in den die Daten gespeichert werden und von dort auch wieder gelesen werden können. • Statt die Adresse im Hauptspeicher des Computers (im Allgemeinen eine sehr große Zahl) benutzen zu müssen, können die Daten über den Namen der Variablen, den sogenannten Bezeichner, angesprochen werden. Der Bezeichner kann aus Buchstaben, Zahlen und dem Unterstrich (_) bestehen, muss aber immer mit einem Buchstaben beginnen und darf keine Leer- oder Sonderzeichen enthalten (Beispiel: ganzeZahl_1). Zusatzinformationen: • Der Typ integer wird in Java mit int notiert (eine entspr. Variable wird in Speicherplätzen vom Umfang 32 bit abgelegt und kann ganzzahlige Werte im Bereich zwischen −231 und +231 − 1 annehmen) oder er wird mit long vereinbart (Speicherplatzlänge: 64 bit; Wertebereich: −263 bis +263 − 1). Im weiteren Verlauf der Aufgabenbearbeitung werden nun Gleitpunktzahlen benötigt; sie werden in Java vereinbart zu float (Speicherplatzlänge: 32 bit, Wertebereich: +/ − 3.4028235 ∗ 1038 und im Bereich um 0: +/ − 1.4012984 ∗ 10−45 ) oder bei höherer Genauigkeit zu double (Speicherplatzlänge 64 bit; Wertebereich: +/ − 1.797693 ∗ 10308 und im Bereich um 0: +/ − 4.9406564 ∗ 10−324 ). • Java hat (ähnlich anderen Programmiersprachen) ein strenges Typenkonzept. Zwar wird bei einer Zuweisung eines Wertes vom Typ Ganzzahl an eine Variable vom Typ Gleitpunktzahl eine automatische Typanpassung vorgenommen, jedoch können Einbußen in der Genauigkeit auftreten; Zuweisungen von Gleitpunktzahlen an Variablen vom Typ Ganzzahl können nur durch explizites Notieren der Anpassung im Quelltext vorgenommen werden (z.B.: float a = 12.567; int x = (int)a;). Ein solches type-casting wird erzielt durch Voranstellen des umklammerten Typs vor den Variablennamen des anzupassenden Wertes. 8 Aufgabe 5 1. Schreiben sie ein Rechenprogramm, dass mehrere Methoden für alle gängigen Rechenoperationen besitzen soll (Addition, Subtraktion, Multiplikation, Division). Deklarieren Sie hierzu zwei Variablen in der main-Methode, denen Sie feste Werte zuweisen oder von der Konsole einlesen. Wenn Sie das eip-Paket importiert haben geht dies beispielsweise mit: System . out . print ( " Wert x eingeben : " ) ; double x = Std . in . readDouble () ; Dann sollen die Ergebnisse der Rechenoperationen berechnet und ausgegeben werden. Die Ausgabe z.B. des Additionsergebnisses soll in etwa wie folgt aussehen: Die Summe von 3.5 und 4.3 ist 7.8. Führen Sie die Berechnung der Ergebnisse in einzelnen Methoden durch. Der Methodenkopf der Additionsmethode (add) beispielsweise sollte wie folgt aussehen: public static double add ( double a , double b ) Das berechnete Ergebnis kann aus der Methode mit Hilfe der Anweisung return zurückgegeben werden. Im aufrufenden Code (d.h. in diesem Fall Ihrer main-Methode) kann der berechnete Wert durch den Ausdruck add(x,y) verwendet werden. Hinweis: Die Werte in den Variablen x und y werden an die Methode add übergeben und haben dann dort die Namen a und b. 2. Erweitern sie ihr Rechenprogramm um eine Methode um Potenzen (z.B. 23 ) errechnen zu können. Der Methodenkopf soll wie folgt aussehen: public static double power ( double a , int n ) Benutzen Sie eine for-Schleife die nacheinander a0 , a1 , a2 usw. bis an berechnet und das letzte Ergebnis schließlich zurückliefert. Hinweis: Beachten Sie, dass a0 = 1 ist und dass sie z.B. a5 als a · a · a · a · a schreiben können. 9 Teilaufgabe 1.6 - Mandala (10%) Zurück zur Turtle: Zeichnen Sie geometrische Muster nach folgendem Algorithmus: Aufgabe 6 1. Der folgende Code soll 18 mal hintereinander ausgeführt werden square60 ( tina ) ; tina . rightTurn (20) ; tina . forward (20) ; Benutzen Sie hierfür eine for-Schleife (und kein Copy-and-Paste). 2. Nun 18 mal hintereinander das gleiche mit einer Methode zum Zeichnen eines gleichseitigen Dreiecks triangle60(); 3. Konstruieren Sie mit den Ihnen soweit vorliegenden Methoden andere “nette” geometrische Muster mit der gleichen Technik. Teilaufgabe 1.7 - Doodle (10%) Interessante geometrische Grundformen, aus denen sich komplexere Figuren konstruieren lassen, sind sogenannte doodle (engl. für Kritzelei). Ein Beispiel für ein doodle ist die folgende Gestalt: 30 30 60 120 120 120 60 60 hier anfangen Aufgabe 7 1. Konstruieren Sie mit der turtle-Grafik eine Methode zum Zeichnen des oben gezeigten Doodle. Beginnen Sie mit dem Zeichnen am unteren Ende der Figur und fassen Sie die Anweisungen zum Zeichnen in einer eigenen Methode doodle() zusammen. 2. Die entstehende Figur entspricht nicht den Anforderung für “state transparency“. Wird dieser “Doodle” 4-mal nacheinander aufgerufen, so entsteht eine in sich geschlossene graphische Figur. Die gesamte Sequenz ist nun “state transparent”, da sie sich 4-mal um 90 Grad gedreht hat. Realisieren Sie ein Programm, das diese Figur mittels einer Wiederholungsanweisung und der Methode doodle zeichnet. 10 3. Zeichnen Sie eine weitere in sich geschlossene Figur nach folgendem Muster und wiederholen Sie dies 8-mal: doodle () ; tina . leftTurn (45) ; Hinweis Beim Zeichnen verlässt die turtle die Zeichenfläche an der unteren Kante um ihren Weg von der oberen Kante aus fortzuführen. Das ist eine Folge der in sich geschlossenen Zeichenfläche. Definieren Sie das Objekt turtlescreen mit größerer Dimension für die Zeichenfläche, z.B. wie folgt: Turtlescreen turtlescreen = new TurtleScreen(0,0,900,900); Die beiden Parameter 0,0 entsprechen den x,y-Position der linken obere Ecke des Fensters; Die beiden Parameter 900,900 entsprechen der Höhe und Weite des Fensters. Auch könnte man den Startpunkt des turtle-Weges aus dem standardmäßig gegebenen Mittelpunkt an einen besser geeigneten Punkt verlegen (z.B. mithilfe von: tina.penUp(); tina.leftTurn(90); tina.forward(200); usw.). 4. Lassen Sie sich einige weitere interessante geschlossene Figuren aus doodles einfallen. Sie können (um besonders komplexe Figuren zu erzeugen) Wiederholungen “ineinander schachteln”. 11 Teilaufgabe 1.8 - Parkettierung (20%) Aus den Methoden für das Zeichnen von Dreiecken, Vierecken und Sechsecken kann man leicht sogenannte Parkettierungen programmieren. Das Prinzip ist aus unserem Beispiel für Vierecke abzuleiten. Hier werden zwei ineinandergeschachtelte Schleifen genutzt um die Methoden zum Zeichnen je eines Vierecks aufzurufen (siehe Abb. 1 und das darauf folgende Programmbeispiel SquareParquet). Hinweis Bei ineinandergeschachtelten Schleifen wird die innenliegende Schleife jeweils komplett abgearbeitet bevor die umgebende äußere um einen Schritt “weitergeschaltet” wird. Bei der Positionierung der turtle in den Startpunkt werden tina.setX(); und tina.setY(); benutzt. Abbildung 1: Rechteck-Parkettierung /* * * * */ Abbildung 2: Sechseck-Parkettierung @author tturtle , Tina Turtle , Biotech . , 3. Sem . , Mat . Nr .: 2238968 @version 11.11.2001 by Tina Turtle moving the turtle import eip .*; public class SquareParquet { // method to move the turtle on a square of sidelength 50 public static void square50 ( Turtle tina , int length ) { tina . penDown () ; for ( int i =0; i <4; i ++) { tina . forward ( length ) ; // tina . leftTurn (90) ; } tina . penUp () ; // (" state transparent ") } public static void main ( String [] args ) 12 { /* * Assigning a turtlescreen of size 600 x 600 units , * left upper side at x =0 , y =0 */ TurtleScreen turtlescreen = new TurtleScreen (0 ,0 ,1200 ,1200) ; Turtle tina = new Turtle ( turtlescreen ) ; // useful variables int width = 8; int height = 10; int length = 50; tina . rt (180) ; // now it ’s looking to the bottom // otherwise the turtle would draw over the top border for ( int i = 1; i <= width ; i ++) { for ( int j = 1; j <= height ; j ++) { // set the current turtle position tina . setX ( length * i ) ; tina . setY ( length * j ) ; // draw the square for this position square50 ( tina , length ) ; } } } } Aufgabe 8 1. Verdeutlichen Sie sich die Funktionsweise des Programms zur “Rechteck-Parkettierung” (SquareParquet). 2. Schreiben Sie ein eigenes Programm, das Sechsecke nach dem Muster der Abb. 2 aneinanderfügt zur “Sechseck-Parkettierung”. 3. Schreiben Sie ein zweites Programm, das das Muster von Abb. 2 erstellt jedoch jedes zweite Sechseck auslässt 13 Teilaufgabe 1.9 - Freiwillige Zusatzaufgabe für Interessierte In der Abb. 3 ist ein Indianerzelt wiedergegeben. Die äußeren Seitenlängen betragen 3·a, die Seiten der Zeltöffnung je a (wählen Sie a fest zu 15). Da die Dreiecke gleichseitig sind betragen die Innenwinkel 60◦ und die Außenwinkel 120◦ . Abbildung 3: Indianerzelt Abbildung 4: Zeltkachelmuster Aufgabe 9 1. Schreiben Sie eine Methode, die das Indianerzelt zeichnet. 2. Schreiben Sie eine zweite Methode, die ein Sechseck der Seitenlänge 2 · a erzeugt. 3. Legen Sie im weiteren auf die Seiten des Sechsecks die Anfänge (nämlich 2 · a) der Außenseite eines Indianerzeltes und reihen Sie in zwei geschachtelten Schleifen diese Grafiken so aneinander, dass die Figur aus Abb. 4 entsteht, eine Parkettierung nach dem Zeltkachelmuster. 14