Ab in die Ecke mit dem Huhn, in Einzelschritten

thoff430

Mitglied
(Der andere Thread lässt sich leider nicht mehr editieren, deswegen hier ein Update)

edit: Sorry, ich hab hier vorhin Mist gebaut und Sachen falsch kopiert. Schon spät... Ist jetzt korrigiert!

Hallo miteinander,

ich wollte schon eine geraume Zeit mit dem Programmieren beginnen...und jetzt habe ich endlich einen Java-Kurs an meiner Uni. Wir arbeiten mit GreenFoot, hab selbst aber auch schon ein wenig Erfahrung im Umgang mit Eclipse gesammelt. Stehe trotzdem noch ziemlich am Anfang... und habe folgendes Problem:



Das Huhn soll in die obere rechte Ecke laufen, Schritt für Schritt, falls es da nicht bereits ist.
Ich denke der Hund liegt in Zeile 45 bei der Subklasse Barnfield begraben. Die Methode move() wird nur einmal ausgeführt. Ich möchte sie aber ausführen, solange es noch geht (canMove() also 'true' liefert). Ersetze ich if durch while, komme ich ohne Probleme in die Ecke, allerdings in einem einzigen Schritt. Wie krieg ich das Huhn nun dazu, Schritt für Schritt bis zum Rand zu gehen? (Meine Aufgabe ist es, eine Methode goToURCorner() zu entwerfen, die genau das macht.) So wie es da steht läuft das Huhn diagonal nach oben. WalkToBorder() macht nicht das, was es sollte...sondern entspricht nur einem einzelnen move().

Klasse Chicken (vorgegeben, von mir nicht bearbeitet):
Java:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Chicken here.
 * 
 * @author Sjaak Smetsers
 * @version Version 1.0 -- 1-11-2011
 */
public class Chicken  extends Actor
{
    public static final int EAST  = 0, WEST  = 1, NORTH = 2, SOUTH = 3;

    public int direction;
    private GreenfootImage chickenRight, chickenLeft;

    
    public Chicken () {
        chickenLeft = getImage();
        chickenRight  = new GreenfootImage(chickenLeft);
        chickenRight.mirrorHorizontally();
        setDirection(WEST);
    }


    /**
     * Check whether there is an egg in the same cell as we are.
     */
    public boolean foundEgg() {
        return getOneObjectAtOffset(0, 0, Egg.class) != null;
    }
    
     /**
     * Check whether there is a fence ahead of us.
     */
    public boolean fenceAhead() {
        Actor may_be_fence = null;
        if (direction == SOUTH) {
             may_be_fence =  getOneObjectAtOffset(0, 1, Fence.class);
        } else if (direction == EAST) {
             may_be_fence =  getOneObjectAtOffset(1,0, Fence.class);
        } else if (direction == NORTH) {
             may_be_fence =  getOneObjectAtOffset(0,-1, Fence.class);
        } else /* direction should be WEST here */{
             may_be_fence =  getOneObjectAtOffset(-1,0, Fence.class);
        }
        if (may_be_fence == null) {
            return false;
        }
        else {
            return true;
        }
    
    }
        
    public void layEgg() {
        getWorld().addObject(new Egg (), getX (), getY ());
    }
    
    public Egg takeEgg() {
        Actor egg_actor = getOneObjectAtOffset(0, 0, Egg.class);
        if (egg_actor != null) {
            return (Egg) egg_actor;
        } else {
            ShowError ("There was no egg in this cell");
            return null;
        }
    }

     public boolean facingNorth () {
        return direction == NORTH;
     }
    
     
    /**
     * Move one cell forward in the current direction.
     */

    public void move()
    {
        if (! borderAhead()) {
            if (! fenceAhead ()) {
                if (direction == SOUTH) {
                    setLocation(getX(), getY() + 1);
                } else if (direction == EAST) {
                    setLocation(getX() + 1, getY());
                } else if (direction == NORTH) {
                    setLocation(getX(), getY() - 1);
                } else /* direction should be WEST here */{
                    setLocation(getX() - 1, getY());
                }
            } else {
                ShowError ("A fence was blocking the way");
            }
        } else {
            ShowError ("End of the world reached");
        }
    }

    /**
     * Test if we can move forward. Return true if we can, false otherwise.
     */
    public boolean canMove()
    {
        if (fenceAhead () || borderAhead ()) {
            return false;
        } else {
            return true;
        }
    }
    
    /**
     * Test is a cell ahead of us.
     */
    public boolean borderAhead () {
        if (direction == SOUTH) {
             return getY() == getWorld().getHeight() - 1;
        } else if (direction == EAST) {
             return getX() == getWorld().getWidth()  - 1;
        } else if (direction == NORTH) {
             return getY() == 0;
        } else /* direction should be WEST here */{
             return getX() == 0;
        }
    }

