• Keine Ergebnisse gefunden

252-0027-00: Einführung in die Programmierung Übungsblatt 8

N/A
N/A
Protected

Academic year: 2022

Aktie "252-0027-00: Einführung in die Programmierung Übungsblatt 8"

Copied!
5
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

252 - 0027 - 00 : Einführung in die Programmierung Übungsblatt 8

Abgabe:21. November2017, 13:00

Checken Sie mit Eclipse wie bisher die neue Übungs-Vorlage aus.

Aufgabe 1: EBNF (Bonus!)

Achtung: Diese Aufgabe gibt Bonuspunkte (siehe “Leistungskontrolle” im www.vvz.ethz.ch).

Die Aufgabe muss eigenhändig und alleine gelöst werden. Die Abgabe erfolgt wie gewohnt per Commit in Ihrem SVN Repository. Verbindlich ist der letzte Commit vor dem Abgabetermin.

In dieser Aufgabe erstellen Sie wieder EBNF-Beschreibungen. Alle Beschreibungen werden in der Text-Datei “EBNF.txt” abgelegt, welche sich in Ihrem SVN Repository befindet. Ändern Sie nicht die Struktur dieser Datei und achten Sie darauf, dass sich Ihre Beschreibungen genau an die folgenden Vorgaben halten:

• Verwenden Sie “<=” als Zeichen für “ist definiert als”.

• Namen von Regeln stehen zwischen<und >, also z.B.<name>.

• Der Name der Startregel ist in der jeweiligen Aufgabe vorgegeben und darf nicht geändert werden. Sie dürfen aber neue Regeln hinzufügen.

• Es sollen die Kontrollelemente der Vorlesung benutzt werden:{,},[,]und|

• Für Gruppierungen können Sie(und)verwenden.

a) Erstellen Sie eine EBNF-Beschreibung <zeit>, welche genau jene Wörter zulässt, die einer Zeitangabe einer Digitaluhr entsprechen. Eine solche Zeitangabe hat genau 6 Ziffern, die paarweise durch:getrennt sind. Das erste Paar gibt die Stunden, das zweite Paar die Minuten und das dritte Paar die Sekunden an. Die frühste Zeit des Tages ist00:00:00und die späteste Zeit23:59:59. Zeitangaben ausserhalb dieses Zeitraums sollen nicht akzeptiert werden.

Beispiele gültiger Zeitangaben:00:13:37, 11:22:33

Beispiele ungültiger Zeitangaben:24:00:00, 10:61:00, 5:10:10, 10:10

b) Erstellen Sie eine EBNF-Beschreibung<palindrom>, die nur genau jene Wörter zulässt, welche ausschliesslich aus den Zeichena, b, nundobestehen undPalindrome sind. Palindrome

(2)

sind Wörter, die vorwärts wie rückwärts gelesen identisch sind (Eine leere Zeichenfolge ist kein Wort).

Beispiele gültiger Wörter:abba, bnb, a, non, nan, bob, anna Beispiele ungültiger Wörter:ab, zoz, bnnnbb, annb

c) Erstellen Sie eine EBNF-Beschreibung<rezept>, welche Kochrezepte beschreibt. Ein Rezept besteht aus einer Folge von Schritten. Jeder Schritt beschreibt eine Aktion, z.B. eine Zutat hinzufügen oder die Temperatur des Herds erhöhen. Ein Beispielrezept sieht so aus:

add-salt. add-pepper. increase-temp. add-water. add-pasta.

stir. decrease-temp. serve.

Ihre EBNF-Beschreibung soll genau die Rezepte zulassen, welche den folgenden Regeln entsprechen. Um Leerzeichen brauchen (und sollen) Sie sich nicht kümmern.

• Ein Schritt ist entweder increase-temp, decrease-temp, stir, serve oder add-ZUTAT, wobeiZUTAT eine der folgenden Zutaten ist:salt,pepper,cream,pasta,eggoderwater.

Jeder Schritt wird durch einen Punkt beendet.

