# Roboter-Simulation



## El Kabong (16. Aug 2010)

Hallo!

Eigentlich ist meine Aufgabe keine richtige Hausaufgabe, eher eine Übungsaufgabe, deshalb bin ich mir nicht so sicher ob ich jetzt im richtigen Unterforum poste.
Folgendes ist meine Aufgabe:



> Implementieren Sie eine Klasse zur Simulation von Robotern.
> Ein Roboter hat eine Position (angegeben durch zwei int-Koordinaten) und eine Blick- bzw. Bewegungsrichtung
> (Norden, Osten, Süden, Westen oder auch oben, unten, rechts, links).
> Sehen Sie verschiedene Konstruktoren vor (mit Defaultwerten für Position und Richtung bzw. mit zu übergebenden
> ...



Und hier ist das was ich bisher habe:


```
public class Roboter {

    Scanner sc = new Scanner(System.in);
    int xposition;
    int yposition;
    int richtung;
    int NORDEN;
    int SUEDEN;
    int WESTEN;
    int OSTEN;
    int auswahl = sc.nextInt();

    public Roboter(int xposition, int yposition) {
        this.xposition = xposition;
        this.yposition = yposition;
    }

    public Roboter(int richtung) {
        this.NORDEN = 0;
        this.SUEDEN = 1;
        this.WESTEN = 2;
        this.OSTEN = 3;


        this.richtung = richtung % 4;
        if (this.richtung < 0) {
            this.richtung *= -1;
        }
    }

    public void step() {
        switch (auswahl) {
            case 1:
                this.yposition = this.yposition + 1;
            case 2:
                this.yposition = this.yposition - 1;
            case 3:
                this.xposition = this.xposition - 1;
            case 4:
                this.xposition = this.xposition + 1;

        }
    }

    public void turnLeft() {
        switch (auswahl) {
            case 1:
                this.yposition = this.yposition + 1 % 4;
            case 2:
                this.yposition = this.yposition - 1 % 4;
            case 3:
                this.xposition = this.xposition - 1 % 4;
            case 4:
                this.xposition = this.xposition + 1 % 4;
        }
    }

    public void turnRight() {
        switch (auswahl) {
            case 1:
                this.yposition = this.yposition + 1 % 4;
            case 2:
                this.yposition = this.yposition - 1 % 4;
            case 3:
                this.xposition = this.xposition - 1 % 4;
            case 4:
                this.xposition = this.xposition + 1 % 4;
        }
    }

    public void schritte(int schritte) {
        switch (auswahl) {
            case 1:
                this.yposition = this.yposition + 2;
            case 2:
                this.yposition = this.yposition - 2;
            case 3:
                this.xposition = this.xposition - 2;
            case 4:
                this.xposition = this.xposition + 2;
        }
    }

    public void show() {
        System.out.println("xposition" + xposition);
        System.out.println("yposition" + yposition);
        System.out.println("Richtung" + richtung);
    }
}
```

Okay, das mit der Vierteldrehung gestaltet sich für mich schwerer als zuerst gedacht. Da ich ja mit int arbeiten soll wird meine Idee nicht funktionieren. 
Ich hatte mir gedacht das ich den Roboter auf einer x und y Achse hoch, runter, links und rechts gehen lassen kann. Bei +1 soll der Roboter entweder hoch oder nach rechts gehen. Bei -1 nach unten oder nach links. Nun das mit der Vierteldrehung funktioniert da ich keine 0.25 als int Wert verwenden kann. Arrrrgh. 
Vielleicht hat ja jemand einen Tipp wie ich das Problem lösen kann.


Gruß,
El Kabong


----------



## faetzminator (16. Aug 2010)

Wenn S=0, W=1, N=2, O=3 (aufs "normale" Koordinatensystem bezogen), dann kannst du für rechts drehen [c]r = (r + 1) % 4[/c], links drehen [c]r = (r + 4 - 1) % 4[/c] und fürs bewegen [c]x = (r - 2) % 2[/c] und [c]y = (r - 1) % 2[/c] verwenden.


----------



## Final_Striker (17. Aug 2010)

Mit deinen beiden Konstruktoren hast du entweder einen Roboter, der zwar weiß wo er steht aber nicht weiß in welche Richtung er gehen soll oder einen Roboter, der weiß in welche Richtung er gehen soll aber nicht weiß wo er steht.^^

Und wieso bewegt sich dein Roboter, wenn er sich auf der Stelle dreht? ;-)


