MINT lernen

Projekt: Bücherverwaltung

Zwei Textaufgaben mit Hinweisen und Erwartungshorizont – dasselbe Vorgehen, übertragen auf den Spieleschrank der Brettspiel-AG.

Dein Fortschritt:
0 / 0 Aufgaben
1

Der Spieleschrank der Brettspiel-AG

AFB I–II

Die Brettspiel-AG verleiht ihre Spiele in den Pausen. Nach dem Vorbild der Bücherverwaltung plant sie ein Programm: Jedes Spiel hat einen Namen, eine kleinste und eine größte Zahl an Mitspielenden und ist ausgeliehen oder nicht. Der Spieleschrank verwaltet alle Spiele in einer Liste. Im Schrank stehen in dieser Reihenfolge: Catan (3–4), Dixit (3–8), Uno (2–10) und Azul (2–4).

Später soll eine Methode ausleihen(name) dazukommen: Sie gibt true zurück und markiert das Spiel als ausgeliehen, wenn es im Schrank steht und frei ist – sonst false.

Material 1: Klassendiagramm
Spieleschrank
  • - spiele: Liste vom Typ Spiel
  • c Spieleschrank()
  • + hinzufuegen(s: Spiel)
  • + suche(name: Zeichenkette): Spiel
  • + anzahlVerfuegbar(): Ganzzahl
verwaltet0..*
Spiel
  • - name: Zeichenkette
  • - minSpieler: Ganzzahl
  • - maxSpieler: Ganzzahl
  • - ausgeliehen: Wahrheitswert
  • c Spiel(name: Zeichenkette, minSpieler: Ganzzahl, maxSpieler: Ganzzahl)
  • + getName(): Zeichenkette
  • + getMinSpieler(): Ganzzahl
  • + getMaxSpieler(): Ganzzahl
  • + istAusgeliehen(): Wahrheitswert
  • + setAusgeliehen(ausgeliehen: Wahrheitswert)
Ein neues Spiel ist nicht ausgeliehen.
Material 2: Zwei Methoden der Klasse Spieleschrank
public Spiel suche(String name) {
    for (Spiel s : spiele) {
        if (s.getName().equals(name)) {
            return s;
        }
    }
    return null;
}

public int anzahlVerfuegbar() {
    int anzahl = 0;
    for (Spiel s : spiele) {
        if (!s.istAusgeliehen()) {
            anzahl++;
        }
    }
    return anzahl;
}
for (Spiel s : spiele) geht die Liste von vorn nach hinten durch.
  1. Beschreibe die Beziehung zwischen den beiden Klassen in Material 1 und die Aufgabe des Attributs spiele.
  2. Wende die Methode suche auf "Uno" und auf "Tabu" an. Gib jeweils die Zahl der Namensvergleiche und die Rückgabe an.
  3. Dixit und Azul werden ausgeliehen: schrank.suche("Dixit").setAusgeliehen(true); und schrank.suche("Azul").setAusgeliehen(true); Ermittle danach die Rückgabe von anzahlVerfuegbar() mit einer Tracetabelle.
  4. Gib drei unterschiedliche Testfälle für die geplante Methode ausleihen an – jeweils Aufruf, Ausgangslage und erwartetes Ergebnis.

Hinweise

Hinweis zu Aufgabe a)
Was bedeutet die Linie mit „verwaltet“ und „0..*“? Welcher Datentyp steckt hinter „Liste vom Typ Spiel“?
Hinweis zu Aufgabe b)
Gehe die Spiele in der Reihenfolge des Schranks durch. Die Methode endet sofort mit return, sobald der Name passt.„Anwenden“ heißt: das Verfahren mit genau diesen Werten Schritt für Schritt durchführen.
Hinweis zu Aufgabe c)
Spalten: aktuelles Spiel s, s.istAusgeliehen(), anzahl.
Hinweis zu Aufgabe d)
Welche Fälle kann es geben? Denke an ein freies, ein schon ausgeliehenes und ein gar nicht vorhandenes Spiel.

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

Zwischen Spieleschrank und Spiel besteht eine Assoziation „verwaltet“: Ein Spieleschrank kennt beliebig viele Spiele (0..*), auch keines. Das Attribut spiele ist in Java eine ArrayList<Spiel>; sie speichert Verweise auf die Spiel-Objekte und kann wachsen, wenn mit hinzufuegen neue Spiele dazukommen. Über die Liste kann der Schrank alle Spiele durchlaufen, z. B. zum Suchen oder Zählen.

Erwartungshorizont zu Aufgabe b)

suche("Uno"): Catan ≠ Uno, Dixit ≠ Uno, Uno = Uno – nach 3 Vergleichen wird das Spiel-Objekt Uno zurückgegeben.

suche("Tabu"): Alle 4 Namen werden verglichen, keiner passt; nach der Schleife wird null zurückgegeben („kein Spiel gefunden“).

Erwartungshorizont zu Aufgabe c)
ss.istAusgeliehen()anzahl
(Start)–0
Catanfalse1
Dixittrue1
Unofalse2
Azultrue2

Rückgabe: 2 – Catan und Uno sind verfügbar.

Erwartungshorizont zu Aufgabe d)
AufrufAusgangslageerwartet
ausleihen("Catan")Catan steht frei im Schranktrue, Catan danach ausgeliehen
ausleihen("Catan")Catan ist schon ausgeliehenfalse, nichts ändert sich
ausleihen("Tabu")Tabu gibt es nichtfalse, kein Absturz

