Kürzel: | asciishop-A04-PP |
Name: | AsciiShop, Runde#4 |
Kette: | Asciishop PP |
Kategorie: | Bildverarbeitung |
Mitgelieferte Datei(en):
Abzugebende Datei(en): AsciiImage.java, AsciiShop.java
Optional abzugebende Datei(en):
Ausführbar: AsciiShop
Die Klasse AsciiShop ist zu erstellen und soll eine ausführbare Klasse sein und muss daher die public static void main(String[] args) Methode beinhalten. Ihr Programm wird automatisch auf Korrektheit überprüft. Die Überprüfung erfolgt durch die Ausführung der als ausführbar bezeichneten Klasse (AsciiShop).
Das Programm liest eine angegebene Anzahl von Zeilen eines ASCII-Bildes ein. Diese Daten werden einem Objekt der Klasse AsciiImage zeilenweise hinzugefügt. Nach dem Einlesen des Bildes können mehrere Befehle folgen, um das Bild vertikal zu flippen oder transponieren, bzw. die Anzahl an unterschiedlichen vorkommenden Zeichen zu bestimmen. Zusätzlich soll auch der fill-Befehl aus Runde 3 benutzt werden können. Abschließend wird das Endergebnis ausgegeben.
Aufgabenstellung | Klassen und Methoden | Ein- und Ausgabedaten | Bewertung und Kriterien |
Hinweise | FAQ | Fehlerbehandlung | Testen |
Ein wichtiges Ziel in der Softwareentwicklung ist die sinnvolle Strukturierung von Code, um ihn so übersichtlicher und leichter erweiterbar zu machen. In der objektorientierten Programmierung werden hierzu Objekte (und Klassen) eingesetzt, die bestimmte Aufgaben erfüllen sollen. So liegt es nahe alle Informationen eines ASCII-Bildes in einem eigenen Objekt zu speichern.
Wie in Runde 3 soll wieder ein ASCII-Bilder eingelesen werden. Vor dem Einlesen des eigentlichen Bildes wird der Befehl read
erwartet, dessen Parameter die Anzahl der einzulesenden Zeilen angibt. So bedeutet der Befehl read 5
, dass genau 5 Zeilen eingelesen werden sollen. Werden anschließend mehr oder weniger Zeilen als erwartet eingegeben, so soll "INPUT MISMATCH
" ausgegeben werden.
Wie in den vorhergehenden Runden ist die main
-Methode des AsciiShop
für das Einlesen des Bildes und der Befehle zuständig. Diesmal werden jedoch die eingelesen Bildzeilen nicht in einem Array-Objekt gespeichert, sondern in einem Objekt vom Typ AsciiImage
. Dazu muss eine entsprechende Klasse definiert werden. In dieser Klasse gibt es die Methode addLine
, mit der dem Bild eine Zeile hinzugefügt werden kann. Diese Methode überprüft auch, ob die übergebene Zeile die richtige Länge hat. Ein Objekt der Klasse AsciiImage
speichert nicht nur die Bilddaten, sondern verwaltet auch die Höhe und Breite des Bildes. Auf diese Eigenschaften kann mittels der unten beschriebenen Methoden getWidth
und getHeight
zugegriffen werden.
Nach dem Einlesen des Bildes kann entweder gar kein Befehl oder einer oder mehrere der folgenden Befehlen eingegeben werden. Befehle, die in dieser Beispielrunde neu sind, sind farblich hervorgehoben:
uniqueChars
bestimmt mittels der Methode getUniqueChars
wieviele unterschiedliche Zeichen im Bild vorkommen. Das Ergebnis dieser Berechnung wird unmittelbar in einer eigenen Zeile ausgegeben.flip-v
spiegelt das Bild in vertikaler Richtung (sprich: vertauscht die erste mit der letzten Zeile, die zweite mit der vorletzten, usw.) durch Aufruf der entsprechenden Methode flipV
.transpose
transponiert das Bild durch Aufruf der Methode transpose
.fill
x y c
beginnt, ausgehend von der Position (x,y)
, alle angrenzenden Pixel, die die selbe Farbe, wie der Ausgangspixel haben, auf c
zu setzen (Floodfill, siehe Spezifikation zu Runde 3). Ist die Position unzulässig, so soll "OPERATION FAILED
" ausgegeben werden.
Die genannten Befehle uniqueChars
, flip-v
, transpose
und fill
haben entsprechende Objekt-Methoden in der Klasse AsciiImage
. Nach dem Einlesen können optional Befehle folgen. Alle hier aufgeführten Befehle können in beliebiger Reihenfolge und Häufigkeit auftreten.
uniqueChars
ist der einzige Befehl der eine unmittelbare Ausgabe erzeugt. Die anderen Befehle verändern das Bild.
Geben Sie im letzten Schritt das korrekt formatierte Bild, gefolgt von dessen Breite und Höhe aus. Rufen Sie dafür die entsprechenden Methoden in Ihrem AsciiImage
auf.
Bonusaufgaben werden nicht im Online-System getestet, die Beurteilung erfolgt erst während des Abschlussgesprächs.
In AsciiImage
soll die Methode public boolean isSymmetricH()
implementiert werden. Diese überprüft, ob das Bild horizontal symmetrisch ist - sprich ob jede Zeile für sich symmetrisch ist (oder anders formuliert: ob jede Zeile ein Palindrom ist - vgl. Palindrom). Diese Methode soll aufgerufen werden, falls der Befehl symmetric-h
eingegeben wird. Das Ergebnis (true/false) soll dann unmittelbar (analog zum Befehl uniqueChars
noch vor dem Bild) in einer eigenen Zeile ausgegeben werden.
Achten Sie auf die korrekte Datenkapselung. Insbesondere sollen Sie sinnvolle Zugriffsmodifikatoren für Variablen (und Methoden) verwenden.
main
-Methode. Sie verarbeitet die Eingaben, erzeugt das AsciiImage
und gibt das Ergebnis aus.
public static void main(String[] args)
System.in
ein und gibt direkt auf System.out
aus.System.in
ein, noch gibt sie direkt auf System.out
aus.
public AsciiImage()
public boolean addLine(String line)
false
zurückgegeben, andernfalls definiert die Länge der Zeile die Breite des Bildes. Danach übergebene Bildzeilen müssen dieser Breite entsprechen, ansonsten gibt die Methode false
zurück. Diese Methode muss sicherstellen, dass abhängige Eigenschaften des Bildes (Höhe, Breite) aktualisiert werden. Die Methode gibt true
zurück, wenn die Länge der Zeile mit der Breite des Bildes übereinstimmt und daher die Zeile dem Bild hinzugefügt werden konnte.public int getWidth()
public int getHeight()
public String toString()
public int getUniqueChars()
abaaabac
3 unterschiedliche Zeichen.public void flipV()
public void transpose()
public void fill(int x, int y, char c)
Beachten Sie die allgemeinen Hinweise zur Installation und zur Ein-/Ausgabe, sowie zur Abgabe und zur Beurteilung in den FAQ. Beispiele zum Umgang mit Ein-/Ausgabe sowie den Methoden der Klasse String
finden Sie im Skriptum oder in den Vorlesungsfolien.
Zur Speicherung der Bilddaten in AsciiImage soll ein einziger String verwendet werden. Dies ermöglicht das einfache Hinzufügen neuer Bildzeilen. Es gibt jedoch mehrere Möglichkeiten wie diese Daten darin abgelegt werden. Es empfiehlt sich alle Zeilen in einem (also ohne Zeilenumbrüche) zu speichern. In der toString
-Methode wird daraus ein korrekt formatierter String erzeugt.
Die Höhe und Breite des Bildes muss zusätzlich zum Bildinhalt in entsprechenden Objektvariablen gespeichert werden. Diese Information wird beispielsweise für die Bestimmung der Position eines Zeichens im String auf Grund der Pixelkoordinaten benötigt oder für die Implementierung der Methode toString
.
Die Methode muss sicherstellen, dass der von ihr zurückgegebene String das gespeicherte Bild in darstellbarer Form beinhaltet. Das bedeutet, dass das Bild, falls es wie unter Speicherung beschrieben gespeichert wird, in Zeilen unterteilt und dazu an den entsprechenden Stellen ein Zeilenumbruch ‘\n’ eingefügt werden muss. Um auf die einzelnen Zeichen/Zeilen des Bildes zuzugreifen, sollen Methoden der String-Klasse verwendet werden (charAt
). Die Methode liefert den korrekt formatierten String zurück. In der Methode selbst soll kein Aufruf von System.out.print
oder System.out.println
erfolgen.
Um die Anzahl an unterschiedlichen Zeichen zu bestimmen, ist es erforderlich das Bild (also den gesamten String) zu durchlaufen. Um die unterschiedlichen vorkommenden Zeichen zu zählen, können diese dabei in einem zusätzlichen String gespeichert werden: Mit Hilfe der Methode contains
der Klasse String
kann bei jedem Zeichen überprüft werden, ob dieses bereits in dem String vorkommt. Wenn es nicht vorkommt, so wird es dem String hinzugefügt, ansonsten wird das nächste Zeichen überprüft.
Um das Bild zu modifizieren, ist es sinnvoll den String des neuen Bildes Zeichen für Zeichen zusammenzubauen. Eine wichtige Überlegung dabei ist, wie gezielt auf ein bestimmtes Zeichen in dem Ursprungs-Bild zugegriffen werden kann: Dafür kann es vorteilhaft sein eine Methode private char getPixel(int x, in y)
zu implementieren, die das Zeichen an der entsprechenden x/y-Position zurückgibt. Überlegen Sie sich dann für jedes Zeichen an der Stelle (xneu
, yneu
) im neuen (sprich geflippten oder transponierten) Bild, an welcher Position (xalt
, yalt
) dieses im alten Bild war.
Um die Methode public void fill(int x, int y, char c)
zu implementieren, kann die Methode public static void fill(String[] data, int x, int y, char c)
aus Runde 3 umgebaut werden. Für die Implementierung kann es vorteilhaft sein, neben getPixel
auch eine Methode private void setPixel(int x, int y, char c)
zu implementieren, die das Zeichen an der entsprechenden x/y-Position neu setzt. Wird ein Pixel neu gesetzt, muss der String, der den Bildinhalt speichert, neu erzeugt werden. Um die Bestandteile des neuen Strings aus dem alten String auszulesen, kann die Methode substring
der Klasse String
benutzt werden.
Wenn Sie Fragen zur Implementierung oder auch zu Java haben, können Sie das Informatik-Forum nutzen. Im Rahmen der wöchentlichen Laborien stehen Tutoren für Fragen zur Verfügung. | ||
Informatik-Forum | Laborien |
Ein read
Befehl gefolgt von der Anzahl an Zeilen die einzulesen sind, gefolgt von den Zeilen eines Ascii-Bildes. Es darf davon ausgegangen werden, dass das Bild keine Leerzeichen enthält. Nach dem Einlesen des Bildes können die Befehle uniqueChars
, flip-v
, transpose
oder fill
(optional: symmetric-h
) folgen. Reihenfolge und Häufigkeit der Befehle ist beliebig.
Das korrekt formatierte ASCII-Bild sowie Höhe und Breite desselben. Wird der Befehl uniqueChars
eingegeben, so wird noch vor dem Bild in einer eigenen Zeile die Anzahl der unterschiedlichen vorkommenden Zeichen ausgegeben (optional: analog dazu wird bei Eingabe des Befehls symmetric-h
das Ergebnis in einer eigenen Zeile vor dem Bild ausgegeben).
Geben Sie "INPUT MISMATCH
" aus und brechen Sie die weitere Verarbeitung ab, falls einer der folgenden Fehler auftritt:
read
gefolgt von einer Zahlread
spezifiziertOPERATION FAILED
" aus und brechen Sie die weitere Verarbeitung ab der folgende Fehler auftritt:
fill
angegebene Position liegt ausserhalb des Bildbereichs
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|