Übungen zur objektorientierten Programmierung

76
Übungen zur objektorientierten Programmierung Klaus Becker 2013

description

Übungen zur objektorientierten Programmierung. Klaus Becker 2013. Objektorientierung. "Objektorientierung ist die derzeitige Antwort auf die gestiegene Komplexität der Softwareentwicklung." Oestereich: Objektorientierte Software-Entwicklung. - PowerPoint PPT Presentation

Transcript of Übungen zur objektorientierten Programmierung

Page 1: Übungen zur  objektorientierten Programmierung

Übungen zur objektorientierten Programmierung

Klaus Becker

2013

Page 2: Übungen zur  objektorientierten Programmierung

2 Objektorientierung

"Objektorientierung ist die derzeitige Antwort auf die gestiegene Komplexität der Softwareentwicklung."Oestereich: Objektorientierte Software-Entwicklung

Bei den hier zusammengestellten Übungen zur objektorientierten Programmierung geht es um einfache Spiele, die man am Computer ausführen kann. Ziel ist es, solche Spielprogramme mit Hilfe von Softwarebausteinen zu entwickeln.

Page 3: Übungen zur  objektorientierten Programmierung

3 Teil 1

Objekte und Klassen

Page 4: Übungen zur  objektorientierten Programmierung

4 Das Spiel 17-und-4

Ziel ist es, das Spiel 17-und-4 mit Hilfe geeigneter Softwarebausteine zu simulieren.

Wir spielen 17-und-4 hier in einer vereifachten Version. Man benötigt hierzu einen Kartenstapel, bei dem die Karten gut durchmischt sind.

Die Spieler können jetzt (reihum) Karten ziehen. Ziel ist es, mit den gezogenen Karten der Zahl 21 - also 17 und 4 - möglichst nahe zu kommen. Wer mit den gezogenen Karten mehr als 21 erzielt, hat allerdings verloren.

Jede Karte hat dabei einen festgelegten Kartenwert:

11 10 9 8 7 4 3 2

Page 5: Übungen zur  objektorientierten Programmierung

5 Kartenstapel

Was macht einen Kartenstapel aus?

vorhandene Karten

gezogene Karte

mischen

Karte ziehen

ist leer?

Ein Kartenstapel besteht aus einer Ansammlung noch vorhandener Karten und ggf. einer gezogenen Karte. Einen Kartenstapel kann man mischen. Wenn er nicht leer ist, dann kann man die oberste Karte ziehen.

Page 6: Übungen zur  objektorientierten Programmierung

6

Ein Bauplan für Kartenstapel-Objekte

from random import randint

class Kartenstapel(object): def __init__(self): self.kartenListe = [ 'X-A', 'X-K', 'X-D', 'X-B', 'X-10', 'X-9', 'X-8', 'X-7', 'P-A', 'P-K', 'P-D', 'P-B', 'P-10', 'P-9', 'P-8', 'P-7', 'H-A', 'H-K', 'H-D', 'H-B', 'H-10', 'H-9', 'H-8', 'H-7', 'K-A', 'K-K', 'K-D', 'K-B', 'K-10', 'K-9', 'K-8', 'K-7' ] self.gezogeneKarte = None

def alleKartenAuflegen(self): self.kartenListe = [ 'X-A', 'X-K', 'X-D', 'X-B', 'X-10', 'X-9', 'X-8', 'X-7', 'P-A', 'P-K', 'P-D', 'P-B', 'P-10', 'P-9', 'P-8', 'P-7', 'H-A', 'H-K', 'H-D', 'H-B', 'H-10', 'H-9', 'H-8', 'H-7', 'K-A', 'K-K', 'K-D', 'K-B', 'K-10', 'K-9', 'K-8', 'K-7' ] self.gezogeneKarte = None

def mischen(self): neueListe = [] aktuelleAnzahl = len(self.kartenListe) while aktuelleAnzahl > 0: i = randint(0, aktuelleAnzahl-1) neueListe = neueListe + [self.kartenListe[i]] del self.kartenListe[i] aktuelleAnzahl = len(self.kartenListe) self.kartenListe = neueListe ...

vorhandene Karten

gezogene Karte

mischen

Karte ziehen

ist leer?

Page 7: Übungen zur  objektorientierten Programmierung

7 Aufgabe 1

Auf I:1.10.2.1.2 findest du eine Implementierung der Klasse Kartenstapel.

Führe einen Python-Dialog zu einem 17-und-4-Spiel (mit einem einzigen Spieler). Erzeuge hierzu zunächst ein Objekt der Klasse Kartenstapel. Benutze anschließend passende Methoden. Inspiziere nach jedem Schritt den Objektzustand.

>>> >>> kartenstapel = Kartenstapel()>>> kartenstapel.kartenListe['X-A', 'X-K', 'X-D', 'X-B', 'X-10', 'X-9', 'X-8', 'X-7', 'P-A', 'P-K', 'P-D', 'P-B', 'P-10', 'P-9', 'P-8', 'P-7', 'H-A', 'H-K', 'H-D', 'H-B', 'H-10', 'H-9', 'H-8', 'H-7', 'K-A', 'K-K', 'K-D', 'K-B', 'K-10', 'K-9', 'K-8', 'K-7']...

Page 8: Übungen zur  objektorientierten Programmierung

8 Aufgabe 2

Die Verwendung eines Kartenstapel-Objekts kann man auch mit einem Testprogramm erkunden.

(a) Speichere das folgende Testprogramm im selben Ordner ab, in dem auch eine Datei spielkarten.py mit der Klassendeklaration der Klasse Kartenstapel gespeichert ist. Führe das Testprogramm anschließend aus und erläutere die erzeugten Ausgaben.

(b) Entwickle analog ein Testprogramm, das einen Kartenstapel erzeugt, die Karten mischt und anschließend solange die oberste Karte zieht und ausgibt, bis der Kartenstapel leer ist. Benutze dabei die in der Klassendeklaration vorgesehenen Operationen.

from kartenspiel import Kartenstapel# Testprogrammkartenstapel = Kartenstapel()print(kartenstapel.kartenListe)print(kartenstapel.gezogeneKarte)print()kartenstapel.mischen()print(kartenstapel.kartenListe)print(kartenstapel.gezogeneKarte)print()print(kartenstapel.istLeer())kartenstapel.karteZiehen()print(kartenstapel.kartenListe)print(kartenstapel.gezogeneKarte)

Page 9: Übungen zur  objektorientierten Programmierung

9 Kartenhaufen