• increase- unddecrease-temperhöhen bzw. verringern die Herdtemperatur um je eine Stufe. Wir nehmen an, dass die Temperatur am Anfang auf Stufe 0 ist. Am Ende des Rezepts muss die Temperatur wieder 0 sein und sie darf niemals negativ werden.

• Wenn Salz hinzugegeben wird, muss im nächsten Schritt auch Pfeffer hinzugegeben werden.

• Das fertige Menu wirdimmerundimmer erstam Schluss serviert (serve).

Aufgabe 2: Doubly-linked List

Die Liste, die Sie in der letzten Übung implementierten, ist “einfach verkettet”, d.h., jeder Knoten hat nur eine Referenz auf den nächsten in der Liste. Doppelt verkettete Listen sind auch von hinten nach vorne verkettet, d.h., jeder Knoten hat auch eine Referenz zum vorherigen. Dies bringt einige Vorteile mit sich, z.B. lassen sich so Werte am Ende der Liste effizient entfernen und man kann die Liste einfach von hinten nach vorne durchgehen (über die Liste “iterieren”). Ausserdem kann man einfacher Werte aus dem Innern der Liste entfernen.

a) Sie finden in Ihrem Projekt eineLinkedPersonList, welche gleich funktioniert wie die Muster- lösung zurLinkedIntList, einfach fürPerson-Objekte anstatt fürints. Erweitern Sie diese einfach verkettete Liste zu einer doppelt verketteten Liste. Fügen Sie dafür ein prev-Feld zu PersonNode hinzu und ändern Sie die Methoden in LinkedPersonList wo nötig (oder vorteilhaft).

b) Fügen Sie eineremoveNode()-Methode hinzu, welche ein gegebenesPersonNode-Objekt aus der Liste entfernt. Diese Methode kann verwendet werden, um einen Knoten innerhalb einer

for(PersonNode n = list.first; n != null; n = n.next) { ... }- Schleife zu entfernen. Diese Methode wird sich in Aufgabe3als hilfreich erweisen.

(3)

xkcd: Forgettingby Randall Munroe (CC BY-NC2.5, modified)

c) Erweitern Sie die Tests inLinkedPersonListTest. Die vorgegebenen Tests sind für die ein- fach verkettete Liste ausgelegt. Fügen Sie wo nötig Test-Code hinzu und schreiben Sie eine Test-Methode fürremoveNode(). Testen Sie vor allem die neu hinzugekommene Konsistenz- Bedingung:

Für alle Knotenngilt:n.next == null || n.next.prev == n(und analog fürn.prev).

Aufgabe 3: Warteschlangen-Simulation

Doppelt verkettete Listen eignen sich gut als Warteschlangen (engl. “Queue”). “Software-Warteschlangen”

werden in vielen Anwendungen verwendet, um Objekte oder Daten zwischenzuspeichern, bevor sie verarbeitet werden. In dieser Aufgabe sollen Sie sie hingegen verwenden, um die realen Warteschlangen vor den Kassen in Ihrer nächsten Migros-Filiale zu simulieren.

Die Simulation läuft in diskreten Schritten ab. Das heisst, die Zeit wird in gleichgross Intervalle unterteilt und in jedem Intervall passieren gewisse Dinge. Zum Beispiel kann in einem Intervall ein Kassierer einen Gegenstand scannen oder eine Person die Warteschlange wechseln. Die Simulation hat folgende Parameter:

Anzahl Kassen und Kassier-Effizienz: Eine Liste [p0,p1, ...,pn] der Längen mit 0≤ pi < 1. Es gibtn(besetzte) Kassen und deri-te Kassierer scannt in jedem Zeitschritt mit Wahrscheinlich- keit pi einen Gegenstand aus dem Warenkorb der vordersten Person in seiner Warteschlange.

Wenn er den letzten Gegenstand einer Person gescannt hat, verlässt diese Person die Kasse.

Erschein-Wahrscheinlichkeit: Eine Zahl e, wobei 0 ≤ e < 1. In jedem Zeitschritt erscheint mit Wahrscheinlichkeite eine neue Person und steht an einer zufälligen Schlange an.

