5

ラングトンアリの問題は単純です。アリが白と黒の四角形のボードを歩きます。

  • 白い四角で、右に 90 度回転し、四角の色を反転し、1 単位前に進みます
  • 黒い四角で、左に 90 度回転し、四角の色を反転し、1 単位前に進みます

「ゲーム」が始まると盤面は真っ白。

私はシミュレーションを実装しましたが、改善の助けが必要な歩行と回転の非常に醜い解決策があります。現在の歩き方は以下の通りです。

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

そして、方向を変える関数:

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";
    }
}

文字列の代わりに int を使用することを考えましたが、どのようにすればよいかよくわかりません。ヘルプやヒントをいただければ幸いです。


編集:今、私はいくつかを変更しました。変数を持つ Ant クラスを作成しました

int x, int y, Direction dir

そして、次の方法で実行します。

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);
    }
}

そして私の最初の列挙型:

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];
    }
}
4

7 に答える 7

3

Java でを使用==して s を比較すると、期待する結果が得られません。代わりStringにメソッドを使用してください。equals

、、、およびの列挙型を定義することを検討します。NORTHSOUTHEASTWEST

于 2013-07-23T17:19:53.160 に答える
2

各方向にintを割り当てます(時計回りに進みます):

NORTH = 0;
EAST = 1;
SOUTH = 2;
WEST = 3;

左に -1 を割り当てます。1として右:

LEFT = -1;
RIGHT = 1;

次に、方向を変更する簡単な関数を作成できます。

private void turn(int leftOrRight){
    dir = (dir + leftOrRight) % 4;
}

enumsこれは、何らかの理由でを使用したくないことを前提としています。

于 2013-07-23T17:25:57.913 に答える
1

、などの文字列リテラルの代わりに列挙型を使用することを検討してください。NORTHSOUTH

列挙型はタイプ セーフであるため、誤っSUOTHSOUTH. さらに、enumインスタンスは安全に比較できます==(シリアライゼーションを含むいくつかの奇妙なエッジ ケースを除いて)。==文字列を現在ではなく比較している方法は、どこから来equalsたのかによって、潜在的な問題を引き起こす可能性があります。文字列に対するvsの説明については、この回答をご覧ください。dirleftOrRight==equals

文字列、列挙型、および int はすべてswitchコンストラクトでサポートされているため、if/else ブランチの代わりにそれを使用して、コードを少しきれいにすることも検討できます。

于 2013-07-23T17:19:04.727 に答える
0

ビットマスキングを使用することで、ここでエレガントなソリューションが得られるように感じます。そうすれば、代わりに単純なビット操作ですべてのターン操作を実行できます。ここにビットマスクの使用に関する非常に優れたチュートリアルがあります: http://www.vipan.com/htdocs/bitwisehelp.html

たとえば、方向を 4 ビットの数値で表し、回転を単純なブール値で表す場合、これをすべて 1 つの if/else ステートメントで行うことができます。

if (leftOrRight == 0){
    //right shift one bit
}
else if (leftOrRight == 1){
    //left shift one bit
}

別の方法として、左/右のインジケーターを 1 または -1 にして、ターンごとに左にシフトすることもできます。

于 2013-07-23T17:19:30.057 に答える
0

私は列挙型を使用します。そのような:

enum Directions {
    NORTH, 
    SOUTH, 
    EAST, 
    WEST
}

Java 6 を使用する場合は、それでスイッチを使用することもできます。

ああ、また、 とは決して比較Stringしないでください==。を使用しequalsます。理由はこちらをご覧ください。

于 2013-07-23T17:19:38.377 に答える