Was macht einen einen Kartenhaufen aus?

Kartenliste Wert

Karte hinzufügen

Unter einem Kartenhaufen soll hier eine Ansammlung von Karten verstanden werden. Einem solchen Kartenhaufen kann man weitere Karten hinzufügen. Ein Kartenhaufen hat zudem einen Gesamtwert (das ist die Summe der Werte aller Karten des Kartenhaufens). Im vorliegenden Beispiel beträgt der Gesamtwert 23.

Page 10: Übungen zur  objektorientierten Programmierung

10 Aufgabe 3

class Kartenhaufen(object): def __init__(self): self.kartenListe = # ... self.wert = # ...

def hinzufuegen(self, karte): self.kartenListe = # ... if karte[2] == 'A': kartenwert = 11 elif karte[2] == 'K': kartenwert = 4 # ... self.wert = # ...

Die Klassendeklaration ist noch nicht ganz fertig. Kannst du die fehlenden Teile (mit #... markiert) ergänzen?

Wenn du die Klassendeklaration richtig ergänzt hast, dann kannst du als Test einen geeigneten Python-Dialog führen. Vorher musst du die Klassendeklaration aber einmal ausführen, damit sie vom Python-Ausführsystem übernommen wird.

Page 11: Übungen zur  objektorientierten Programmierung

11 Aufgabe 4

Speichere jetzt die Klassendeklarationen der Klassen Kartenstapel und Kartenhaufen in einer gemeinsamen Datei ab und führe sie einmal aus.

Simuliere anschließend ein 17-und-4-Spiel mit zwei Spielern. Hier der Beginn einer solchen Simulation.

>>> >>> >>> kartenstapel = Kartenstapel()>>> kartenstapel.mischen()>>> kartenhaufenSpieler1 = Kartenhaufen()>>> kartenhaufenSpieler2 = Kartenhaufen()>>> kartenstapel.karteZiehen()>>> karte = kartenstapel.gezogeneKarte>>> kartenhaufenSpieler1.hinzufuegen(karte)>>> kartenstapel.karteZiehen()>>> karte = kartenstapel.gezogeneKarte>>> kartenhaufenSpieler2.hinzufuegen(karte)>>> ...

Page 12: Übungen zur  objektorientierten Programmierung

12 Aufgabe 5

In der Datei kartenspiel.py befinden sich die Deklarationen der Klassen Kartenstapel und Kartenhaufen.

(a) Ein Spieler zieht seine Karten nach der folgenden Strategie: Solange der Gesamtwert aller Karten noch kleiner als 18 ist, wird eine Karte gezogen. Entwickle ein Simulationsprogramm zu dieser Strategie.

(b) Ein Spieler zieht seine Karten immer nach der folgenden Strategie: Solange der Kartenwert noch kleiner als 18 ist, wird eine Karte gezogen. Ermittle mit einer Simulation, wie oft der Spieler bei dieser Strategie im Mittel über der 21 landet.

Page 13: Übungen zur  objektorientierten Programmierung

13 Aufgabe 6

(a) Analysiere zunächst die Klasse Kartenhand. Welche Attribute werden hier festgelegt? Was sollen sie verwalten? Welche Methoden gibt es? Was sollen sie leisten? Beschreibe die Klasse auch mit einem Klassendiagramm.

class Kartenhand(object): def __init__(self): self.kartenListe = [] self.anzahl = 0

def hinzufuegen(self, karte): self.kartenListe = self.kartenListe + [karte] self.anzahl = self.anzahl + 1

def wegnehmen(self, karte): if karte in self.kartenListe: i = self.kartenListe.index(karte) del self.kartenListe[i] self.anzahl = self.anzahl - 1

>>> >>> meineKarten = Kartenhand()>>> meineKarten.hinzufuegen('P-B')>>> meineKarten.kartenListe?>>> meineKarten.hinzufuegen('H-10')>>> meineKarten.kartenListe?>>> meineKarten.hinzufuegen('P-A')>>> meineKarten.kartenListe?>>> meineKarten.wegnehmen('H-10')>>> meineKarten.kartenListe?>>> meineKarten.wegnehmen('X-7')>>> meineKarten.kartenListe?>>> meineKarten.anzahl?

(b) Was steht an Stelle der Fragezeichen? Überprüfe deine Vermutungen.

Page 14: Übungen zur  objektorientierten Programmierung

14 Aufgabe 6

(c) Die Deklaration der Klasse Kartenhand unterscheidet sich von der oben gezeigten nur im Kontruktor. Was ist hier anders? Wozu könnte das gut sein? Betrachte hierzu auch den folgenden Python-Dialog.

class Kartenhand(object): def __init__(self, kartenGegeben): self.kartenListe = kartenGegeben self.anzahl = len(self.kartenListe)

def hinzufuegen(self, karte): self.kartenListe = self.kartenListe + [karte] self.anzahl = self.anzahl + 1

def wegnehmen(self, karte): if karte in self.kartenListe: i = self.kartenListe.index(karte) del self.kartenListe[i] self.anzahl = self.anzahl - 1

>>> >>> meineKarten = Kartenhand(['X-A', 'H-A', 'P-7'])>>> meineKarten.kartenListe['X-A', 'H-A', 'P-7']>>> meineKarten.anzahl3

Page 15: Übungen zur  objektorientierten Programmierung

15 Aufgabe 6

(d) Erläutere die Unterschiede zu den bisher betrachteten Klassendeklarationen. Führe selbst einen Python-Dialog zum Testen aus. Dokumentiere mit diesem Dialog das Verhalten der einzelnen Methoden der Klasse.

class Kartenhand(object): def __init__(self, kartenGegeben): self.kartenListe = kartenGegeben self.anzahl = len(self.kartenListe)

def existiertKarte(self, karte): if karte in self.kartenListe: ergebnis = True else: ergebnis = False return ergebnis

def hinzufuegen(self, karte): if not self.existiertKarte(karte): self.kartenListe = self.kartenListe + [karte] self.anzahl = self.anzahl + 1

def wegnehmen(self, karte): if self.existiertKarte(karte): i = self.kartenListe.index(karte) del self.kartenListe[i] self.anzahl = self.anzahl - 1

Page 16: Übungen zur  objektorientierten Programmierung

16 Aufgabe 7

Gegeben ist ein Klassendiagramm zur Beschreibung einer Klasse Wuerfel.

(a) Erläutere die Bestandteile der Klasse Wuerfel: Welche Daten werden hier verwaltet? Welche Operationen soll ein Wuerfel-Objekt ausführen können?

(b) Implementiere zunächst die Klasse Wuerfel. Entwickle dann einen Python-Dialog zum Testen dieser Klasse. In diesem Dialog sollen zwei Würfelobjekte erzeugt und geworfen werden.

(c) Ermittle mit einem Testprogramm, wie oft man einen Würfel (durchschnittlich) werfen muss, bis die Summe der Augenzahlen der Würfelwürfe die Zahl 21 überschreitet. Benutze die Klasse Wuerfel, um ein Würfelobjekt zu erzeugen.

Page 17: Übungen zur  objektorientierten Programmierung

17 Aufgabe 8

Für viele Spiele benötigt man eine Art Punktekonto. Auf dieses Konto kann man eine vorgegebene Anzahl von Punkten "einzahlen", der Punktekontostand erhöht sich dann entsprechen. Man kann analog auch eine vorgegebene Anzahl von Punkten "abheben", natürlich nur, wenn genügend Punkte auf den Konto sind.

Entwickle zunächst ein Klassendiagramm mit allen benötigten Attributen und Methoden. Entwickle anschließend eine passende Implementierung und teste sie.

Page 18: Übungen zur  objektorientierten Programmierung

18 Teil 2

Modularisierung

Page 19: Übungen zur  objektorientierten Programmierung

19

Experimente mit Kartenhaufen-Objekten

class Kartenhaufen(object): def __init__(self): self.kartenListe = [] self.wert = 0

def hinzufuegen(self, karte): self.kartenListe = self.kartenListe + [karte] if karte[2] == 'A': kartenwert = 11 elif karte[2] == 'K': kartenwert = 4 elif karte[2] == 'D': kartenwert = 3 elif karte[2] == 'B': kartenwert = 2 elif karte[2] == '1': kartenwert = 10 elif karte[2] == '9': kartenwert = 9 elif karte[2] == '8': kartenwert = 8 … self.wert = self.wert + kartenwert

Page 20: Übungen zur  objektorientierten Programmierung

20 Aufgabe 9

>>> >>> meinKartenhaufen = Kartenhaufen()>>> meinKartenhaufen.hinzufuegen('K-B')>>> meinKartenhaufen.hinzufuegen('X-9')>>> meinKartenhaufen.kartenListe = meinKartenhaufen.kartenListe + ['H-K']>>> meinKartenhaufen.kartenListe['K-B', 'X-9', 'H-K']>>> meinKartenhaufen.wert11

(a) Welcher reale Vorgang wird hier simuliert? (b) Stimmt der angegebene Gesamtwert der Karten? Warum ist hier etwas schiefgelaufen?

Page 21: Übungen zur  objektorientierten Programmierung

21 Aufgabe 10

>>> >>> meinKartenhaufen = Kartenhaufen()>>> meinKartenhaufen.hinzufuegen('K-B')>>> meinKartenhaufen.hinzufuegen('X-9')>>> meinKartenhaufen.hinzufuegen('H-K')>>> meinKartenhaufen.getKartenListe()['K-B', 'X-9', 'H-K']>>> meinKartenhaufen.getWert()15

Ändere die Deklaration der Klasse Kartenhaufen passend zum Klassendiagramm ab.

Page 22: Übungen zur  objektorientierten Programmierung

22 Aufgabe 11

Betrachte die Klasse Kartenhand.

(a) Ergänze zunächst geeignete Zugriffsmethoden für die Attribute der Klasse.

(b) Ergänze die Implementierung um eine Schnittstellenbeschreibung, so dass die Klasse benutzt werden kann, ohne dass man sich die Implementierungsdetails anschauen muss.

class Kartenhand(object): def __init__(self, kartenGegeben): self.kartenListe = kartenGegeben self.anzahl = len(self.kartenListe)

def existiertKarte(self, karte): if karte in self.kartenListe: ergebnis = True else: ergebnis = False return ergebnis

def hinzufuegen(self, karte): if not self.existiertKarte(karte): self.kartenListe = self.kartenListe + [karte] self.anzahl = self.anzahl + 1

def wegnehmen(self, karte): if self.existiertKarte(karte): i = self.kartenListe.index(karte) del self.kartenListe[i] self.anzahl = self.anzahl - 1

Page 23: Übungen zur  objektorientierten Programmierung

23 Aufgabe 12

Zur Simulation von Lotto-Ziehungen wird hier eine Klasse Lottogeraet bereitgestellt. Du findest eine Implementierung dieser Klasse in der Datei lotto.py (siehe I:1.10.2.2.8).

(a) Teste die Klasse mit einem einfachen Testprogramm, das alle Methoden der Klasse benutzt.

(b) Löse mit Hilfe der Klasse folgendes Problem: Wie oft kommt deine Lieblingszahl (z.B. die 13) in 1000 Lottoziehungen vor?

from random import randint

class Lottogeraet(object): def __init__(self):

# erzeugt e. Obj. z. Simulation e. Lottogeraets

self.geraetVorbereiten() def geraetVorbereiten(self):

# fuellt das Lottogeraet mit Kugeln von 1..49 # leert den Behaelter der gezogenen Kugeln

self.vorhandeneKugeln = list(range(1, 50)) self.gezogeneKugeln = []

def kugelZiehen(self):

# zieht ei. Kugel aus den noch vorhand. Kugeln # entfernt diese Kugel aus dem Kugelbehaelter # legt d. Kugel i. Behaelter d. gezog. Kugeln ab…

Page 24: Übungen zur  objektorientierten Programmierung

24 Aufgabe 13

Betrachte noch einmal die Klasse Lottogeraet zur Simulation eines Lottogeräts.

Ziel ist es, die Implementierng der Klasse Lottogeraet so abzuändern, dass die vorhandenen bzw. gezogenen Kugeln mit Hilfe von Ankreuzfeldern (implementiert mit Listen mit 49 Wahrheitswerten) verwaltet werden. Am Verhalten der Methoden soll sich dabei aber nichts ändern.

(a) Entwickle eine passende Implementierung. Benutze zum Testen das Testprogramm aus Aufgabe 12.

(b) Was muss man nach Veränderungen in der Implementierung an der Schnittstellenbeschreibung ändern?

from random import randint

class Lottogeraet(object): def __init__(self):

# erzeugt e. Obj. z. Simulation e. Lottogeraets

self.geraetVorbereiten() def geraetVorbereiten(self):

# fuellt das Lottogeraet mit Kugeln von 1..49 # leert den Behaelter der gezogenen Kugeln

self.vorhandeneKugeln = list(range(1, 50)) self.gezogeneKugeln = []

def kugelZiehen(self):

# zieht ei. Kugel aus den noch vorhand. Kugeln # entfernt diese Kugel aus dem Kugelbehaelter # legt d. Kugel i. Behaelter d. gezog. Kugeln ab…

Page 25: Übungen zur  objektorientierten Programmierung

25 Teil 3

Beziehungen zwischen Objekten

Page 26: Übungen zur  objektorientierten Programmierung

26 Würfelspiele

Ziel ist es, Würfelspiele mit Hilfe von Objekten zu simulieren. Dabei steht hier das Zusammenspiel der Objekte im Vordergrund.

Page 27: Übungen zur  objektorientierten Programmierung

27 Aufgabe 14

Schaue dir die beiden folgenden Python-Dialoge genau an (und führe sie selber durch). Worin unterscheiden sie sich? Kannst du das unterschiedliche Verhalten auch erklären?

>>> >>> w1 = Wuerfel()>>> w2 = w1>>> w3 = w1>>> w1.werfen()>>> w1.getAugen()6>>> w2.getAugen()6>>> w3.getAugen()6>>> w2.werfen()>>> w2.getAugen()4>>> w1.getAugen()4>>> w3.getAugen()4

>>> >>> w1 = Wuerfel()>>> w2 = Wuerfel()>>> w3 = Wuerfel()>>> w1.werfen()>>> w1.getAugen()4>>> w2.getAugen()2>>> w3.getAugen()1>>> w2.werfen()>>> w2.getAugen()6>>> w1.getAugen()4>>> w3.getAugen()1

Page 28: Übungen zur  objektorientierten Programmierung

28 Ein Würfelbecher – Version 1

Würfelbecher werden benutzt, um Würfel so zu werfen, dass man keine Würfelergebnisse vorhersagen kann. Die Würfel werden hier nicht direkt geworfen, sondern man lässt sie aus dem Becher herausrollen. Dieser Vorgang soll mit geeigneten Software-Objekten simuliert werden.

from random import randint

class Wuerfel(object): def __init__(self): self.augen = randint(1, 6)

def werfen(self): self.augen = randint(1, 6)

def getAugen(self): return self.augen

# Testwuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()wuerfel1.werfen()wuerfel2.werfen()wuerfel3.werfen()print(wuerfel1.getAugen())print(wuerfel2.getAugen())print(wuerfel3.getAugen())

Page 29: Übungen zur  objektorientierten Programmierung

29 Ein Würfelbecher – Version 1

Bisher ist noch kein Objekt zur Simulation des Würfelbechers im Spiel. Ein solches Würfelbecher-Objekt soll jetzt hinzugefügt werden. Seine Aufgabe ist es unter anderem, die drei Würfel zu aktivieren. Um das zu ermöglichen, wird das Würfelbecher-Objekt mit Zeigern auf die Würfel-Objekte versehen.

…wuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()…

Page 30: Übungen zur  objektorientierten Programmierung

30 Aufgabe 15

#----------------------------------------# Wuerfel#----------------------------------------

from random import randint

class Wuerfel(object): …

#----------------------------------------# Wuerfelbecher#----------------------------------------

class Wuerfelbecher(object): def __init__(self): self.w1 = None self.w2 = None self.w3 = None

def wuerfelHerausrollen(self): self.w1.werfen() self.w2.werfen() self.w3.werfen()

# Testwuerfel1 = Wuerfel()

# 1wuerfel2 = Wuerfel()

# 2 wuerfel3 = Wuerfel()

# 3becher = Wuerfelbecher()

# 4becher.w1 = wuerfel1

# 5becher.w2 = wuerfel2

# 6becher.w3 = wuerfel3

# 7becher.wuerfelHerausrollen() # 8print(wuerfel1.getAugen()) # 9print(wuerfel2.getAugen()) # 10print(wuerfel3.getAugen()) # 11

(a) Die Anweisungen im Testprogramm sind durchnummeriert. Welche dieser Anweisungen werden benutzt, um die Objekte zu erzeugen und zu verbinden?

Aufgabe:

Ergänze einen Würfel.

Page 31: Übungen zur  objektorientierten Programmierung

(b) Worin unterscheidet sich die folgende Implementierung zum Würfelsystem von der Implementierung in Teilaufgabe (a)?

31 Aufgabe 15

…class Wuerfelbecher(object): def __init__(self): self.w1 = None self.w2 = None self.w3 = None

def setWuerfel(self, pW1, pW2, pW3): self.w1 = pW1 self.w2 = pW2 self.w3 = pW3

def getWuerfel(self): wListe = [self.w1, self.w2, self.w3] return wListe

def wuerfelHerausrollen(self): …

wuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()becher = Wuerfelbecher()becher.setWuerfel(wuerfel1, wuerfel2, wuerfel3)becher.wuerfelHerausrollen()print(wuerfel1.getAugen())print(wuerfel2.getAugen())print(wuerfel3.getAugen())

Page 32: Übungen zur  objektorientierten Programmierung

(c) Die Ausgabe der Würfelergebnisse könnte man hier auch anders realisieren. Wie?

32 Aufgabe 15

…class Wuerfelbecher(object): def __init__(self): self.w1 = None self.w2 = None self.w3 = None

def setWuerfel(self, pW1, pW2, pW3): self.w1 = pW1 self.w2 = pW2 self.w3 = pW3

def getWuerfel(self): wListe = [self.w1, self.w2, self.w3] return wListe

def wuerfelHerausrollen(self): …

wuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()becher = Wuerfelbecher()becher.setWuerfel(wuerfel1, wuerfel2, wuerfel3)becher.wuerfelHerausrollen()for wuerfel in …: print(…)

Page 33: Übungen zur  objektorientierten Programmierung

33 Aufgabe 15

#----------------------------------------# Wuerfel#----------------------------------------

from random import randint

class Wuerfel(object): …

#----------------------------------------# Wuerfelbecher#----------------------------------------

class Wuerfelbecher(object): def __init__(self, pW1, pW2, pW3): self.w1 = pW1 self.w2 = pW2 self.w3 = pW3

def wuerfelHerausrollen(self): self.w1.werfen() self.w2.werfen() self.w3.werfen()

# Testwuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()becher = Wuerfelbecher(wuerfel1, wuerfel2, wuerfel3)becher.wuerfelHerausrollen()print(wuerfel1.getAugen())print(wuerfel2.getAugen())print(wuerfel3.getAugen())

(d) Schaue dir den Konstruktor der Klasse Wuerfelbecher genau an. Was ist hier anders gemacht? Wie funktioniert die Er-zeugung und Ver-bindung der Objekte?

Page 34: Übungen zur  objektorientierten Programmierung

34 Ein Würfelbecher – Version 2

Einen Würfelbecher kann man mit einer unterschiedlichen Anzahl von Würfeln benutzen.

Die Klasse Wuerfelbecher soll jetzt so abgeändert werden, dass beliebig viele Wuerfel-Objekte verwaltet und aktiviert werden können.

Page 35: Übungen zur  objektorientierten Programmierung

35 Aufgabe 16

#----------------------------------------# Wuerfel#----------------------------------------

from random import randint

class Wuerfel(object): …

#----------------------------------------# Wuerfelbecher#----------------------------------------

class Wuerfelbecher(object): def __init__(self): self.wListe = []

def wuerfelHinzufuegen(self, w): # ...

def wuerfelHerausrollen(self): for w in self.wListe: # ...

# Testwuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()…becher = Wuerfelbecher()becher.wuerfelHinzufuegen(wuerfel1)becher.wuerfelHinzufuegen(wuerfel2)becher.wuerfelHinzufuegen(wuerfel3)…becher.wuerfelHerausrollen()print(wuerfel1.getAugen())print(wuerfel2.getAugen())print(wuerfel3.getAugen())…

(a) Ergänze die Implementierung der Klasse Wuerfelbecher so, dass das Testprogramm sinnvolle Ergebnisse liefert.

(b) Erkläre, wie die Objektkonstellation hier aufgebaut und genutzt wird.

Page 36: Übungen zur  objektorientierten Programmierung

36 Aufgabe 16

#----------------------------------------# Wuerfel#----------------------------------------

#----------------------------------------# Wuerfelbecher#----------------------------------------

class Wuerfelbecher(object): def __init__(self): self.wListe = []

def wuerfelHineinlegen(self, pWListe): self.wListe = self.wListe + pWListe

def wuerfelHerausrollen(self): for w in self.wListe: w.werfen() self.wListe = []

(c) Analysiere die folgende etwas andere Implementierung eines Würfelbechers. Worin unterscheidet sie sich von der oben betrachteten? Beschreibe in Worten, welche Objekte hier jeweils miteinander in Beziehung zueinander stehen.

Page 37: Übungen zur  objektorientierten Programmierung

37 Aufgabe 16

# Testwuerfel1 = Wuerfel()wuerfel2 = Wuerfel()wuerfel3 = Wuerfel()wuerfel4 = Wuerfel()wuerfel5 = Wuerfel()alleWuerfel = [wuerfel1, wuerfel2, wuerfel3, wuerfel4, wuerfel5]becher = Wuerfelbecher() # 1for wuerfel in alleWuerfel: print(wuerfel.getAugen())print()becher.wuerfelHineinlegen([wuerfel1, wuerfel2, wuerfel3]) # 2becher.wuerfelHerausrollen() # 3for wuerfel in alleWuerfel: print(wuerfel.getAugen())print()becher.wuerfelHineinlegen([wuerfel4, wuerfel5]) # 4becher.wuerfelHerausrollen() # 5for wuerfel in alleWuerfel: print(wuerfel.getAugen())

(d) Verdeutliche die an den markierten Stellen (#1, ..., #5) jeweils vorliegenden Objektkonstellationen mit Hilfe von Objektdiagrammen.

Page 38: Übungen zur  objektorientierten Programmierung

38 Ein Würfelbecher – Version 3

Bei einem realen Würfelsystem existieren Würfel und Würfelbecher unabhängig voneinander.

In der folgenden Simulation des Würfelsystems soll das jetzt etwas anders gestaltet werden.

Page 39: Übungen zur  objektorientierten Programmierung

39 Aufgabe 17

#----------------------------------------# Wuerfel#----------------------------------------…

#----------------------------------------# Wuerfelbecher#----------------------------------------

class Wuerfelbecher(object): def __init__(self): self.wListe = []

def wuerfelHinzufuegen(self): w = Wuerfel() self.wListe = self.wListe + [w]

def wuerfelHerausrollen(self): for w in self.wListe: w.werfen()

def getAlleWuerfel(self): return self.wListe

# Testbecher = Wuerfelbecher()becher.wuerfelHinzufuegen()becher.wuerfelHinzufuegen()becher.wuerfelHinzufuegen()becher.wuerfelHinzufuegen()becher.wuerfelHinzufuegen()becher.wuerfelHerausrollen()for wuerfel in becher.getAlleWuerfel(): print(wuerfel.getAugen())

(a) Wie wird die Objektkonstellation hier erzeugt? Wie zeigt sich das im Quelltext?

(b) Warum ist es in dieser Realisierung besonders einfach, weitere Würfel hinzuzufügen? Probiere es selbst aus.

Page 40: Übungen zur  objektorientierten Programmierung

40 Aufgabe 18

(a) Verdeutliche die Objektkonstellation zu einer selbst gewählten Spielsituation mit einem Objektdiagramm.

…wuerfel1 = Wuerfel()wuerfel2 = Wuerfel()

spieler1 = Spieler('Zauberhand')spieler1.setWuerfel(wuerfel2)

spieler2 = Spieler('Looser')spieler2.setWuerfel(wuerfel1)

for i in range(5): spieler1.wuerfeln() spieler2.wuerfeln() print('Punktestand', spieler1.getName(), ':', spieler1.getPunkte()) print('Punktestand', spieler2.getName(), ':', spieler2.getPunkte()) print()

…class Spieler(object): def __init__(self, pName): self.name = pName self.wuerfel = None self.punkte = 0

def setWuerfel(self, pWuerfel): self.wuerfel = pWuerfel def wuerfeln(self): self.wuerfel.werfen() self.punkte = self.punkte + self.wuerfel.getAugen()

def getName(self): return self.name

def getPunkte(self): return self.punkte

Page 41: Übungen zur  objektorientierten Programmierung

41 Aufgabe 18

(b) In der gezeigten Implementierung des Spiels wird eine Kennt-Beziehung benutzt. Woran erkennt man das? Ändere die Implementierung so ab, dass Hat-Beziehungen anstelle der Kennt-Beziehungen benutzt werden.

…wuerfel1 = Wuerfel()wuerfel2 = Wuerfel()

spieler1 = Spieler('Zauberhand')spieler1.setWuerfel(wuerfel2)

spieler2 = Spieler('Looser')spieler2.setWuerfel(wuerfel1)

…class Spieler(object): def __init__(self, pName): self.name = pName self.wuerfel = None self.punkte = 0

def setWuerfel(self, pWuerfel): self.wuerfel = pWuerfel def wuerfeln(self): self.wuerfel.werfen() self.punkte = self.punkte + self.wuerfel.getAugen()

def getName(self): return self.name

def getPunkte(self): return self.punkte

Page 42: Übungen zur  objektorientierten Programmierung

42 Aufgabe 18

(c) Wir ändern das Spielsystem wie folgt ab.

Beschreibe, was sich geändert hat. Implementiere und teste das neue Spielsystem.

Page 43: Übungen zur  objektorientierten Programmierung

43 Aufgabe 18

(d) Ein Spielmanager soll eine feste / beliebige Anzahl Spieler verwalten und zum Spielen aktivieren. Zudem soll der Spielmanager nach den Spielrunden den Gewinner ermitteln.

Entwickle zunächst ein Objektdiagramm für das erweiterte Spielsystem. Beschreibe das Spielsystem auch mit einem Klassendiagramm. Implementiere und teste das gesamte Spielsystem.

(e) Ändere das Spielsystem aus (d) wie folgt ab: Der Spielmanager verwaltet und aktiviert eine beliebige Anzahl von Spielern. Nach jeder Spielrunde scheidet der Spieler aus, der die geringste Punktzahl hat. Wenn es keinen eindeutigen Verlierer gibt, scheidet kein Spieler aus. Gespielt wird solange, bis der Gewinner feststeht.

Page 44: Übungen zur  objektorientierten Programmierung

44 Aufgabe 19

Wir betrachten das Spiel "chuck a luck". Das Spiel "chuck-a-luck" wird folgendermaßen gespielt:

Der Spieler / die Spielerin zahlt zuerst einen Dollar (Cent) als Einsatz. Diesen setzt er / sie auf eine Zahl des Spielfeldes. Anschließend wirft er / sie drei Würfel. Der Spielanbieter bestimmt, wie viele Würfel mit der gesetzten Spielzahl übereinstimmen. Gibt es keine Übereinstimmungen, ist der Einsatz verloren, ansonsten zahlt der Spielanbieter den Einsatz zurück und zusätzlich für jede Übereinstimmung einen Dollar (Cent).

Page 45: Übungen zur  objektorientierten Programmierung

45 Aufgabe 19

(a) Erstelle zunächst ein Objektdiagramm für eine Spielsituation. Ergänze dann das Klassendiagramm entsprechend.

(b) Implementiere das Spiel passend zum Klassendiagramm. Teste die Implementierung anschließend mit einem Testprogramm.

Page 46: Übungen zur  objektorientierten Programmierung

46 Teil 4

Vererbung

Page 47: Übungen zur  objektorientierten Programmierung

47 Kartenstapel als Stapel

Stapel werden im Alltag benutzt, wenn man Gegenstände nach dem LIFO-Prinzip verwalten möchte. LIFO bedeutet dabei "last in, first out" bzw. "wer zuletzt kommt, wir als erstes bearbeit".

Kartenstapel sind spezielle Stapel, bei denen Karten nach dem LIFO-Prinzip verwaltet werden. Kartenstapel weisen zusätzliche Besonderheiten auf. Die Karten eines Kartenstapels möchte man auch mischen können.

Zielsetzung:

Wir werden die Klasse Kartenstapel im Folgenden neu konzipieren. Wir werden dabei ausnutzen, dass Kartenstapel als spezielle Stapel aufgefasst werden können.

Page 48: Übungen zur  objektorientierten Programmierung

48 Stapel

Zur Realisierung des LIFO-Prinzips benötigt man Operationen, um ein neues Element oben auf dem Stapel abzulegen und um das oberste Element vom Stapel zu entfernen.

Page 49: Übungen zur  objektorientierten Programmierung

49 Aufgabe 20

Implementiere die Klasse Stapel und teste sie sorgfältig.

Stapel()# erzeugt einen leeren Stapel

aufDenStapelLegen(element: object)# legt element oben auf den Stapel

oberstesElement(): object# liefert als Ergebnis das oberste Stapelelement

oberstesEntfernen()# entfernt das oberste Stapelelement istLeer(): bool# liefert als Ergebnis True / False, je nachdem,# ob der Stapel leer ist oder nicht

Page 50: Übungen zur  objektorientierten Programmierung

50 Stapel mit Abheben

Die Modellierung der Klasse Stapel sieht nur einen Zugriff auf das oberste Element des Stapels vor. Für viele Anwendungen ist es günstig, wenn man einen ganzen Teilstapel abheben oder hinzufügen kann.

Zur Realisierung dieser zusätzlichen Stapeloperationen sehen wir eine neue Klasse StapelMitAbheben vor, die die bisherige Klasse Stapel erweitert.

Page 51: Übungen zur  objektorientierten Programmierung

51 Aufgabe 21

Ergänze die Implementierung der Basisklasse Stapel und der Erweiterungsklasse StapelMitAbheben.

class Stapel(object):

def __init__(self): self.listeElemente = []

class StapelMitAbheben(Stapel):

def __init__(self): Stapel.__init__(self)

def anzahlElemente(self): return len(self.listeElemente)

Page 52: Übungen zur  objektorientierten Programmierung

52 Stapel mit Mischen

Die Klasse StapelMitAbheben sieht bereits die Möglichkeit vor, Teilstapel abzuheben und hinzuzufügen. Mit diesen Operationen könnte man die folgende - auch in der Realität benutzte - Vorform des Mischens realisieren.

Wenn man diesen Vorgang mehrfach wiederholt, werden die Elemente des Ausgangsstapels gut durchmischt.

Page 53: Übungen zur  objektorientierten Programmierung

53 Aufgabe 22

Implementiere die Klasse StapelMitMischen als Erweiterung der Klasse StapelMitAbheben. Teste die neue Klasse mit einem Testprogramm.

Page 54: Übungen zur  objektorientierten Programmierung

54 Kartenstapel

Die Klasse StapelMitMischen sieht bereits eine Vielzahl von Methoden vor, die zur Realisierung der Klasse Kartenstapel sehr hilfreich sind. Wir modellieren daher die Klasse Kartenstapel als Erweiterung der Klasse StapelMitMischen.

Page 55: Übungen zur  objektorientierten Programmierung

55 Aufgabe 23

Implementiere die Klasse Kartenstapel als Erweiterung der Klasse StapelMitMischen.

Teste die Klasse Kartenstapel mit geeigneten Testprogrammen.

Page 56: Übungen zur  objektorientierten Programmierung

56 Teil 5

Miniwelt und Datenmodell

Page 57: Übungen zur  objektorientierten Programmierung

57 Miniwelt 17-und-4

Beim Spiel 17-und-4 geht es darum, so viele Karten von einem Kartenstapel zu ziehen, dass der Gesamtwert der Karten möglichst nahe an der 21 liegt und die Grenze 21 nicht überschreitet.

10+4=14

Page 58: Übungen zur  objektorientierten Programmierung

58 17-und-4 – vereinfachte Spielregeln

/1/ Für das Spiel wird ein gut durchmischter Kartenstapel benötigt. Von diesem Kartenstapel werden die Karten einzeln von oben gezogen.

/2/ Das Spiel wird mit zwei Spielpartnern durchgeführt. Der Benutzer übernimmt die Rolle eines Spielers. Der Computer übernimmt die Rolle des Spielmanagers. Dieser Spielmanager ist u.a. dafür verantwortlich, dass der Gewinn ausgezahlt wird.

/3/ Beide Spielpartner verfügen (zu Beginn) über ein Reservoir an Spielmarken. Der Spielmanager (als Vertreter des Spielanbieters) hat dabei ein sehr viel größeres Reservoir an Spielmarken.

/4/ Der Spieler muss als Einsatz mindestens 1 Spielmarke zahlen. Der Spieler kann jederzeit weitere Spielmarken als Einsatz zahlen. Nach jeder eingesetzten Spielmarke muss der Spieler aber eine Karte ziehen. Wenn der Spieler eine Spielmarke einsetzt, muss der Spielmanager stets nachziehen und ebenfalls eine Spielmarke setzen.

/5/ Der Spieler kann (nach dem Mindesteinsatz von 1 Spielmarke) Karten ziehen. Wenn die Summe der Werte der gezogenen Karten die Genze 21 überschreitet, dann darf der Spieler keine weiteren Karten mehr ziehen - er hat sich dann verzockt. Der Spieler sollte also rechtzeitig mit dem Kartenziehen aufhören. Der Spieler kann nach jeder gezogenen Karte das Spiel beenden.

Page 59: Übungen zur  objektorientierten Programmierung

59 17-und-4 – vereinfachte Spielregeln

/6/ Nachdem der Spieler seine Karten gezogen hat, ist der Spielmanager dran. Der Spielmanager soll hier nach folgenden Regeln Karten ziehen: Wenn die Summe der Werte der gezogenen Karten die 16 überschreitet, dann soll der Spielmanager mit dem Kartenziehen aufhören, ansonsten soll er eine Karte ziehen. Der Spielmanager entscheidet also nicht selbst, ob eine weitere Karte gezogen werden soll, sondern verfährt hier nach einer festen Regel.

/7/ Der Spielmanager ist für die Auszahlung des Gewinns zuständig. Wenn ein Spielpartner zu viele Karten gezogen hat (d.h. Karten mit einem Gesamtwert von mehr als 21), dann hat er auf jeden Fall verloren. Wenn beide Spielpartner verloren haben, dann wird der Einsatz nicht ausgezahlt und verbleibt im Einsatzdepot. Gewonnen hat ein Spielpartner, wenn er höchstens 21 Punkte erzielt hat und der andere sich verzockt hat, oder, wenn beide Spielpartner höchstens 21 Punkte erzielt haben und er die größere Punktzahl erzielt hat. Wenn beide Spielpartner höchstens 21 Punkte erzielt haben und dabei die gleiche Punktzahl erzielt haben, dann wird der Einsatz ebenfalls nicht ausgezahlt und verbleibt im Einsatzdepot.

Page 60: Übungen zur  objektorientierten Programmierung

60 Aufgabe 24

Oft ist es günstig, Software-Objekte so zu konzipieren, dass sie Objekten der Miniwelt entsprechen. Welche Objekte bieten sich bei der vorliegenden Miniwelt an? Beschreibe die Zuständigkeiten der Objekte.

10+4=14

Page 61: Übungen zur  objektorientierten Programmierung

61 Aufgabe 25

Gegeben ist die folgende Spielsituation: Der Spieler hat gerade eine Karte vom Kartenstapel gezogen: Kreuz Dame. Hierdurch erhöht sich die Punktzahl des Spielers auf 13. Der Spielmanager hat noch keine Karten gezogen. Entsprechen beträgt seine Punktzahl 0. Der Spieler hat - genau wie der Spielmanger - bisher zwei Spielmarken gesetzt. Der Spieler hat jetzt nur noch 5 Spielmarken auf seinem Spielmarkenkonto. Der Spielmanager verfügt noch über 101 Spielmarken. Die Karten des Kartenstapel sind gut durchmischt. Die nächste oben auf dem Stapel liegende (noch nicht sichtbare) Karte ist das Karo Ass.

Ergänze das Objektdiagramm so, dass alle Daten von einem passenden Objekt verwaltet werden. Führe hier geeignete Attribute ein und ordne ihnen in der Spielsituation vorkommenden Daten als momentane Attributwerte zu.

Page 62: Übungen zur  objektorientierten Programmierung

62 Aufgabe 26

Beschreibe eine Klasse Kartenstapel mit einem Klassendiagramm.

Page 63: Übungen zur  objektorientierten Programmierung

63 Aufgabe 27

Beim 17-und-4-Spiel werden die Spielpartner mit Spielkapital (z.B. in Form von Spielmarken) versehen. Mit diesem Spielkapital können sie Einsätze machen und auch Gewinne erzielen.

Es ist günstig, eine recht allgemein gehaltene Klasse Konto zur Kapitalverwaltung zu benutzen.

Entwickle und beschreibe eine Klasse Konto, die es erlaubt, einfache Kontooperationen (wie einzahlen und auszahlen) durchzuführen. Beachte auch, dass man manchmal nachfragen muss, ob noch Kapital auf dem Konto vorhanden ist.

Page 64: Übungen zur  objektorientierten Programmierung

64 Aufgabe 28

Ein Objekt der Klasse Spieler hat eine Reihe von Zuständigkeiten:

Verwaltung der aktuellen Punktzahl

Zugriff auf ein Konto-Objekts, mit dem die Spielmarken verwaltet werden

Zugriff auf das Kartenstapel-Objekt und das Konto-Objekt, mit dem die gesetzten Marken verwaltet werden

Punkte einer gezogenen Karte addieren

Einsatz in das Einsatzkonto zahlen

eine Karte vom Kartenstapel zahlen

Analysiere das Klassendiagramm und erläutere, wie die Zuständigkeiten hier realisiert werden.

Page 65: Übungen zur  objektorientierten Programmierung

65 Aufgabe 29

Ein Objekt der Klasse Spielmanager hat eine Reihe von Zuständigkeiten:

Verwaltung der aktuellen Punktzahl

Zugriff auf ein Konto-Objekts, mit dem die Spielmarken verwaltet werden

Zugriff auf das Kartenstapel-Objekt und das Konto-Objekt, mit dem die gesetzten Marken verwaltet werden

Zugriff auf das Spieler-Objekt

Punkte einer gezogenen Karte addieren

Einsatz in das Einsatzkonto zahlen

eine Karte vom Kartenstapel ziehen

ein Spiel vorbereiten (Kartenstapel mit allen Karten versehen, Punktstände auf 0 setzen)

den Kartenstapel veranlassen, die Karten zu mischen

den Gewinner ermitteln und ggf. den Gewinn auszahlen

Entwickle ein Klassendiagramm zur Klasse Spielmanager.

Page 66: Übungen zur  objektorientierten Programmierung

66 Aufgabe 30

Bisher haben wir bei der Modellierung außer Acht gelassen, dass Spielaktionen nicht in beliebiger Reihenfolge ausgeführt werden dürfen. So muss z.B. der Spieler eine Karte ziehen, wenn er einen Einsatz gezahlt hat. Unzulässig wäre es also, wenn der Spieler den Einsatz schnell noch erhöht, nachdem er mit einer gezogenen Karte 21 Punkte erreicht hat.

(a) Analysiere und erläutere das vorgegebene Zustandsdiagramm. (b) Ergänze es so, dass ein komplettes Spiel sinnvoll abgebildet ist.

Page 67: Übungen zur  objektorientierten Programmierung

67 Aufgabe 31

(a) Was soll die Methode karteZiehenSpieler leisten?

(b) Beschreibe analog die Ausführung der Methode karteZiehenSpielmanager() mit einem Struktogramm.

Page 68: Übungen zur  objektorientierten Programmierung

68 Aufgabe 32

Entwickle passend zum Datenmodell eine Implementierung, mit der man das Spiel 17-und-4 wie im folgenden Testprogramm (vgl. I: …) spielen kann.

Page 69: Übungen zur  objektorientierten Programmierung

69 Teil 6

Datenmodell und GUI

Page 70: Übungen zur  objektorientierten Programmierung

70 Grafische Benutzeroberfläche

Schöner wäre es, wenn der Benutzer die Spielaktionen über eine grafische Benutzeroberfläche ausführen könnte.

>>> gezogene Karte des Spielers: P-DDen Einsatz erhöhen? (j/n): jgezogene Karte des Spielers: X-10Den Einsatz erhöhen? (j/n): nNoch eine Karte ziehen? (j/n): jgezogene Karte des Spielers: K-8Den Einsatz erhöhen? (j/n): nNoch eine Karte ziehen? (j/n): ngezogene Karte des Spielmanagers: X-Agezogene Karte des Spielmanagers: H-8SpielerPunkte: 21Kontostand: 12SpielmanagerPunkte: 19Kontostand: 98

Die Ausführung des Spiels im Ausführfenster ist nicht sehr benutzerfreundlich.

Page 71: Übungen zur  objektorientierten Programmierung

71 Datenmodell und GUI

Als Beispiel betrachten wir die Anzeige eines Kartenstapels.

Wir betrachten hier die Verknüpfung mit einer grafischen Benutzeroberfläche mit einem Datenmodell.

Page 72: Übungen zur  objektorientierten Programmierung

72 Aufgabe 33

Mache dich mit dem Quelltext der Klasse GUI vertraut (siehe I: …). Ergänze den Quelltext so, dass es auf der Benutzeroberfläche eine zusätzliche Schaltfläche gibt, mit der man die Karten des Kartenstapels mischen kann.

#---------------------------------------------------# GUI#--------------------------------------------------- from tkinter import *gelb = "#FBD975"

class GUI(object): def __init__(self, datenmodell): # Referenzattribute zum Datenmodell self.kartenstapel = datenmodell[0] # Erzeugung des Fensters self.fenster = Tk() self.fenster.title("Kartenstapel") self.fenster.geometry('260x280') …

#---------------------------------------------------# Datenmodell#---------------------------------------------------

from kartenstapel import Kartenstapelkartenstapel = Kartenstapel()datenmodell = [kartenstapel]

#---------------------------------------------------# GUI-Objekt#---------------------------------------------------

gui = GUI(datenmodell)gui.fenster.mainloop()

Page 73: Übungen zur  objektorientierten Programmierung

73 Aufgabe 34

Begründe anhand des Quelltextes, dass u.a. folgende Objekte am Gesamtsystem beteiligt sind.

#-----------------------------------------------# Datenmodell#-----------------------------------------------

from kartenstapel import Kartenstapelkartenstapel = Kartenstapel()datenmodell = [kartenstapel]

#-----------------------------------------------# GUI-Objekt#-----------------------------------------------

gui = GUI(datenmodell)gui.fenster.mainloop()

Page 74: Übungen zur  objektorientierten Programmierung

74 Aufgabe 35

Aufgabe:

Das Software-System benutzt eine 2-Schichten-Architektur: Die obere Schicht ist für die GUI zuständig, die untere für das Datenmodell. Warum ist es günstig, wenn in der unteren Schicht (d.h. im Datenmodell) keine Bezüge auf die obere Schicht (d.h. die GUI) genommen werden?

Page 75: Übungen zur  objektorientierten Programmierung

75 Aufgabe 36

(a) Skizziere eine grafische Benutzeroberfläche zum 17-und-4-Spiel. Überlege dir dabei, welche Interaktionsmöglichkeiten der Benutzer mit der Software haben sollte.

10+4=14

Page 76: Übungen zur  objektorientierten Programmierung

76 Aufgabe 36

(b) Implementiere das gesamte Software-System. Benutze ein bereits getestetes Datenmodell zum 17-und-4-Spiel. Achte auch auf eine sinnvolle Software-Architektur (z.B. Zwei-Schichten-Architektur mit Befrager-Strategie).