Robotersimulation - ein einfaches Beispiel für OOP-Anfänger

 

Diese in Excel-VBA implementierte Fallstudie ist im Hinblick auf folgende Punkte interessant:

 

  • Die Benutzerführung (das UI) beruht ausschließlich auf einem Formular
  • es ist eine sehr einfache, geradezu  primitive Simulation, die aber gerade aus diesem Grund gut für eine erste Bekanntschaft mit der objektorientierten Programmierung geeignet ist.

Das Programm soll dem Benutzer erlauben, einen Roboter auf einer rechtwinkligen Fläche zu bewe­gen. Die Bewegungsfläche entspricht einem Koordinatensystem, dessen Ursprung links oben liegt. Der Roboter kann sich nur parallel zu den Achsen dieses Koordinatensystems bewegen. Er hat nur vier mögliche Ausrichtungen (Blickrichtungen): nach Norden, nach Osten, nach Süden oder nach Westen.

Der Roboter ist mit einem sehr knapp bemessenen Satz von Befehlen ausgestattet. Er beherrscht folgende Bewegungen:

  • einen Schritt nach vorne (einsvor)
  • Drehung um 90° nach rechts (rechts)
  • Drehung um 90° nach links (links).

Es handelt sich insofern um eine Simulation, als der Roboter nicht real existiert. Der Benutzer kann sich jedoch vorstellen, dass ein realer Roboter vorhanden ist, der sich genau so verhält, wie die Bild­schirmausgaben dies anzeigen.

Das folgende Bild zeigt das Steuerpult, mit dem der Benutzer den Roboter bewegen kann. Die oben sichtbare Statusanzeige informiert den Benutzer über Position und Ausrichtung des Roboters. Unter­halb der Statusanzeige befinden sich die Steuertasten.  Für jeden der Basisbefehle ist eine Taste vor­handen.

 

 

Die Anwendung ist in zwei Schichten aufgebaut. Die obere Schicht enthält das UI in Form einer For­mularklasse RobotForm. Die untere Schicht besteht aus der Klasse robot, die den Roboter reprä­sen­tiert. Wir beginnen mit der Formularklasse:

 

'Formularklasse RobotForm (für Roboter mit Grundbefehlen)

 

Option Explicit

Private rob As robot

 

Private Sub UserForm_Initialize()

    Set rob = New robot

    rob.setStatus 100, 100, "n"

    Statusanzeige

End Sub

 

Private Sub Statusanzeige()

    Me.xTBx.Text = CStr(rob.getX)

    Me.yTBx.Text = CStr(rob.getY)

    Me.dirTBx.Text = rob.getDir

End Sub

 

Private Sub vorBtn_Click()

    rob.einsvor

    Statusanzeige

End Sub

 

Private Sub linksBtn_Click()

    rob.links

    Statusanzeige

End Sub

 

Private Sub RechtsBtn_Click()

    rob.rechts

    Statusanzeige

End Sub

 

Die Instanzenvariable rob bezeichnet den zu steuernden Roboter. Beim Laden des Formulars wird die Prozedur UserForm_Initialize ausgeführt;  in dieser Prozedur wird ein Objekt der Klasse robot ange­legt und der Variablen rob zugeordnet. Dann werden mit Hilfe von setStatus dem Roboter Werte für seinen Anfangszustand übergeben. Diese Werte werden anschließend mit einem Aufruf der Prozedur Statusanzeige auch in das Formular übernommen.

Für jede Steuerungstaste gibt es eine Ereignisprozedur, welche im Prinzip daraus besteht, zunächst den Befehl für die gewünschte Bewegung an den Roboter weiterzugeben und danach die Status­an­zeige zu aktualisieren.

Wir betrachten nun die Klasse robot:

 

Option Explicit

 

Private x As Integer    'waagrechte Position des Roboters

Private y As Integer    'senkrechte Position

Private dir As String   'Ausrichtung; mögliche Werte:  n, s, o, w

 

 

Public Sub setStatus(ByVal xstart As Integer, _

                     ByVal ystart As Integer, _

                     ByVal dirstart As String)

    x =   xstart

    y =   ystart

    dir = dirstart

End Sub

 

 

 

 

Public Sub einsvor()

    If dir = "n" Then

        y = y - 1

    ElseIf dir = "w" Then

        x = x - 1

    ElseIf dir = "s" Then

        y = y + 1

    Else                'dir = "o"

        x = x + 1

    End If

End Sub

 

 

Public Sub rechts()

    If dir = "n" Then

        dir = "o"

    ElseIf dir = "w" Then

        dir = "n"

    ElseIf dir = "s" Then

        dir = "w"

    Else                'dir = "o"

        dir = "s"

    End If

End Sub

 

 

Public Sub links()

    If dir = "n" Then

        dir = "w"

    ElseIf dir = "w" Then

        dir = "s"

    ElseIf dir = "s" Then

        dir = "o"

    Else               'dir = "o"

        dir = "n"

    End If

End Sub

 

 

Public Function getX()

    getX = x

End Function

 

 

Public Function getY()

    getY = y

End Function

 

 

Public Function getDir()

    getDir = dir

End Function

 

Die Instanzenvariablen x, y und dir dienen dazu, den aktuellen Zustand des Roboters festzuhalten. Die Methode setStatus positioniert den Roboter zu Beginn der Arbeit auf der Ebene. Die darunter stehenden Methoden lassen sich grob in Gruppen einteilen. Da sind zunächst die Prozeduren, welche Bewegungsaufträge ausführen, nämlich einsvor, rechts und links. Da der Roboter nicht wirk­lich existiert und sich daher auch nicht bewegen kann, beschränken sich diese Methoden darauf, den Zustand herzustellen, der sich beim Ausführen der jeweiligen Bewegung ergeben hätte.

Es folgt die Gruppe der drei Methoden getX, getY und getDir. Sie sind Informationsfunktionen und sollen erlauben, von der Steuerung aus den Zustand des Roboters zu erfragen. Diese Funktionen tun nichts weiter, als den aktuellen Zustand der Instanzenvariablen x, y und dir bekannt zu geben.

Die bisher besprochenen Methoden bilden zusammen die Basisbefehle des Roboters. Wir wollen für das Folgende annehmen, dass der Roboter so gebaut ist, dass er tatsächlich nur diese Grund­opera­tionen ausführen kann. Mit anderen Worten: wir verfügen über einen Roboter mit dem Befehlssatz

  • setStatus
  • einsvor
  • rechts
  • links
  • getX
  • getY
  • getDir

 

Leider ist unser Roboter etwas unbequem zu benutzen. Um ihn hundert Schritte nach vorne zu bewegen, muss der Benutzer am Steuerpult hundertmal die Vorwärtstaste drücken. Wir wollen annehmen, der Roboter sei mechanisch so beschaffen, dass er tatsächlich nur die drei Grundoperationen einsvor, rechts und links ausführen kann.

Es gibt jedoch die Möglichkeit, zusätzliche und umfangreichere Befehle zu programmieren, die auf den Basisbefehlen aufbauen. Hierfür benötigen wir eine Zusatzausstattung in Form einer Zwischeninstanz, welche die vom Benutzer erteilten Befehle in  Basisbefehle umwandelt.  Wie dies geschehen kann, wird in der anschließenden Fallstudie „OOP – Beispiel (2)" (Das Prinzip der Komposition) demonstriert.