Hamster Schleifen
Aus ProgrammingWiki
Wiki-Quelltext dieser Seite.
<language>Java</language>
Im Internet Explorer ist die Darstellung deutlich langsamer als im FireFox. Es wird deshalb der FireFox Browser für die Hamsterbeispiele empfohlen.
== Schleife in Java ==
Häufig benötigt man beim Programmieren eine mehrfache Ausführung eines Teilbereichs. <br>
Denkbar ist es, dass ein Programmierer dazu einfach Zeilen wiederholt.<br>
So lässt sich z.B. das kleine 1 x 1 von 3 wie folgt ausgeben:
<run id="4b03eaf9ee5f7">
System.out.println("3 x 1 = 3");
System.out.println("3 x 2 = 6");
System.out.println("3 x 3 = 9");
System.out.println("3 x 4 = 12");
System.out.println("3 x 5 = 15");
System.out.println("3 x 6 = 18");
System.out.println("3 x 7 = 21");
System.out.println("3 x 8 = 24");
System.out.println("3 x 9 = 27");
</run>
Eleganter ist da schon die Verwendung der WHILE-Schleife:
<run id="4b03eaf9eedf0">
int faktor = 1;
while ( faktor <= 9 ) {
System.out.println("3 x " + faktor + " = " + 3*faktor );
faktor++;
}
</run>
Für genau diesen Fall gibt es aber auch eine Schleife: die for-Schleife. Sie ist immer dann sinnvoll einsetzbar, wenn
* Eine bestimmte Anzahl von Wiederholungen durchgeführt werden soll
* Eine Variable von einem bestimmten Wert bis zu einem anderen gezählt werden soll
Das folgende Beispiel macht genau das selbe wie die while-Schleife im obigen Beispiel
<run id="4b03eaf9ef5dc">
for ( int faktor = 1; faktor <= 9; faktor ++ ) {
System.out.println("3 x " + faktor + " = " + 3*faktor );
}
</run>
;Weitere Beispiele
//allgemeiner Aufbau
for ( Zählvariable mit Anfangswert; Anfangswert; Bedingung; Schrittweite) {
// Anweisung, die wiederholt werden soll
}
// hochzählen in 1er-Schritten
for ( int zählvariable = Anfangswert; zählvariable <= Endwert; zählvariable++ ) {
// Anweisung, die wiederholt werden soll
}
// hochzählen in 5er-Schritten
for ( int zählvariable = Anfangswert; zählvariable <= Endwert; zählvariable+=5 ) {
// Anweisung, die wiederholt werden soll
}
// Countdown
for ( int zählvariable = Anfangswert; zählvariable > Endwert; zählvariable-- ) {
// Anweisung, die wiederholt werden soll
}
== Schleifen im Java Hamster Modell ==
<code id="4b03eaf9eda09" hidden>
int GridSize = 50;
public Object Hamster(Object Spielfeld) {
public int x;
public int y;
public int look = 0; // 0 up, 1 right, 2 down, 3 left
int speed = 50;
Object Feld= Spielfeld;
int inMouth = 0;
void wait() {
if(speed < 1) speed = 1;
if(speed > 100) speed = 100;
Thread.sleep(1000-(speed-1)*10);
}
void vor() {
wait();
Feld.drawField(x,y);
if(look == 0)
if(y > 0) y--; else y = Feld.sizeY-1;
if(look == 1)
if(x < Feld.sizeX-1) x++; else x = 0;
if(look == 2)
if(y < Feld.sizeY-1) y++; else y = 0;
if(look == 3)
if(x > 0) x--; else x = Feld.sizeX-1;
draw();
}
void linksUm() {
wait();
if(look == 0) look = 3; else
if(look == 1) look = 0; else
if(look == 2) look = 1; else
if(look == 3) look = 2;
draw();
}
void nimm() {
wait();
if(Feld.map[x][y] > 0) {
Feld.map[x][y]--;
inMouth++;
draw();
}else alert("Kein Korn hier");
}
void gib() {
wait();
if(inMouth > 0){
Feld.map[x][y]++;
inMouth--;
draw();
}else alert("Kein Korn im Mund");
}
boolean vornFrei() {
if(look == 0)
if(y > 0) return Feld.map[x][y-1] != -1;
if(look == 1)
if(x < Feld.sizeX-1) return Feld.map[x+1][y] != -1;
if(look == 2)
if(y < Feld.sizeY-1) return Feld.map[x][y+1] != -1;
if(look == 3)
if(x > 0) return Feld.map[x-1][y] != -1;
return false;
}
boolean kornDa() {
return Feld.map[x][y] > 0;
}
boolean maulLeer() {
return inMouth == 0;
}
void draw(){
Feld.drawField(x,y);
canvas.drawImage(x*GridSize,y*GridSize,GridSize,GridSize,"http://michael-hielscher.de/hamster/hamster"+look+".png");
}
return this;
}
public Object Spielbrett() {
public int sizeX = 10;
public int sizeY = 8;
public int[][] map= new int[sizeX][sizeY];
void initMap(){
canvas.clear();
for(int y=0; y < sizeY; y++)
for(int x=0; x < sizeX; x++)
if(x==0 ||y == 0||x == sizeX-1|| y == sizeY-1) map[x][y] = -1;
drawMap();
}
void placeWall(int x, int y){
if(x>=0 &&y >= 0&&x < sizeX && y < sizeY) { map[x][y] = -1; drawField(x,y); }
}
void clearWall(int x, int y){
if(x>=0 &&y >= 0&&x < sizeX && y < sizeY) { map[x][y] = 0; drawField(x,y); }
}
void drawMap(){
for(int y=0; y < sizeY; y++)
for(int x=0; x < sizeX; x++)
drawField(x,y);
}
void drawField(int x, int y) {
canvas.setColor(255,255,255);
canvas.fillRect(x*GridSize,y*GridSize,GridSize,GridSize);
canvas.setColor(0,0,0);
canvas.rect(x*GridSize,y*GridSize,GridSize-1,GridSize-1);
if(map[x][y] == -1) {
canvas.drawImage(x*GridSize,y*GridSize,GridSize,GridSize,"http://michael-hielscher.de/hamster/brick_wall.png");
}
if(map[x][y] > 0) {
int image = map[x][y];
if(image > 9) image = 9;
canvas.drawImage(x*GridSize,y*GridSize,GridSize,GridSize,"http://michael-hielscher.de/hamster/grain"+image+".png");
}
}
void putGrain(int x, int y,int count) {
map[x][y] = count;
drawField(x,y);
}
return this;
}
Object Spielfeld = Spielbrett();
Object Paul = Hamster(Spielfeld);
void vor() {Paul.vor();}
void linksUm() {Paul.linksUm();}
void nimm() {Paul.nimm();}
void gib() {Paul.gib();}
boolean vornFrei() {return Paul.vornFrei();}
boolean kornDa() {return Paul.kornDa();}
boolean maulLeer() {return Paul.maulLeer();}
//////// Setup Map /////////
Spielfeld.initMap();
Spielfeld.placeWall(2,5);
Spielfeld.placeWall(7,5);
Paul.x = 5;
Paul.y = 5;
Paul.look = 3;
Paul.draw();
Paul.speed = 60; // 1 slow - 100 fast
Spielfeld.putGrain(2,1,4);
Spielfeld.putGrain(5,2,3);
</code>
<canvas w=500 h=400>
</canvas>
Unsere erste Aufgabe soll es sein, den Hamster solange nach vorn zu bewegen bis eine Wand vor ihm steht. Klicke einmal auf "Ausführen", um die Startaufstellung zu sehen. Wir können dies wieder ganz einfach mit IF Anweisungen aufschreiben:
<run id="4b03eaf9efd4c">
if( vornFrei() ) // wir prüfen ob vor uns frei ist (keine Wand)
vor(); // wenn ja dann eins nach vorn laufen.
if( vornFrei() )
vor();
if( vornFrei() )
vor();
</run>
Wie wir an diesem Beispiel sehen können, läuft der Hamster bis zur Wand und hält an wie er es soll. Wenn der Hamster aber zu Beginn nach Norden geschaut hätte, würde er nich ganz bis zur Wand laufen, da wir maximal 3 Felder nach vorn rücken mit unserem Programm. Wir könnten nun einfach noch 2 IF Bedingungen unten anfügen, damit unser Programm auch nach Norden funktioniert, aber was wenn wir die Spielfeldgröße gar nicht genau kennen?
Auch hier kann man Schleifen sinnvoll einsetzen. Wollen wir etwa, dass der Hamster solange nach vorn läuft bist eine Wand kommt, können wir dies am besten mit einer WHILE Schleife erledigen:
<run id="4b03eaf9f052d">
while ( vornFrei() ) // wir prüfen ob vor uns frei ist (keine Wand)
{
vor(); // wenn ja laufen wir eins nach vorn
}
for(int i=0; i < 3; i++) linksUm(); // wir drehen uns 3 mal
while ( vornFrei() ) // wir prüfen wieder ob vor uns frei ist (keine Wand)
{
vor(); // wenn ja laufen wir eins nach vorn
}
</run>
Nun kann man auch Schleifen in Schleifen verschachteln. Etwa soll der Hamster nun solange herumlaufen bis endlich unter ihm ein Korn liegt:
<run id="4b03efafb42f7">
while(kornDa() == false){
while ( vornFrei() ) // wir prüfen ob vor uns frei ist (keine Wand)
{
vor(); // wenn ja laufen wir eins nach vorn
if(kornDa()) break; // wenn jetzt da ein Korn liegt brechen wir die Schleife ab
}
linksUm(); // wir drehen uns 3 mal
}
</run>