13. Aufgabe (13 Punkte) Schreiben Sie eine neue Klasse Zahlenanalyse, mit der Integer-Objekte genauer betrachtet werden können. Bei den zu entwickelnden Methoden kann es immer sinnvoll sein, sich den Ablauf zunächst mit Aktivitätsdiagrammen zu veranschaulichen und dabei noch keinen konkreten Programmcode in die Aktionen zu schreiben. Bei zwei Teilaufgaben ist ein solches Diagramm gefordert, beim Rest optional. Machen Sie solchen Skizzen zunächst per Hand, durchaus mit schwerer zu lesenden Korrekturen, verschwenden Sie keine Zeit mit der Suche nach einem Werkzeug. a) Schreiben Sie eine Methode istteilervon(integer,integer), die feststellt, ob die erste übergebene Zahl Teiler der zweiten übergebenen Zahl ist. Nutzen Sie die Modulo- Rechnung mit %. Falls die erste Zahl 0 ist oder eines der Objekte null ist, soll das Ergebnis false sein. b) Schreiben Sie eine Methode alleteilervon(integer), die alle Teiler der übergebenen Zahl ausgibt. Für Zahlen kleiner 1 und den null-wert wird nichts ausgegeben. Überprüfen Sie innerhalb einer Schleife alle möglichen Teiler ab der Zahl 1. Zeichnen Sie zunächst ein Aktivitätsdiagramm für den Ablauf Ihrer Methode. c) Schreiben Sie eine Methode groesstergemeinsamerteiler(integer,integer), der die größte Zahl findet, die Teiler beider übergebenen Zahlen ist. Nutzen Sie dabei ein einfaches Verfahren, bei dem Sie z. B. alle Zahlen von 1 bis zur ersten übergebenen Zahl ausprobieren. Sollte ein Parameter kleiner 1 oder null sein, ist das Ergebnis 0. Zeichnen Sie zunächst ein Aktivitätsdiagramm für den Ablauf Ihrer Methode. d) Aufgabe c) kann auch durch den sogenannten Euklidschen Algorithmus gelöst werden. Informieren Sie sich über das Verfahren und implementieren Sie es als Methode groesstergemeinsamerteiler2(integer,integer). e) Zu entwickeln ist eine Methode eingabeanalyse(), die den Nutzer immer wieder zur Eingabe einer Fließkommazahl (Double) auffordert, die immer zwischen -100.0 und 100.0 liegt (muss geprüft werden, falsche Werte ignorieren) und die nach jeder Eingabe den kleinsten und den größten bisher eingegebenen Wert sowie den Mittelwert (Durchschnitt aller eingegebenen Werte) ausgibt. Überlegen Sie, welche Informationen man in lokalen Variablen speichern muss (man muss sich nicht alle Zahlen merken). Das Programm wird mit der Eingabe der Zahl -1 terminiert, nutzen Sie die Klasse EinUndAusgabe.java von der Veranstaltungsseite. Ein Nutzungsdialog kann wie folgt aussehen, Eingaben sind umrandet. Geben Sie einen Wert ein: 3.5 Minimum: 3.5 Maximum: 3.5 Schnitt: 3.5 Geben Sie einen Wert ein: 7.5 Minimum: 3.5 Maximum: 7.5 Schnitt: 5.5 Geben Sie einen Wert ein: 2 Minimum: 2.0 Maximum: 7.5 Schnitt: 4.333333333333333 Geben Sie einen Wert ein: 4.33 Minimum: 2.0 Maximum: 7.5 Schnitt: 4.3325 Geben Sie einen Wert ein: 101 Geben Sie einen Wert ein: -1 f) Entwickeln Sie ein Methode abzahlungzeigen(), die einen Kredit k in Euro, einen Zinssatz z in % und eine jährliche Tilgungssumme t in Euro jeweils als Double-Werte einliest. Die Kreditsumme des Folgejahres mit jährlicher Tilgung berechnet sich als k*(1+z/100) t. Ihr Programm soll das Jahr, die verbleibende Kreditsumme und die bisher insgesamt gezahlten Zinsen (im Jahr k*(z/100)) ausgeben. Ihr Programm endet, wenn der Kredit zurück gezahlt ist. Falls dieses nicht möglich ist, soll Ihr Seite 1 von 5
Programm eine Warnung ausgeben. Zwei Nutzungsdialoge können wie folgt aussehen, Eingaben sind umrandet. Kreditsumme: 100 Zinssatz: 10 Tilgung: 20 1.Jahr Restkredit: 90.00000000000001, gezahlte Zinsen:10.0 2.Jahr Restkredit: 79.00000000000003, gezahlte Zinsen:19.0 3.Jahr Restkredit: 66.90000000000003, gezahlte Zinsen:26.900000000000002 4.Jahr Restkredit: 53.590000000000046, gezahlte Zinsen:33.59 5.Jahr Restkredit: 38.949000000000055, gezahlte Zinsen:38.949000000000005 6.Jahr Restkredit: 22.843900000000062, gezahlte Zinsen:42.84390000000001 7.Jahr Restkredit: 5.128290000000071, gezahlte Zinsen:45.12829000000002 8.Jahr Restkredit: -14.358880999999922, gezahlte Zinsen:45.64111900000003 Kreditsumme: 250000 Zinssatz: 4.5 Tilgung: 1000.42 Kredit so nicht abzahlbar! g) Entwickeln Sie eine Methode zahlenraten() mit der Sie mit dem Computer Zahlenraten spielen können. Dazu soll der Computer eine Zahl zwischen 1 und 100 (jeweils einschließlich) wählen. Die Klasse EinUndAusgabe.java bietet dazu die Methode zufall(integer,integer), die einen Zufallswert zwischen den übergebenen minimalen und maximalen Werten liefert. Danach kann der Spieler seinen Tipp eingeben und der Computer antwortet mit, zu tief oder korrekt. Weiterhin zählt der Computer die Anzahl der Versuche und gibt dies vor jedem Rateversuch aus. Ein Nutzungsdialog kann wie folgt aussehen, Eingaben sind umrandet. 1.Versuch: Zahl raten: 67 2.Versuch: Zahl raten: 46 3.Versuch: Zahl raten: 23 4.Versuch: Zahl raten: 11 zu tief 5.Versuch: Zahl raten: 17 zu tief 6.Versuch: Zahl raten: 20 Bravo, getroffen. h) (freiwillig) Ändern Sie Ihr Programm aus g) so, dass der Computer zwar immer korrekt antwortet, allerdings den Spieler immer dazu bringt, die maximale Anzahl an Versuchen zu machen. Der Computer rät also keine Zahl sondern versucht sich möglichst viele Möglichkeiten offen zu halten. Dabei sind natürlich alle Hinweise mit zu tief und korrekt. Beispiel: Der Spieler gibt am Anfang 60 ein, dann stellt der Computer fest, zwischen 1 und 60 liegen mehr Zahlen als zwischen 60 und 99, deshalb gibt der Computer zu hoch aus. Beim nächsten Tipp 25, gibt der Computer dann zu tief aus, da zwischen 25 und 60 mehr Zahlen liegen als zwischen 1 und 25. Seite 2 von 5
14. Aufgabe (5 Punkte) Schreiben Sie eine neue Klasse InteraktionsbrettSpielerei.java, mit der die Klasse Interaktionsbrett weiter untersucht werden soll. Ihre Klasse soll zumindest eine Objektvariable der folgenden Art enthalten: Interaktionsbrett ib; a) Die Klasse bietet u. a. folgende Methoden, mit denen ein Text auf dem Interaktionsbrett platziert werden und mit dem man die Länge eines Textes bestimmen kann (Font und die Fontgröße 12 pt sind nicht änderbar). Der Ausgangspunkt des Textes befindet sich auf der Basislinie der Zeichen. Um diesen Begriff zu verdeutlichen, schreiben Sie eine Methode, die möglichst genau das obige Bild als Ergebnis hat (Zoom 3). void neuertext(java.lang.integer x, java.lang.integer y, java.lang.string text) Methode zur Ausgabe eines Textes. java.lang.integer textlaenge(java.lang.string text) Berechnet die Länge eines Textes für eine mögliche graphische Ausgabe. b) Lesen Sie zunächst die Hintergrundinformationen zur reaktiven Programmierung mit der Klasse Interaktionsbrett am Ende des Aufgabenblatts durch. Ergänzen Sie in Ihrer Klasse folgende Methoden. public void bewegdich(){ ib.neuerkreis(this,"k1",30,30,10); public Boolean mitmausangeklickt(string name, Integer x, Integer y){ return true; public Boolean mitmausverschoben(string name, Integer x, Integer y){ return true; Was beobachten Sie, wenn Sie versuchen, den Kreis mit gedrückter linker Maustaste (in der virtuellen Umgebung langsam) zu verschieben? Was beobachten Sie, wenn Sie den Rückgabewert in der Methode mitmausangeklickt auf false setzen? c) Schreiben Sie ein neues Programm mit Hilfe der Klasse Interaktionsbrett, das einen Basketballwurf simulieren soll. Erzeugen Sie dazu einen verschiebbaren Kreis (Ball) und ein unverschiebbares Rechteck (Korb) an einer beliebigen sichtbaren Position auf dem Interaktionsbrett. Der Ball gilt als in den Korb geworfen, wenn sich der Mittelpunkt des Kreises innerhalb des Rechtecks befindet und er losgelassen wurde. Ergänzen Sie dazu die notwendigen Implementierungen der Methoden Seite 3 von 5
mitmausverschoben, mitmausangeklickt und mitmauslosgelassen. Befindet sich der Ball im Korb, soll er nicht mehr bewegt werden können. Die Bilder zeigen zwei typische Spielsituationen nachdem auch d) gelöst wurde. Die folgende Methode kann beim Platzieren von Ball und Korb hilfreich sein. java.lang. Integer zufall(java.lang.integer start, java.lang.integer ende) Methode zur Erzeugung einer ganzzahligen Zufallszahl zwischen (einschließlich) den übergebenen Grenzen. d) Ergänzen Sie das Programm so, dass am Ende des Spiels die verbrauchte Zeit angezeigt wird e) Wahrscheinlich haben Sie in den vorherigen Aufgaben das gesamte Programm in einer Klasse realisiert. Ändern Sie das Programm so ab, dass der Korb eine eigene Klasse wird. Dabei soll der Korb im Konstruktor das genutzte Interaktionsbrett als Parameter erhalten und sich dann an zufälliger Stelle zeichnen. Weiterhin soll der Korb eine Methode getroffen beinhalten, mit der überprüft wird, ob der Ball den Korb getroffen hat, der Korb muss dazu natürlich wissen, an welcher Position er steht. f) (freiwillig) Erweitern Sie das Programm mit den bisher bekannten Hilfsmitteln so, dass zehn Bälle in zehn unterschiedliche Körbe auf einem Spielfeld geworfen werden müssen. In jedem Korb darf nur ein Ball sein. Nutzen Sie ArrayLists, wenn Sie mehrere Objekte des gleichen Typs verwalten wollen. Hintergrund: Reaktive Programmierung mit der Klasse Interaktionsbrett Man spricht bei einer Software von einem reaktiven System, wenn es seine Berechnungen nicht selbständig ausführt, sondern von außen angestoßen wird. Grafische Oberflächen sind ein Beispiel für ein reaktives System, da z. B. erst etwas ausgeführt wird, wenn der Nutzer einen Knopf anklickt. Bei der Programmierung muss man die Reaktion auf eine solche Aktion programmieren. Typischerweise schreibt man dazu Methoden, die vom umgebenden System (z. B. Betriebssystem oder virtuelle Maschine) aufgerufen werden. Damit das System weiß, welche Methoden genutzt werden, muss dies irgendwo vereinbart sein. Die Klasse Interaktionsbrett bietet die Möglichkeit, mit jeder der unterstützten Objektarten (Punkt, Linie, Kreis, Rechteck, Text) zu interagieren, d. h. auf Mausaktionen mit diesen Objekten zu reagieren. Dazu gibt es bei der Erzeugung der Objekte jeweils eine zweite Methode mit zwei zusätzlichen Parametern mit den Typen Objekt und String, wie folgender Ausschnitt aus den Methoden für einen Kreis zeigt. void neuerkreis(java.lang.integer x, java.lang.integer y, java.lang.integer radius) Methode zum Zeichnen eines neuen Kreises. void neuerkreis(java.lang.object quelle, java.lang.string name, java.lang.integer x, java.lang.integer y, java.lang.integer radius) Methode zum Zeichnen eines neuen Kreises, der verändert und dessen Nutzung beobachtet werden kann. Die beiden Parameter haben folgende Bedeutung. Das übergebende Objekt wird gegebenenfalls benachrichtigt, falls der Kreis mit der Maus bearbeitet (geklickt, Seite 4 von 5
verschoben, neu platziert) wurde. Das gegebenenfalls bezieht sich darauf, dass das benachrichtigte Objekt bestimmte Methoden anbieten muss, die die Maus-Aktionen verarbeiten. Diese Methoden werden gleich vorgestellt. Der übergebene String steht für einen Namen des Objektes, der bei der Verarbeitung der Mausaktionen mit übergeben wird. Das Objekt, das die Mausaktionen verarbeitet, kann so mehrere Objekte an ihrem Namen unterscheiden. Möchte man, dass ein Objekt, das einen Kreis zeichnet, auch auf die zugehörigen Mausaktionen reagieren kann, muss sich das Objekt selbst (this) als zu benachrichtigendes Objekt übergeben. Möchte man im benachrichtigten Objekt auf Maus-Aktionen reagieren, muss man zumindest eine der drei Folgenden Methoden realisieren, die wie folgt auch in der Klassendokumentation beschrieben sind. Es gilt dabei, dass man mitmausverschoben nur nutzen kann, wenn mitmausangeklickt erlaubt ist (Rückgabe true). MitMausLosgelassen ist nur erlaubt, wenn mitmausverschoben erlaubt ist. Will man die Maussteuerungsmöglichkeiten nutzen, muss das mit dem graphischen Element übergebene Objekt eine oder mehrere der folgenden Methoden implementieren, die dann vom Interaktionsbrett bei einer Maus-Aktion aufgerufen werden. public Boolean mitmausverschoben(string name, Integer x, Integer y) Das Objekt wird informiert, dass ein graphisches Element mit Namen name an die Position (x,y) verschoben wurde, die zugehörige Mausbewegung ist beendet. Mit dem Rückgabewert kann man mitteilen, ob die Verschiebung überhaupt gewünscht ist (true) oder nicht (false). public Boolean mitmausangeklickt(string name, Integer x, Integer y) Das Objekt wird informiert, dass ein graphisches Element mit Namen name an der Position (x,y) gerade angeklickt wurde, die zugehörige Mausbewegung beginnt gerade. Mit dem Rückgabewert kann man mitteilen, ob eine Bearbeitung (konkret eine Verschiebung) überhaupt gewünscht ist (true) oder nicht (false). public Boolean mitmauslosgelassen(string name, Integer x, Integer y) Das Objekt wird informiert, dass ein graphisches Element mit Namen name gerade an die Position (x,y) verschoben und an dieser Position losgelassen wurde, die zugehörige Mausbewegung endet gerade. Mit dem Rückgabewert kann man mitteilen, ob das Ablegen des Elements an dieser Stelle überhaupt gewünscht ist (true) oder nicht (false). Der sicherlich selten genutzte Fall false hat nur Auswirkungen, wenn der Nutzer zum nächsten Zeitpunkt auf eine Stelle klickt, an der sich kein auswählbares graphisches Element befinde. Dann wird das zuletzt benutzte Element genutzt und z. B. wieder verschoben. Objekte können dem Interaktionsbrett mitteilen, dass sie über gedrückte Tasten informiert werden wollen. Hierzu dient die Methode willtasteninfo(). Das zu informierende Objekt muss dann eine Methode der folgenden Form realisieren: public void tastegedrueckt(string s) Seite 5 von 5