Warenkorb-Grösse: Eine natürliche Zahlw. Jede Person hat zu Beginn zwischen 0 und wGegen- stände in seinem Warenkorb. Die genaue Anzahl jeder Person ist zufällig.

Faulheit der Leute: Eine natürliche Zahl f. Da gewisse Schlangen länger werden können als andere, möchten die Leute vielleicht mal wechseln, abhängig von ihrer Faulheit. Eine Person wechselt (in jedem Zeitschritt) zur momentan kürzesten Schlange, falls diese um mindestens

f kürzer ist als die aktuelle Position1dieser Person in seiner Schlange.

1Positionen sind 0-indexiert, d.h., die vorderste Person hat Position 0, die nächste Position 1, usw.

(4)

Implementieren Sie diese Simulation in einer KlasseMigrosSimulation, welche diese Parameter im Konstruktor entgegen nimmt. Die Klasse soll einerun()-Methode haben, welche die Anzahl Zeitschritte entgegen nimmt und die Simulation durchführt. Danach können die Resultate der Simulation mit Accessor-Methoden (“getter”) ausgelesen werden. Die Implementation der Simu- lation soll von externem Zugriff geschützt sein (“encapsulation”). Folgende Resultate sollen zur Verfügung gestellt werden:

getFinished(): Eine Liste mit allen Personen, welche es bis zum Ende der Simulation durch den Kassenbereich “geschafft” haben. Jede Person enthält die ursprüngliche Anzahl Gegenstände in ihrem Warenkorb und die Zeit (in Anzahl Zeitschritten), die sie in den Warteschlangen verbracht hat.

getAvgQueueLengths(): Ein Array, welches diedurchschnittlicheLänge jeder Warteschlange wäh- rend der gesamten Simulation enthält.

getMaxQueueLengths(): Ein Array mit denmaximalenLängen der Warteschlangen.

Ändern Sie dazu IhrePerson-Klasse so ab, dass sie statt Körpergrösse, usw. die für die Simulation benötigten Felder enthält. Schreiben Sie schliesslich eine KlasseMigrosSimulationAppmit einer main()-Methode, welche einige (oder alle) Parameter für die Simulation von der Konsole einliest, die Simulation erstellt und durchführt und schliesslich einige interessante Daten ausgibt. Verwen- den Sie zum Beispiel die Methoden aus der gegebenenUtils-Klasse, um die durchschnittlichen und maximalen Längen der Warteschlangen schön auszugeben.

Zusatz-Aufgabe:Wenn Sie wollen, können Sie die Simulation erweitern, indem Sie z.B. die Zeit um die Schlange zu wechseln simulieren, während der Simulation Kassen öffnen und schliessen oder weitere “Persönlichkeitsmerkmale” einfliessen lassen.

Aufgabe 4: Pong

In dieser Aufgabe geht es darum, den KlassikerPong von 1972 nach zu bauen. Es sollen zwei Spieler ge- geneinander spielen können. Dafür kommt die bereits bekannteWindow-Klasse zum Zug. Sie bietet einige Me- thoden, um Input von Maus und Tastatur aufzuneh- men. Eine davon istisKeyPressed(String keyName), welche truezurück gibt, wenn die spezifizierte Taste zum Zeitpunkt des Aufrufs gedrückt ist:

if(window.isKeyPressed("up")) { // move something around }

Das Spiel besteht aus einem Ball und aus zwei Spielern, welche je einen vertikalen Balken kontrollieren und versuchen, den Ball im Spiel zu halten. Wenn der Ball das Spiel seitlich verlässt, erhält der gegenüberliegende Spieler einen Punkt. Wenn der Ball hingegen die Wände oben und unten oder einen Spielerbalken berührt, prallt er ab.

(5)

a) In Ihrem Projekt finden Sie bereits Vorlagen für folgende Klassen:

PongGame: Verantwortlich für das Speichern und Berechnen der Spielsituation.

PongGUI: Verantwortlich für die grafische Umsetzung des Spielgeschehens. Beinhaltet die main-Methode und ist für die graphische Oberfläche des Spiels verantwortlich.