Weitere sinnvolle Fälle, z. B. ein leerer Schrank, sind gleichwertig.

2

Ausleihen, Zurückgeben und passende Spiele finden

AFB II–III

Die AG baut ihr Programm aus Aufgabe 1 weiter. Neben ausleihen soll es zurueckgeben(name) geben (liefert true, wenn ein ausgeliehenes Spiel zurückkommt). Außerdem wünschen sich viele eine Hilfe für die Pause: „Wir sind zu dritt – welche freien Spiele passen?“

Die AG wächst: Bald sollen 40 Spiele im Schrank stehen, der Förderverein spricht sogar von 400. Und weil Uno so beliebt ist, schenkt ein Vater der AG ein zweites Uno, das ebenfalls mit hinzufuegen in die Liste kommt.

  1. Implementiere die Methoden ausleihen und zurueckgeben der Klasse Spieleschrank. Nutze suche.
  2. Erweitere die Klasse um eine Methode spieleFuer(personen: Ganzzahl): Liste vom Typ Spiel, die alle freien Spiele liefert, die für so viele Personen geeignet sind. Gib das Ergebnis für 3 Personen im Schrank aus Aufgabe 1 (nichts ausgeliehen) an.
  3. Schätze ab, wie viele Namensvergleiche suche bei 40 und bei 400 Spielen höchstens und im Mittel braucht, wenn das Spiel vorhanden ist.
  4. Bewerte, wie gut das Programm mit dem zweiten Uno zurechtkommt, und schlage eine Verbesserung vor.

Hinweise

Hinweis zu Aufgabe a)
suche kann null liefern – prüfe das, bevor du eine Methode am Ergebnis aufrufst. Ausgeliehen wird nur ein freies Spiel.
Hinweis zu Aufgabe b)
Lege in der Methode eine neue, leere ArrayList<Spiel> an, durchlaufe alle Spiele und füge passende hinzu. „Passend“: frei und minSpieler ≤ personen ≤ maxSpieler.
Hinweis zu Aufgabe c)
Günstigster Fall: das Spiel steht vorn. Ungünstigster Fall: ganz hinten. Im Mittel: Durchschnitt über alle möglichen Plätze.
Hinweis zu Aufgabe d)
Spiele durch: Das erste Uno ist ausgeliehen, jemand möchte Uno. Was liefert suche("Uno"), was ausleihen("Uno"), was anzahlVerfuegbar()? Kriterien: Korrektheit, Widerspruchsfreiheit, Aufwand der Änderung.

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)
public boolean ausleihen(String name) {
    Spiel s = suche(name);
    if (s == null || s.istAusgeliehen()) {
        return false;
    }
    s.setAusgeliehen(true);
    return true;
}

public boolean zurueckgeben(String name) {
    Spiel s = suche(name);
    if (s == null || !s.istAusgeliehen()) {
        return false;
    }
    s.setAusgeliehen(false);
    return true;
}

Die Prüfung auf null muss zuerst stehen: Wegen || wird s.istAusgeliehen() dann gar nicht mehr aufgerufen. Test: ausleihen("Uno") → true, nochmal → false, ausleihen("Tabu") → false.

Erwartungshorizont zu Aufgabe b)
public ArrayList<Spiel> spieleFuer(int personen) {
    ArrayList<Spiel> passend = new ArrayList<>();
    for (Spiel s : spiele) {
        if (!s.istAusgeliehen() && s.getMinSpieler() <= personen
                && personen <= s.getMaxSpieler()) {
            passend.add(s);
        }
    }
    return passend;
}

Für 3 Personen: Catan, Dixit, Uno und Azul – alle vier (Uno 2–10 und Azul 2–4 schließen die 3 ein). Zum Vergleich: für 6 Personen nur Dixit und Uno.

Erwartungshorizont zu Aufgabe c)

Höchstens: so viele Vergleiche, wie Spiele im Schrank stehen – 40 bzw. 400 (Spiel steht ganz hinten).

Im Mittel: Steht das Spiel mit gleicher Wahrscheinlichkeit auf jedem Platz, braucht man durchschnittlich \( \frac{n+1}{2} \) Vergleiche: 20,5 bei 40 und 200,5 bei 400 Spielen.

Die Zahl der Vergleiche wächst also proportional mit der Anzahl der Spiele: zehnmal so viele Spiele, etwa zehnmal so viele Vergleiche. Für eine Brettspiel-AG ist das trotzdem kein Problem – auch 400 Vergleiche erledigt ein Rechner in einem Augenblick.

Erwartungshorizont zu Aufgabe d)

Ablauf: Das erste Uno ist ausgeliehen. suche("Uno") liefert immer das erste Uno der Liste. ausleihen("Uno") gibt deshalb false zurück, obwohl das zweite Uno frei im Schrank liegt. Gleichzeitig zählt anzahlVerfuegbar() das zweite Uno als verfügbar – das Programm widerspricht sich selbst.

Bewertung: Für Spiele, die es nur einmal gibt, arbeitet das Programm korrekt. Mit Doppelten ist es fehlerhaft: Ein vorhandenes Spiel kann nicht verliehen werden. Das Problem ist ernst, weil gerade beliebte Spiele doppelt vorkommen.

Verbesserung: ausleihen sucht das erste freie Spiel mit dem Namen (eigene Schleife: equals und !istAusgeliehen()), zurueckgeben entsprechend das erste ausgeliehene. Alternativ bekommt jedes Spiel eine eindeutige Nummer. Jede begründete Bewertung mit tragfähigem Vorschlag ist vollständig.