0

Gridworld を使用して、Eclipse でチェッカー ゲームを作成する作業を行っています。これまでのところ、私は赤い部分だけを修正しています。私の目標は、ピースを move() して、ジャンプするかステップするかを選択できるようにすることです。明らかに、ジャンプ (つまり、ピースが反対の色のピースの上を移動し、グリッドからそのピースを削除する場合) はステップよりも優先されます。私の問題は、最初の 2 列または最後の 2 列にあるピースを移動しようとするたびに、Illegal Out of Bounds エラーが発生することです。誰でもこれを解決するのを手伝ってもらえますか? よろしくお願いします。

import java.awt.Color;
import info.gridworld.actor.Actor;
import info.gridworld.actor.Bug;
import info.gridworld.actor.Critter;
import info.gridworld.actor.Flower;
import info.gridworld.grid.Grid;
import info.gridworld.grid.Location;

public class RedPieces extends Bug {
boolean jumped;

public RedPieces() {
    setColor(Color.red);
    setDirection(180);
    jumped = false;
}

public boolean canMove() {
    Grid<Actor> gr = getGrid();
    if (gr == null)
        return false;
    Location loc1 = getLocation();
    if (getGrid().get(new Location(loc1.getRow() + 1, loc1.getCol() - 1)) == null || 
        getGrid().get(new Location(loc1.getRow() + 1, loc1.getCol() - 1)).getColor() == Color.black || 
        getGrid().get(new Location(loc1.getRow() + 1, loc1.getCol() + 1)) == null || 
        getGrid().get(new Location(loc1.getRow() + 1, loc1.getCol() + 1)).getColor() == Color.black) {
        return true;
    }
    return false;
}

public boolean jump2(Location loc){
    Grid<Actor> gr = getGrid();
    if (gr == null)
        return false;
    Location jump1 = new Location(loc.getRow() + 2, loc.getCol() - 2);
    Location jump2 = new Location(loc.getRow() + 2, loc.getCol() + 2);

    if( (gr.isValid(jump1)) && 
        (gr.get(jump1) == null) && 
        (gr.get(jump2) == null) && 
        (gr.get(new Location(loc.getRow() + 1, loc.getCol() -1)) instanceof BlackPieces) && 
        ((gr.get(new Location(loc.getRow() + 1, loc.getCol() + 1)) == null) || 
         (gr.get(new Location(loc.getRow() + 1, loc.getCol() + 1))) instanceof RedPieces))
    {
        gr.get(new Location(loc.getRow() + 1, loc.getCol() -1)).removeSelfFromGrid();
        moveTo(jump1);
        return true;
    }
    else if( (gr.isValid(jump2)) && 
             (gr.get(jump2) == null) && 
             (gr.get(jump1) == null) && 
             (gr.get(new Location(loc.getRow() + 1, loc.getCol() +1)) instanceof BlackPieces) && 
             ((gr.get(new Location(loc.getRow() +1, loc.getCol() - 1)) == null) || 
              (gr.get(new Location(loc.getRow() + 1, loc.getCol() -1)) instanceof RedPieces)))
    {
        gr.get(new Location(loc.getRow() + 1, loc.getCol() +1)).removeSelfFromGrid();
        moveTo(jump2);
        return true;
    }
    else if((gr.isValid(jump1) && gr.get(jump1) == null) && 
            (gr.isValid(jump2) && gr.get(jump2) != null))
    {
        if(gr.get(new Location(loc.getRow() + 1, loc.getCol() -1)) instanceof BlackPieces)
        {
            gr.get(new Location(loc.getRow() + 1, loc.getCol() -1)).removeSelfFromGrid();
            moveTo(jump1);
            return true;
        }
    }
    else if((gr.isValid(jump2) && gr.get(jump2) == null) && 
            (gr.isValid(jump1) && gr.get(jump1) != null))
    {
        if(gr.get(new Location(loc.getRow() + 1, loc.getCol() +1)) instanceof BlackPieces)
        {
            gr.get(new Location(loc.getRow() + 1, loc.getCol() +1)).removeSelfFromGrid();
            moveTo(jump2);
            return true;
        }
    }

    return false;
}

public void move() {
    Grid<Actor> gr = getGrid();
    if (gr == null)
        return;

    Location loc = getLocation();
    Location next1 = new Location(loc.getRow() + 1, loc.getCol() - 1);
    Location next2 = new Location(loc.getRow() + 1, loc.getCol() + 1);
    if (jump2(loc) == false) {
        if (gr.isValid(next2) && gr.get(next2) == null && 
            gr.isValid(next1) && gr.get(next1) != null)
        {
            moveTo(next2);
        }
        else if (gr.isValid(next1) && gr.get(next1) == null && 
                 gr.isValid(next1) && gr.get(next2) != null)
        {
            moveTo(next1);
        }
        else if (gr.isValid(next1) && gr.get(next1) == null && 
                 gr.isValid(next2) && gr.get(next2) == null)
        {
            moveTo(randomLoc(next1, next2));
        }
        else
            return;
    }
}

public static Location randomLoc(Location loc1, Location loc2) {
    double num = Math.random();
    if (num < 0.5)
        return loc1;
    else
        return loc2;
}

public void act() {
    if(canMove()) move();
}
}
4