----------



## El Kabong (17. Aug 2010)

Final_Striker hat gesagt.:


> Mit deinen beiden Konstruktoren hast du entweder einen Roboter, der zwar weiß wo er steht aber nicht weiß in welche Richtung er gehen soll oder einen Roboter, der weiß in welche Richtung er gehen soll aber nicht weiß wo er steht.^^
> 
> Und wieso bewegt sich dein Roboter, wenn er sich auf der Stelle dreht? ;-)



Hm. Eigentlich wollte ich keinen Konstruktor für die Positionen machen, doch durch die Aufgabenstellung wurde ich ja praktisch dazu gezwungen. 

Ich hab jetzt meinen Code nochmal geändert, aber ich glaube nicht zum guten.
Das mit der Vierteldrehung ist mir immer noch nicht klar. Es ist doch egal was ich für Zahlen bei int nehme, der Wert wird doch sowieso immer auf eine ganze Zahl aufgerundet.


```
public Roboter(int xposition, int yposition) {
        this.xposition = xposition;
        this.yposition = yposition;
    }

    public Roboter(int richtung) {
        this.NORDEN = 0;
        this.SUEDEN = 1;
        this.WESTEN = 2;
        this.OSTEN = 3;


        this.richtung = richtung % 4;
        if (this.richtung < 0) {
            this.richtung *= -1;
        }
    }

    public void step() {
        switch (auswahl) {
            case 1:
                this.yposition = (richtung -1) % 2;
            case 2:
                this.yposition = (richtung - 1) % 2 ;
            case 3:
                this.xposition = (richtung - 2) % 2;
            case 4:
                this.xposition = (richtung -2) % 2;

        }
    }

    public void turnLeft() {
        switch (auswahl) {
            case 1:
                this.yposition = (richtung + 4 -1) % 4;
            case 2:
                this.yposition = (richtung + 4 -1) % 4;
           
        }
    }

    public void turnRight() {
        switch (auswahl) {
            case 1:
                this.yposition = (richtung -1) % 2;
            case 2:
                this.yposition = (richtung - 1) % 2;
          
        }
    }

    public void schritte(int schritte) {
        switch (auswahl) {
            case 1:
                this.yposition = this.yposition + schritte;
            case 2:
                this.yposition = this.yposition - schritte;
            case 3:
                this.xposition = this.xposition - schritte;
            case 4:
                this.xposition = this.xposition + schritte;
        }
    }
```


----------



## XHelp (17. Aug 2010)

Also der Scanner bzw. die Eingabe hat in dem Roboter eigentlich nichts verloren.
Falls du "%" als mathematisches Modulo verwendest, dann verwendest du es falsch, weil -1 mod 4 ist nicht 1
Für die Richtung würde ich enums verwenden (zumal ich die Aufgabe auch so deute):

```
public static enum Direction {
  WEST, NORTH, EAST, SOUTH
}
```

Desweiteren brauchst du nur 3 Instanzvariablen: int xPos, yPos und Direction direction
Um den Code nicht so redundant zu machen, kannst du einmal einen Konstruktor implementieren, der alles an Parameter besitzt:

```
public Roboter(int xPos, int yPos, Direction direction) {
  this.xPos = xPos;
  this.yPos = yPos;
  this.direction = direction;
}
```
Dann kannst du bei den restlichen Konstruktoren ihn aufrufen, z.B.:

```
public Roboter(int xPos, int yPos) {
  this(xPos, yPos, Direction.WEST);
}
```
Mir ist nicht klar, was du mit dem switch beim drehen machst, aber mit den Enums könnte z.B. die Drehung nach links so aussehen:

```
direction = Direction.values()[(direction.ordinal() + 3) % 4];
```
(ist eigentlich -1, aber um negative Werte zu vermeiden rechne ich noch +4 dazu, was sich bei modulo eh zu 0 auflöst)
Schritt machen läuft dann genau so wie bei dir. Und auch hier kannst du zunächst 
	
	
	
	





