Einstieg - Simulation eines Roboters
Er ist dann mal weg!
Bisher ist es möglich, dass der Roboter die Grenzen seiner Welt verlässt. Er muss sich nach der Erzeugung nur nach rechts drehen und einige Schritte vorwärts laufen und schon ist er weg.
Aufgabe 1
Der folgende Quelltext zeigt einen Auszug aus der Deklaration der Klasse Roboter
.
Ändere die Methode schritt
mit weiteren Fallunterscheidungen so ab,
dass der Roboter seine (8x8)-Welt
nicht mehr verlassen kann.
class Roboter(object):
def __init__(self):
self.x = 0
self.y = 0
self.r = 'S'
def schritt(self):
if self.r == 'O':
self.x = self.x + 1
elif self.r == 'S':
self.y = self.y + 1
elif self.r == 'W':
self.x = self.x - 1
elif self.r == 'N':
self.y = self.y - 1
...
Variable Weltgröße
Die Welt des Roboters soll flexibel einstellbar sein. Es soll also möglich sein, die Anzahl der Felder sowohl in x- wie auch in y-Richtung in beliebiger (sinnvoller) Weise vorzugeben.
Hierzu muss das Objektmodell zur Roboterwelt erweitert werden. Zwei Vorschläge stehen zur Diskussion:
Vorschlag 1:
Vorschlag 2:
Aufgabe 2
(a) Warum ist Vorschlag 2 im Sinne der Modularisierung wohl günstiger?
(b) Der folgende Quelltext zeigt die Implementierung einer Klasse Welt
.
class Welt(object):
def __init__(self, x, y):
self.felderX = x
self.felderY = y
def getFelderX(self):
return self.felderX
def getFelderY(self):
return self.felderY
def getZustand(self):
return (self.felderX, self.felderY)
def setZustand(self, x, y):
self.felderX = x
self.felderY = y
Wie erzeugt man mit dieser Klasse geeignete Objekte zur Modellierung der beiden oben in Bildern gezeigten Roboterwelten?
Weltgrenzen abtesten - erster Versuch
Wir ändern jetzt die Methode schritt
der Klasse Roboter
wie folgt ab:
<code>
class Roboter(object):
def __init__(self):
self.x = 0
self.y = 0
self.r = 'S'
def schritt(self):
if self.r == 'O' and self.x < welt.getFelderX()-1:
self.x = self.x + 1
elif self.r == 'S' and self.y < welt.getFelderY()-1:
self.y = self.y + 1
elif self.r == 'W' and self.x > 0:
self.x = self.x - 1
elif self.r == 'N' and self.y > 0:
self.y = self.y - 1
...
Mit einem Testprogramm sollen die Veränderungen überprüft werden. Beachte, dass die Datei
roboterwelt.py
die aktuellen Versionen
der Klassen Roboter
und Welt
enthält und im selben Verzeichnis liegt
wie das Testprogramm test.py
.
from roboterwelt import *
# Erzeugung der Objekte
welt = Welt(2, 2)
rob = Roboter()
# Testlauf
print(rob.getZustand())
rob.schritt()
print(rob.getZustand())
rob.schritt()
print(rob.getZustand())
rob.schritt()
print(rob.getZustand())
Bei der Ausführung des Testprogramms erhält man folgende Fehlermeldung:
<code>
Traceback (most recent call last):
...
elif self.r == 'S' and self.y < welt.getFelderY()-1:
NameError: global name 'welt' is not defined
Aufgabe 3
Hast du eine Erklärung für die Fehlermeldung?
Ein Zeiger auf das Weltobjekt
Wir verbessern jetzt Vorschlag 2, indem wird das Roboter
-Objekt mit einem Zeiger
auf das Welt
-Objekt versehen.
bisher - Vorschlag 2:
neu - Vorschlag 3:
Um eine solche Objektkonstellation erzeugen zu können, wird die Klasse Roboter
wie folgt erweitert:
class Roboter(object):
def __init__(self):
self.x = 0
self.y = 0
self.r = 'S'
self.w = None
...
def setWelt(self, w):
self.w = w
def getWelt(self):
return self.w
Aufgabe 4
Führe das folge Testprogramm aus. Erkläre, was die einzelnen Anweisungen bewirken.
from roboterwelt import *
# Erzeugung der Objekte
welt = Welt(2, 2)
rob = Roboter()
rob.setWelt(welt)
# Testlauf
print(rob.getWelt().getFelderX())
print(rob.getWelt().getFelderY())
Weltgrenzen abtesten - zweiter Versuch
Wir ändern jetzt in der erweiterten Klasse Roboter
die Methode schritt
wie folgt ab:
<code>
class Roboter(object):
def __init__(self):
self.x = 0
self.y = 0
self.r = 'S'
self.w = None
def schritt(self):
if self.r == 'O' and self.x < self.w.getFelderX()-1:
self.x = self.x + 1
elif self.r == 'S' and self.y < self.w.getFelderY()-1:
self.y = self.y + 1
elif self.r == 'W' and self.x > 0:
self.x = self.x - 1
elif self.r == 'N' and self.y > 0:
self.y = self.y - 1
...
def setWelt(self, w):
self.w = w
def getWelt(self):
return self.w
Jetzt sollte das folgende Testprogramm funktionieren:
from roboterwelt import *
# Erzeugung der Objekte
welt = Welt(2, 2)
rob = Roboter()
rob.setWelt(welt)
# Testlauf
print(rob.getZustand())
rob.schritt()
print(rob.getZustand())
rob.schritt()
print(rob.getZustand())
rob.schritt()
print(rob.getZustand())
Aufgabe 5
Probiere es aus. Führe auch noch weitere Tests aus.