1 に答える 1

1

読みやすくするためにコードを再フォーマットする必要がありました。そうすることで、いくつかの潜在的なバグを発見しました。

  • このjump2()メソッドでは、2 番目のifステートメントは の有効性をチェックしませんjump2。そのステートメントのgr.get(jump2 == null)条件での例外の原因である可能性があります。if

  • 後続のelse ifステートメントにも同じロジックが適用されます。今回は、 の有効性をチェックしていませんjump1

  • メソッドのmove()最初のでは、バグのように見える 2 回else ifの有効性のみをチェックします。next1質問の再フォーマットされたコードで見つけてください。

if全体として、条件をできるだけ単純な(読みやすい)ように変更する必要があると思います。再フォーマットも役立ちます。

[追加] 2 つの小さなこと。

  • canMove()メソッドでは、最初のステートメントでのみ使用しgrますif。2 番目のステートメントのgetGrid()代わりに使用しています。grif

  • ステートメントnew Locationでグリッドを取得するたびに行うことを避けることはできませんか? if有効性を確認せずにそれらのグリッドを使用しています。それらが有効であると確信していますか? メソッドの最初にそれらを作成し、それらの有効性をチェックして、ifステートメントで使用することができます。ifステートメントの読みやすさにも役立つ場合があります。

【追加】jump2()メソッド簡略化サンプル

次のコードは、列の反対側 (無効、null、または赤い部分) を無視します。片面が黒駒を飛び越えるのに有効な場合、他の面の状態は問題にならないというのが私の仮定です。

public boolean jump2(Location loc){
    Grid<Actor> gr = getGrid();
    if (gr == null)
        return false;

    Location jump1 = new Location(loc.getRow() + 2, loc.getCol() - 2);
    Location jump2 = new Location(loc.getRow() + 2, loc.getCol() + 2);
    Location adjacent1 = new Location(loc.getRow() + 1, loc.getCol() - 1);
    Location adjacent2 = new Location(loc.getRow() + 1, loc.getCol() + 1);

    // try one column
    if( gr.isValid(jump1))
    {
        if( (gr.get(jump1) == null) && 
            (gr.get(adjacent1) instanceof BlackPieces))
        {
            gr.get(adjacent1).removeSelfFromGrid();
            moveTo(jump1);
            return true;
        }
    }

    // try the other column
    if( gr.isValid(jump2))
    {
        if( (gr.get(jump2) == null) && 
             (gr.get(adjacent2) instanceof BlackPieces))
        {
            gr.get(adjacent2).removeSelfFromGrid();
            moveTo(jump2);
            return true;
        }
    }

    return false;
}
于 2014-05-25T23:21:26.207 に答える