Erstellen Sie zwei weitere Klassen Playerund Ball, welche alle Informationen zu Spieler und Ball beinhalten. Ein Spieler hat eine(px,py)-Position, eine Balkenlänge und einen Punk- testand. Ein Ball hat ebenfalls eine Position und zusätzlich eine(vx,vy)-Geschwindigkeit (in Pixel/Spielschritt).

Ändern Sie ausserdem den Konstruktor vonPongGame, dass er zweiPlayer- und eineBall- Instanz erstellt und in Feldern speichert. Der Ball soll zu Beginn des Spiels in der Mitte starten und eine zufällige Geschwindigkeit haben.

b) Ergänzen SiePongGuiso, dass Ball und Spielerbalken angezeigt werden und man die Balken mittels Tastatur (z.B. mit up, down und w, s) bewegen kann. In jedem Durchlauf der main- Schleife sollen Sie diestep()-Methode vonPongGameaufrufen. Ändern Siestep()so ab, dass sich der Ball entsprechend seiner Geschwindigkeit bewegt (noch ohne Kollisionen).

Starten Sie das Programm und überprüfen Sie, ob sich Spieler und Ball wie erwartet bewegen.

c) Fangen Sie jetzt instep()die Kollisionen des Balls mit den Wänden ab. Es gilt “Einfallswinkel ist gleich Ausfallswinkel”.

Tipp: Da alle Wände und Balken senkrecht oder waagrecht sind, ändert sich immer nur eine Komponente der Geschwindigkeit.

d) Stellen Sie das Spiel fertig, indem Sie in step() auch Kollisionen zwischen Ball und Spie- lerbalken abfangen. Sie können z.B. eine Methode in der KlassePongGameschreiben, welche überprüft, ob ein Ball mit einem gegebenen Spieler kollidiert.

Zählen Sie jetzt auch die Punkte der Spieler. Wenn der Ball eine Seitenwand berührt, gibt es einen Punkt und der Ball startet von Neuem in der Mitte des Feldes. Um den Punktestand zu zeichnen, können Sie dieWindow.drawString()-Methode verwenden.

Zusatz-Aufgabe: Erweitern Sie das Spiel so, dass mehrere Bälle gleichzeitig im Spiel sind. Immer nach50Spielschritten soll ein neuer Ball hinzukommen und wieder entfernt werden, wenn er das Spielfeld verlässt. Dafür sollen Sie die Klassen der Doubly-linked List kopieren und für Ball-Objekte anpassen.

Referenzen

ÄHNLICHE DOKUMENTE

Ihr Programm muss diese Bedingung nicht zwingend testen, Sie können aber eine Überprüfung implementieren. Wenn zahl diese Bedingung nicht erfüllt, dann ist das Ergebnis des

Schreiben Sie ein Programm “Zahlen.java”, das einen String, der eine Anzeige kodiert, einliest und die kodierte Zahl als

In der Übungs-Vorlage finden Sie das Programm “Perpetual- Calendar.java”, welches für jedes (gültige) Datum den Wochentag berechnet. Leider enthält das Programm noch Fehler, die

Das Spiel besteht aus einem Ball und aus zwei Spielern, welche je einen vertikalen Balken kontrollieren und versuchen, den Ball im Spiel zu halten. Wenn der Ball das Spiel

In dieser Aufgabe fügen Sie dieser LinkedIntList eine weitere Methode hinzu, welche die Liste umkehrt.. Eine Liste gilt als umgekehrt, wenn für jedes Paar von Nodes a und b, für

Die erste Ihrer parse*(...)-Methoden rufen Sie von parse(String) aus auf. Diese Methoden sollen eine EvaluationException mit einer sinnvollen Fehlermeldung werfen, falls

In der linken Spalte stehen die Programmteile (in der Reihenfolge, in der sie auch schon vom Interpreter fertig geparst werden) und in der rechten Spalte die

Eclipse hilft Ihnen dabei, indem es anzeigt, wo die Fehler sind (und eine mehr oder weniger hilfreiche Fehlermeldung dazu ausgibt), aber Sie müssen selber herausfinden, was das