```
step(int stepCount)
```
 implementieren und bei 
	
	
	
	





```
step()
```
 einfach 
	
	
	
	





```
step(1)
```
 aufrufen.

So, ich hoffe dass es a) dir weiter hilft und b) ich nicht zu viel verraten habe.


----------



## ARadauer (17. Aug 2010)

Ich finde das ist mal eine schöne Übungsaufgabe!


----------



## faetzminator (17. Aug 2010)

Wenn du meinen Ansatz verwendest, benötigst du überhaupt kein switch...


----------



## Final_Striker (17. Aug 2010)

Ein Roboter bewegt sich beim Drehen nicht von der Stelle, aber du veränderst immer noch seine Position!



El Kabong hat gesagt.:


> Hm. Eigentlich wollte ich keinen Konstruktor für die Positionen machen, doch durch die Aufgabenstellung wurde ich ja praktisch dazu gezwungen.


Nö. Da steht "überlegen sie sich sinnvolle Konstruktoren" und nicht "erstellen die zwei sinnlose Konstruktoren". Das ist ein sehr großer Unterschied. ;-)


----------



## faetzminator (17. Aug 2010)

...und ich weiss immer noch nicht, warum da [c]switch[/c]s sind. Hier ein Beispiel mit meinen Erläuterungen, da fehlen nur noch die Konstruktoren und [c]show()[/c] 

```
public static final int NORDEN = 2;
public static final int SUEDEN = 0;
public static final int WESTEN = 1;
public static final int OSTEN = 3;

private int x;
private int y;
private int r;

public void step() {
    x += (r - 2) % 2;
    y += (r - 1) % 2;
}

public void turnLeft() {
    r = (r + 4 - 1) % 4;
}

public void turnRight() {
    r = (r + 1) % 4;
}
```


----------



## XHelp (17. Aug 2010)

Bei 
	
	
	
	





```
step()
```
 müsste es allerdings 
	
	
	
	





```
+=
```
 heißen (bestimmt tippfehler)


----------



## faetzminator (17. Aug 2010)

Ja, natürlich


----------



## El Kabong (17. Aug 2010)

Also, dann nochmal ein überarbeiteter Code von mir.
enum darf, oder kann ich nicht verwenden da das Thema bei uns noch nicht behandelt wurde. Deshalb bleib ich erstmal bei dem was bisher behandelt wurde. Ich hab jetzt die Aufgabe nochmal gelesen und jetzt einfach zwei Konstruktoren für die Richtung und die Position gemacht, aber diesmal etwas anders als in meinen erstem Code. 


```
public class Roboter {

    int NORDEN = 0;
    int SUEDEN = 1;
    int WESTEN = 2;
    int OSTEN = 3;
    int richtung = OSTEN;
    static int[] x = {1, 0, -1, 0};
    static int[] y = {0, 1, 0, -1};
    int xPosition = 0;
    int yPosition = 0;

    public Roboter(int xPosition, int yPosition) {
        this.xPosition = xPosition;
        this.yPosition = yPosition;


    }

    public Roboter(int richtung) {
        this.richtung = richtung % 4;
        if (this.richtung < 0) {
            this.richtung *= -1;

        }
    }

    public void step() {
        xPosition = xPosition + x[richtung];
        yPosition = yPosition + y[richtung];

    }

    public void turnLeft() {
        richtung = (richtung + 1) % 4;

    }

    public void turnRight() {
        richtung = (richtung + 3) % 4;

    }

    public void steps(int steps) {
        xPosition = xPosition + x[richtung] + steps;
        yPosition = yPosition + y[richtung] + steps;

    }

    public void show() {
        System.out.println("xposition" + x);
        System.out.println("yposition" + y);
        System.out.println("Richtung" + richtung);

    }
}
```


----------



## XHelp (17. Aug 2010)

Ne, das funktioniert so nicht.
Zunächst ein mal: was ist, wenn ich ein Roboter erstellen will, der Richtung Timbuktu schaut und auf 2,2 steht? 

```
richtung = (richtung + 1) % 4;
```
Das funktioniert nur, wenn die in die Richtungen in einer sinnvollen Reihenfolge stehen. Bei dir würde ja mit einer Drehung von Norden nach Süden drehen.

