Robots
Zur Navigation springen
Zur Suche springen
Links
Zielsetzung
Es soll ein Programm entwickelt werden, das eine grafische Robotersimulation implementiert. Das ganze wird mit ASCII-Grafik dargestellt.
Modell
- Es gibt ein rechteckiges Gelände.
- In dem Gelände gibt es rechteckige Hindernisse.
- Es gibt N Roboter, jeweils als Punkt gezeichnet.
- Jeder Roboter hat einen Namen: A...Z
- Jeder Roboter hat eine zufällige Ausgangsposition im Gelände.
- Jeder Roboter hat einen Zielpunkt (markiert mit "a"..."z"), zu dem er sich bewegen soll
- Ein Roboter kann nicht dort sein, wo sich ein Hindernis oder ein anderer Roboter befindet.
- Ein Roboter kann sich immer nur auf einen benachbarten Punkt bewegen (wenn sich dort nichts anderes befindet).
- Ein Simulationsschritt: Die Roboter bewegen sich eine Position weiter, wenn sie ihr Ziel noch nicht erreicht haben.
- Wenn der Roboter sein Ziel erreicht hat, bleibt er dort stehen.
- Wenn sich kein Roboter mehr bewegt, dann ist die Simulation beendet.
Farben
Die Farben werden in einer ASCII-Grafik mit Zeichen dargestellt. Weiß (genauer die Hintergrundfarbe) ist das Leerzeichen. Es gibt eine Wert DEFAULT_COLOR: Wenn dieser auftaucht, soll das Objekt seine eigene Farbe nehmen.
Die Klasse Sheet
- Definiere eine Klasse Sheet, die das "Zeichenblatt" modeliert.
- Parameter des Konstruktors: die Breite und die Höhe des Blattes.
- Wir speichern die "Punkte" in einer Liste von Zeilen: Jede Zeile ist ein String mit den Spalten, also $width Zeichen.
- Ein Punkt x, y wird also durch $list->lines[y][x] adressiert.
Konstruktor
- Erzeuge die Zeilenliste $height Einträgen, jeder Eintrag mit Länge $width.
clearTerminal()
Damit die ASCII-Grafik funktioniert, müssen wir ein "Terminal löschen" einbauen:
public function clearTerminal() { echo "\x1b\x5b\x48\x1b\x5b\x32\x4a\xc"; }
isOccupied()
- Definiere die Methode isOccupied, die als Parameter x und y bekommt und als Ergebnis eine Wahrheitswert liefert, ob der Punkt schon belegt ist.
- Belegt ist ein Punkt, wenn dort eine Farbe außer Weiß ist und wenn dort keine Farbe eines Zielpunktes ist.
setPoint()
- Definiere eine Methode, die einen Punkt in das Blatt einträgt. Parameter: x, y, color
setRandomPosition()
- Definiere eine Methode, die in einen Punkt (als Parameter) eine zufällige Position einträgt, die noch nicht belegt ist.
draw()
- Definiere eine Methode, die das Blatt ins Terminal ausgibt.
Klasse Point
- Definiere eine Klasse, die die Attribute x, y und Color hat.
- Definiere den Konstruktor mit den Parametern x, y, und color
draw()
- Definiere eine Methode, die als Parameter ein Blatt und eine Farbe bekommt.
- Zeichne die Position des Punktes in das Blatt: Wenn die Farbe den Wert DEFAULT_COLOR hat, soll die eigene Farbe genommen werden.
Klasse Rectangle
- Leite die Klasse Rectangle aus Punkt ab, mit den zusätzlichen Attributen width und height.
- Der Konstruktor hat die Parameter x, y, width, length und color
draw()
- Definiere eine Methode, die als Parameter ein Blatt und eine Farbe bekommt.
- Zeichne die Position aller Punkte des Rechteck in das Blatt: Wenn die Farbe den Wert DEFAULT_COLOR hat, soll die eigene Farbe genommen werden.
Klasse Robot
- Leite die Klasse Robot von Punkt ab, mit den zusätzlichen Parametern target, colorTarget, xDirection und yDirection
- xDirection kann die Werte +1 und -1 annehmen: wenn ein Hindernis umgangen werden soll, wird die x-Koordinate um diesen Wert geändert.
- yDirection kann die Werte +1 und -1 annehmen: wenn ein Hindernis umgangen werden soll, wird die y-Koordinate um diesen Wert geändert.
- Der Konstruktor hat die Parameter color und das Blatt sheet
- Im Konstrutor wird die zufällige Startposition eingestellt ($sheet->setRandomPosition())
setTarget()
- Wenn es noch kein Target gibt ($this->target == null): Erzeugen eines Targets.
- Sonst: Löschen des Punktes im Blatt: Zeichnen mit der Farbe weiß.
- Zufällige Position des Targets erzeugen ($sheet->setRandomPosition()).
checkDirection()
- Wenn die x-Koordinate den Wert 0 hat, wird xDirection auf +1 gesetzt: Damit wird die Richtung vom linken Rand weg eingestellt.
- Wenn die x-Koordinate den Wert $sheet->width - 1 hat, wird xDirection auf -1 gesetzt. Damit wird die Richtung vom rechten Rand weg eingestellt.
- Analog yDirection
move()
- Erzeuge die Methode mit dem Parameter sheet und dem Ergebistyp bool.
- Der Code kommt später. Liefere false als Ergebis.
Klasse Simulator
- Erzeuge eine Klasse, mit den Attributen:
- sheet: das Zeichenblatt.
- Ein Array statics, das die Hindernisse enthält.
- Ein Array mobiles, das die Roboter enthält.
- Der Konstruktor bekommt den Parameter sheet.
add()
- Definiere eine Methode add, die ein Element bekommt und den Parameter isStatic (als bool).
- Wenn isStatic true ist, trage in die Liste statics ein.
- Sonst trage in die Liste mobiles ein.
- Zeichne das Element.
buildBarriers()
- Definiere eine Methode, die als Parameter die Anzahl Reihen (rows) und Spalten (cols) bekommt.
- Die Hindernisse (Rechtecke) sollen eine Breite width und Höhe height haben.
- $width = $this->sheet->width / $rows / 2;
- Analog $height
- Der Abstand zum nächsten Hindernis soll $width bzw. $height haben
- Der Abstand vom Außenrand soll die Hälfte von $width bzw. $height sein.
buildRobots()
- Die Methode hat den Parameter count.
- Es werden count Roboter erzeugt und in der Liste mobiles eingetragen.
show()
Die Methode löscht das Terminal (clearTerminal) und zeichnet das Blatt.
step()
- Die Methode liefert einen bool-Wert: Wenn es eine Bewegung gab: true, sonst false.
- Die Methode hat eine Variable $countMoves.
- In einer Schleife werden alle Elemente aus mobiles geholt und deren Methode move() aufgerufen.
- Wenn diese den Wert true liefert (Element hat sich bewegt), dann erhöhe $countMoves.
- Liefere false, wenn $countMoves gleich 0 ist, sonst true
Hauptprogramm
- Erzeuge ein Blatt.
- Erzeuge einen Simulator.
- Erzeuge Hindernisse.
- Erzeuge Roboter.
- Eine Schleife: Solange es Bewegungen gibt, führe die Methode step() aus, danach warte 1 Sekunde.
- Gib die Anzahl der Schleifen aus, die benötigt wurden.
- Probiere das Programm aus.
Implementierung der Methode Robot::move()
- Setzen den Rückgabewert $rc auf false.
- Prüfe, ob der Zielpunkt erreicht ist.
- Wenn nein:
- Setze die Variablen $x und $y auf die aktuelle Position
- Wenn $x nicht den Wert von $target->x hat, ändere $x so, dass $x näher an $target->x ist
- Analog $y
- Korrigiere die Richtungen, wenn nötig: checkDirection()
- Wenn der Punkt (x, y) belegt ist:
- Bewege x in die eingestellte Richtung
- Wenn der Punkt (x, y) belegt ist: Bewege y in die eingestellte Richtung
- Wenn der Punkt (x, y) nicht belegt ist:
- Zeichne das Ziel.
- Lösche die alte Position (Zeichnen mit Weiß).
- Merke die Position.
- Zeichne den Punkt
- Merke, dass bewegt wurde: $rc = true