    /**
     * Turns towards the left.
     */
    public void turnLeft() {
        if (direction == SOUTH) {
             setDirection(EAST);
        } else if (direction == EAST) {
             setDirection(NORTH);
        } else if (direction == NORTH) {
             setDirection(WEST);
        } else /* direction should be WEST here */{
             setDirection(SOUTH);
        }
    }

    /**
     * Sets the direction we're facing.
     */
    public void setDirection(int direction){
        direction = direction % 4;
        if (this.direction != direction) {
            this.direction = direction;
            if (direction == SOUTH) {
                setImage(chickenRight);
                setRotation(90);
            } else if (direction == EAST) {
                setImage(chickenRight);
                setRotation(0);
            } else if (direction == NORTH) {
                setImage(chickenLeft);
                setRotation(90);
            } else /* direction should be WEST here */{
                setImage(chickenLeft);
                setRotation(0);
            }
        }
    }
    
    public static int randomDirection () {
        return Greenfoot.getRandomNumber (4);
    }
    
    private void ShowError (String err_msg) {
        World my_world = getWorld();
        my_world.addObject (new Alert (err_msg),my_world.getWidth()/2, my_world.getHeight()/2);
        Greenfoot.stop();
    }

}



Subklasse Barnfield (bis einschließlich goToURCorner() mein Werk, Rest vorgegeben.):
Java:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Fryde here.
 * 
 * @author Sjaak Smetsers
 * @version 26-03-2011
 */
public class Barnfield  extends Chicken
{
    private int eggsHatched;    

    /**
     * Act - do whatever the Fryde wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() { // declares method void act()
         goToURCorner();
    }

    /**
     * Tells Fryde if the northern border is already reached
     */
    public boolean reachedNBorder(){
        while (getY() != 0) {
            return false;
        }
        return true;
    }

    /**
     * Tells Fryde if the eastern border is already reached
     */
    public boolean reachedEBorder(){
        while (getX() != 7) {
            return false;
        }
        return true;
    }
    
    /**
    * These chicken feet are made for walking
    */
    public void walkToBorder() {
        do {
            move();
        }
        while (canMove());
    }

    /**
     * Lets Fryde walk to the 
     * upper right corner
     */
    public void goToURCorner() {
        if (! (reachedNBorder() || reachedEBorder())) {
            switch (direction) {
                case EAST:
                    turnLeft();
                    walkToBorder();
                    turnRight();
                    walkToBorder();
                    break;
                case SOUTH:
                    turn();
                    walkToBorder();
                    turnRight();
                    walkToBorder();
                    break;
                case WEST:
                    turnRight();
                    walkToBorder();
                    turnRight();
                    walkToBorder();
                    break;
                default:
                walkToBorder();  
            } 
        }
    }

    /**
     * Hatch an egg.
     */
    public void hatchEgg () {
        Egg egg_found = takeEgg ();
        getWorld().removeObject(egg_found);
        eggsHatched++;
    }

    /**
     * To make a 180 degree turn
     */
    public void turn () {
        turnLeft ();
        turnLeft ();
    }

    /**
     * Turns towards the right.
     */
    public void turnRight() {
        turnLeft ();
        turnLeft ();        
        turnLeft ();
    }

    /**
     * Make a step backwards
     */
    public void moveBackwards () {
        turn ();
        move ();
        turn ();
    }

    public boolean eggAhead () {
        if (canMove ()) {
            move ();
            if (foundEgg ()) {   // found an egg, have to go back
                moveBackwards ();
                return true;
            }
            else {   // there was no egg
                moveBackwards ();
                return false;
            }
        }
        else
            return false;
    }

    private void moveAndMark () {
        dropPebble ();
        move ();
    }

    private void dropPebble () {
        getWorld().addObject (new Pebble (), getX (), getY ());
    }

}
 
Zuletzt bearbeitet:

thoff430

Mitglied
So ein Mist, ich hab doch tatsächlich oben erst ne ganze Menge durcheinander geworfen. Also nochmal:

Bezogen auf Zeile 45 in Barnfield:
Hau ich dort "if" rein wird die Methode move() wird nur einmal ausgeführt. Ich möchte sie aber ausführen, solange es noch geht (canMove() also 'true' liefert). Ersetze ich if durch (do)while, springt das Huhn sofort in die Ecke. Ähnliches bei for-Schleifen.
 
S

Spacerat

Gast
Tja... wärst du mal beim einfacheren ersten Thread geblieben... ;) Meine dortige [c]goUpperRight()[/c]-Methode sollte zumindest soweit funktionieren *), hättest du nur noch ein wenig umstricken - halt Javacode draus und GreenFoot-Konform machen - müssen. Letzten Endes hast dort eigentlich nur ein boolean vergessen, welcher das Huhn davon abhält, sich dauernd zu drehen, wenn es im Norden angekommen ist.

*) Bis auf einen fatalen Fehler, dessen Änderung ich bereits beantragt habe. [c]else if(!turned)...[/c] gehört eine Abfrage weiter nach aussen... :oops:
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Java Themen

Neue Themen


Oben