[/code]
public void steps(int steps) {
  xPosition = xPosition + x[richtung] + steps;
  yPosition = yPosition + y[richtung] + steps;
}

```
Das funktioniert so auch nicht, da er ja immer steps dazurechnen würde. Du brauchst ein * und kein +

Hast du es selber überhaupt ausprobiert?
```


----------



## El Kabong (17. Aug 2010)

Sicher probier ich meinen Code aus. Ich werd dann morgen Abend nochmal eine Überarbeitung posten.


----------



## XHelp (17. Aug 2010)

Da war nur keine Frage dabei, deswegen habe ich anfangs gedacht, dass es dann quasi vollständigkeitshalber die Endlösung.


----------



## El Kabong (18. Aug 2010)

XHelp hat gesagt.:


> Ne, das funktioniert so nicht.
> Zunächst ein mal: was ist, wenn ich ein Roboter erstellen will, der Richtung Timbuktu schaut und auf 2,2 steht?
> 
> ```
> ...



Ja, ich glaube der Fehler ist die +1. Anstatt der +1 müsste dort eine +3 stehen.
Ich habe das mit den Positionen 2,2 getestet und jetzt müsste es funktionieren, zumindest dreht sich der Roboter jetzt immer um eine Position anstatt um 2.

Das müsste jetzt der komplett richtige Code sein. Meiner Meinung jedenfalls nach. 


```
public class Roboter {

    int NORDEN = 0;
    int SUEDEN = 1;
    int WESTEN = 2;
    int OSTEN = 3;
    int richtung = OSTEN;
    static int[] x = {1, 0, -1, 0};
    static int[] y = {0, 1, 0, -1};
    int xPosition = 0;
    int yPosition = 0;

    public Roboter(int xPosition, int yPosition) {
        this.xPosition = xPosition;
        this.yPosition = yPosition;


    }

    public Roboter(int richtung) {
        this.richtung = richtung % 4;
        if (this.richtung < 0) {
            this.richtung *= -1;

        }
    }

    public void step() {
        xPosition = xPosition + x[richtung];
        yPosition = yPosition + y[richtung];

    }

    public void turnLeft() {
        richtung = (richtung - 3) % 4;

    }

    public void turnRight() {
        richtung = (richtung + 3) % 4;

    }

    public void steps(int steps) {
        xPosition = xPosition + x[richtung] * steps;
        yPosition = yPosition + y[richtung] * steps;

    }

    public void show() {
        System.out.println("xposition " + xPosition);
        System.out.println("yposition " + yPosition);
        System.out.println("Richtung " + richtung);

    }
}
```


----------



## XHelp (19. Aug 2010)

El Kabong hat gesagt.:


> Ja, ich glaube der Fehler ist die +1. Anstatt der +1 müsste dort eine +3 stehen.
> Ich habe das mit den Positionen 2,2 getestet und jetzt müsste es funktionieren, zumindest dreht sich der Roboter jetzt immer um eine Position anstatt um 2.


In wie fern hat die Position des Roboters damit zu tun, ob er richtig dreht oder nicht? 
Ich wiederhole mich zwar, aber hast du es selber mal getestet? Ich meine wirklich mal getestet.

```
public static void main(String[] args) {
	Roboter rob = new Roboter(0);
	rob.show();
	rob.step();
	rob.show();
	rob.show();
	for (int i = 0; i < 4; i++) {
		rob.turnLeft();
		rob.show();
	}
	for (int i = 0; i < 4; i++) {
		rob.turnRight();
		rob.show();
	}
}
```
Einfach mal ausführen und gucken was passiert. Wenn er nach norden zeigt, dann geht er nach osten (usw), beim drehen läuft auch alles schief.


> Das müsste jetzt der komplett richtige Code sein. Meiner Meinung jedenfalls nach.


Dem muss ich leider widersprechen


----------



## El Kabong (21. Aug 2010)

Also mit der Blickrichtung komm ich wirklich ins grüblen, bzw. gar nicht mehr weiter.
Mit diesem Code bin ich wenigstens noch etwas erfolgreich gewesen, denn der Roboter dreht sich hier wenigstens in eine Richtung und wieder zurück. Allerdings dreht er sich in die falsche Richtung und der Code ist auch nur für nicht für jede Richtung anwendbar. Wenn der Roboter zuerst nach Süden blickt funktioniert die Drehung prima, ebenfalls wenn er Richtung Osten blickt. Blickt der Roboter allerdings Richtung Norden macht er eine 180° Drehung, warum das so ist versteh ich allerdings nicht. 



```
public void turnRight() {
        richtung = (richtung  + 4 - 1) % 4;

    }

    public void turnLeft() {
        richtung = (richtung  + 1) % 4;

    }
