Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Langton's Ant Algorithm

Tags:

java

The problem of Langton's Ant is simple. An ant walks a board with white and black squares.

  • At a white square, turn 90° right, flip the color of the square, move forward one unit
  • At a black square, turn 90° left, flip the color of the square, move forward one unit

When the "game" starts the board is all white.

I have implemented the simulation but has a really ugly solution for walkning and turning that I need help improving. Right now the walk is as follows:

if (dir == "NORTH") {
    // Walk up
} else if (dir == "EAST") {
    // Walk right
} else if (dir == "SOUTH") {
    // Walk down
} else if (dir == "WEST") {
    // Walk left
}           

And the function for changing direction:

private void turn(String leftOrRight){
    if(dir == "NORTH" && lor == "RIGHT" ){
        dir = "EAST";
    } else if (dir == "NORTH" && leftOrRight == "LEFT" ){
        dir = "WEST";
    } else if (dir == "EAST" && leftOrRight == "RIGHT" ){
        dir = "SOUTH";
    } else if (dir == "EAST" && leftOrRight == "LEFT" ){
        dir = "NORTH";
    } else if (dir == "SOUTH" && leftOrRight == "RIGHT" ){
        dir = "WEST";
    } else if (dir == "SOUTH" && leftOrRight == "LEFT" ){
        dir = "EAST";
    } else if (dir == "WEST" && leftOrRight == "RIGHT" ){
        dir = "NORTH";
    } else if (dir == "WEST" && leftOrRight == "LEFT" ){
        dir = "SOUTH";
    }
}

I have thought about using ints instead of strings, but not quite sure how i should do it. Any help or hints is appreciated.


EDIT: Now I have changed some. I Created an Ant class that has variables

int x, int y, Direction dir

And run it with the following method:

private void runAnt(Ant ant) {
    int x = ant.getX();
    int y = ant.getY();

    // Check rule 1
    if (matrix[x][y] == true) {
        matrix[x][y] = false;
        w.setDot(x, y, Color.WHITE);
        ant.setDirection(ant.getDirection().right());

    // Check rule 2
    } else if (matrix[x][y] == false) {
        matrix[x][y] = true;
        w.setDot(x, y, Color.BLACK);
        ant.setDirection(ant.getDirection().left());
    }

    // Moves one unit forward according to direction.
    if (ant.getDirection().equals(Direction.N)) {
        ant.setY((ant.getY() - 1 + wSize) % wSize);

    } else if (ant.getDirection().equals(Direction.E)) {
        ant.setX((ant.getX() + 1) % wSize);

    } else if (ant.getDirection().equals(Direction.S)) {
        ant.setY((ant.getY() + 1) % wSize);

    } else if (ant.getDirection().equals(Direction.W)) {
        ant.setX((ant.getX() - 1 + wSize) % wSize);
    }
}

And my very first enum:

public static enum Direction {
    N, E, S, W;
    private static Direction[] vals = values();

    public Direction right() {
        return vals[(this.ordinal() + 1) % vals.length];
    }

    public Direction left() {
        return vals[(this.ordinal() + vals.length - 1) % vals.length];
    }
}
like image 611
Goatcat Avatar asked Jul 23 '13 17:07

Goatcat


1 Answers

Combine using an enum with next() and prev() functions as explained in this answer. Then a right turn is just a next() call and a left turn is a prev() call.

like image 159
Jim Garrison Avatar answered Nov 02 '22 11:11

Jim Garrison