i

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.

Welt

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.

Welt Welt

Hierzu muss das Objektmodell zur Roboterwelt erweitert werden. Zwei Vorschläge stehen zur Diskussion:

Vorschlag 1:

Objektdiagramm

Vorschlag 2:

Objektdiagramm

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:

Objektdiagramm

neu - Vorschlag 3:

Objektdiagramm

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.

Suche

v
7.2.4.5.1
www.inf-schule.de/oop/python/roboter/beziehungen/einstieg_roboterwelt
www.inf-schule.de/7.2.4.5.1
www.inf-schule.de/@/page/WbHQCns2NRtNUh1I

Rückmeldung geben