```


----------



## XHelp (21. Aug 2010)

El Kabong hat gesagt.:


> Blickt der Roboter allerdings Richtung Norden macht er eine 180° Drehung, warum das so ist versteh ich allerdings nicht.




```
int NORDEN = 0;
 int SUEDEN = 1;
 int WESTEN = 2;
 int OSTEN = 3;
```

Weil deine Reihenfolge von den Richtungen falsch ist.


----------



## faetzminator (22. Aug 2010)

... was ich schon x Mal schrieb...


----------



## El Kabong (23. Aug 2010)

So, ich hoffe jetzt ist alles richtig.


```
public class Roboter {

    int NORDEN = 1;
    int SUEDEN = 3;
    int WESTEN = 2;
    int OSTEN = 0;
    int richtung = OSTEN;
    int[] x = {1, 0, -1, 0};
    int[] y = {0, 1, 0, -1};
    int xPosition = 0;
    int yPosition = 0;

    public Roboter(int xPosition, int yPosition) {
        this.xPosition = xPosition;
        this.yPosition = yPosition;


    }

    public Roboter(int richtung) {
        this.richtung = richtung % 4;
        if (this.richtung < 0) {
            this.richtung *= -1;

        }
    }

    public void step() {
        xPosition = xPosition + x[richtung];
        yPosition = yPosition + y[richtung];

    }

    public void turnLeft() {
        richtung = (richtung + 1) % 4;

    }

    public void turnRight() {
        richtung = (richtung + 3) % 4;

    }

    public void steps(int steps) {
        xPosition = xPosition + x[richtung] * steps;
        yPosition = yPosition + y[richtung] * steps;

    }

    public void show() {
        System.out.println("xposition " + xPosition);
        System.out.println("yposition " + yPosition);
        System.out.println("Richtung " + richtung);

    }
}
```


----------



## XHelp (23. Aug 2010)

Noch ein Tipp: ich weiß nicht wer und ob das korrigiert wird, aber ich denke mal, sie wollen noch einen Konstruktor mit Position UND Richtung sehen (ich hätte es gewollt)


----------



## wottpal (15. Sep 2010)

Vielleicht interessiert dich ja diese Aufgabe, wenn du deine erledigt hast. Ist zwar komplexer, jedoch interessant.

*Robuttons*
Die kleinen runden Robuttons aus den Packungen mit Frühstücksflocken können nicht viel
mehr als knapp über der Tischplatte schwebend geradeaus fahren und genauso große 5-Cent-
Münzen mit ihrem Magneten auflesen.
Dabei verhalten sie sich so: Wenn ein Robutton auf eine Münze trifft, hebt er sie auf und fährt
mit ihr weiter, ohne seine Richtung zu verändern; trifft er allerdings auf eine Münze, wenn er
bereits eine andere trägt, setzt er seine Münze vor der anderen Münze ab, dreht sich um 180
Grad und fährt ohne Münze weiter. Treffen zwei Robuttons aufeinander, drehen sie sich beide
zuerst um 180 Grad, dann drehen sie sich aber beide unabhängig voneinander weiter um einen
zufälligen Winkel zwischen –90 und 90 Grad und setzen ihre Fahrt fort. Trifft ein Robutton
auf die Tischkante, wird er von ihr „reflektiert“.
_Aufgabe_
Simuliere und visualisiere diesen Prozess mit verschiedenen Anzahlen an Robuttons und
Münzen und mit Tischen von verschiedenen Größen und Formen. Suche dabei nach Werten
für diese Parameter, die den Prozess besonders interessant werden lassen. Kann man eine
allmähliche Veränderung der Situation beobachten?

Quelle: bwinf.de


----------

