2

これはマルチパートの質問です。

制限:

  • .clone()、 またはCollections、またはは使用できませんSystem
  • 別のオブジェクト タイプに変更することはできません (つまり、ArrayListを aListまたはその他に変更することはできません)。

私の問題は、例外をスローする方法を正確に把握していないことにあると思います。よくわかりません。

これは、私が立ち往生している課題の一部です。

可能であれば、魚 f を魚リストに追加します。

最初に、魚のいる場所の風景が ROCK と等しいかどうかを確認します。そうである場合、その魚はリストに追加されません。代わりに、IllegalFishPositionException をスロー IllegalFishPositionException.FISH_OVER_ROCKして、コンストラクターに渡します。

次に、パラメータと同じ場所にある別の魚 (パラメータとは異なる) をチェックします。見つかった場合、その魚はリストに追加されません。代わりに IllegalFishPositionException をスローIllegalFishPositionException.TWO_FISH_IN_ONE_PLACEし、コンストラクターに渡します。

それ以外の場合は、パラメーターをフィッシュ リストに追加します。

public void addFish(Fish f) {
    ArrayList <Fish> addFish = new ArrayList <Fish>( fish );

    if ( landscape[ f.getRow() ][ f.getCol() ] == ROCK ) {
        throw new IllegalFishPositionException(
                IllegalFishPositionException.FISH_OVER_ROCK );
    }
    for ( Fish f1 : addFish ) {
        if ( ( f1.getRow() == f.getRow() && 
                f1.getCol() == f.getCol() ) || f1 == f ) {
            throw new IllegalFishPositionException(
                    IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE );
        }
    }
    for ( Fish f2 : addFish ) {
        if ( ( f2.getRow() != f.getRow() && 
                f2.getCol() != f.getCol() ) && 
                landscape[ f.getRow() ][ f.getCol() ] != ROCK ) {
            fish.add( f );
        }
    }

}

そして、これが私には論理的だと思われる2番目の方法ですが、テストでは失敗しています。

/* Checks the specified location to see if it has a rock, fish, or plant 
 * in it. If so, returns false; if it is just water, returns true. */
public boolean isSpaceAvailable(int r, int c) {
    if ( landscape[r][c] == ROCK ) {
        return false;
    }
    for ( Fish f : fish ) {
        if ( ( f.getRow() == r ) && ( f.getCol() == c ) ) {
            return false;
        }
    }
    for ( Plant p : plants ) {
        if ( ( p.getRow() == r ) && ( p.getCol() == c ) ) {
            return false;
        }
    }
    return true;
}

addFish に依存するメソッドが他にもいくつかあるので、それを正しく行うことができれば、カスケード効果が得られます。

isSpaceAvailable メソッドに渡す必要がある JUnit テストは次のとおりです。

@Test
public void testIsSpaceAvailable() {
    Model m = new Model(10,10,0,0,0);
    Fish f = new Fish(1, 7, 100, Fish.UP);
    Plant p = new Plant(2, 8, 100);
    m.addFish(f);
    m.addPlant(p);
    assertFalse(m.isSpaceAvailable(1, 7));
    assertFalse(m.isSpaceAvailable(2, 8));
    assertFalse(m.isSpaceAvailable(0, 0));
    for (int i = 1; i < 9; i++) {
        for (int j = 1; j < 9; j++) {
            if ((i != 1 || j != 7) && (i != 2  || j != 8)) {
                assertTrue(m.isSpaceAvailable(i, j));
            }
        }
    }
}

プロジェクトの JavaDoc を参照してください。 http://www.cs.umd.edu/class/spring2013/cmsc131-23/Projects/P7/doc/index.html

私はしばらくこれを見つめていましたが、完全に立ち往生しています。

4

2 に答える 2

0

addFish悪い状態です。local を削除しArrayListます。スレッドの安全性/同時実行性が心配な場合は、ロック戦略を使用するか、メソッドを同期してください。最後のループは間違っていて冗長です。ヒットするまでに、魚を追加するための条件を満たしています。植物がある場所に魚を追加できますか?

public void addFish(Fish f) {

    if ( landscape[ f.getRow() ][ f.getCol() ] == ROCK ) {
        throw new IllegalFishPositionException(
                IllegalFishPositionException.FISH_OVER_ROCK );
    }

    for ( Fish f1 : this.fish ) {
        // is Fish.equals implemented if so use that.
        if ( f1 == f){

           // fish already in list nothing to do
           // usually bad practice to have return in middle of method
           return; 

        } else if ( ( f1.getRow() == f.getRow() && 
                f1.getCol() == f.getCol() )) {
            throw new IllegalFishPositionException(
                    IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE );
        }
    }

   fish.add( f );

}
于 2013-05-10T01:55:44.727 に答える
0

に冗長な 2 番目のループがaddFish()あり、開始する魚がない場合は魚を複数回追加するか、まったく追加しません。

違う:

for ( Fish f2 : addFish ) {
    if ( ( f2.getRow() != f.getRow() && 
            f2.getCol() != f.getCol() ) && 
            landscape[ f.getRow() ][ f.getCol() ] != ROCK ) {
        fish.add( f );    // adds F repeatedly!
    }
}

正しいコード:

public void addFish (Fish f) {
    // we don't need to copy the 'fish' list -- but if we did, we'd call it 'copyFish' not 'addFish'.
    /* List<Fish> copyFish = new ArrayList<Fish>( fish); */

    if (landscape[ f.getRow()][ f.getCol()] == ROCK) {
        throw new IllegalFishPositionException( IllegalFishPositionException.FISH_OVER_ROCK);
    }
    for (Fish exist : fish) {
        if ((exist.getRow() == f.getRow() && exist.getCol() == f.getCol()) {
            throw new IllegalFishPositionException(
                    IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE);
        }
    }
    // All OK;     clear water, no rock or other fish there.
    //    -- add the fish.
    fish.add( f);
    landscape[ f.getRow()][ f.getCol()] = FISH;
}

また、コードをクリーンアップします。コンパクトで、読みやすく、読みやすいものにします。

意味のある簡潔なコードを書く必要があります。意味のない長い口頭や空白を埋めるマングリングではありません。

私の個人的なやり方は、list/set/map/collection フィールド (パラメーターではない) の末尾に 'List' などを付けることです (例: 'fishList')。これにより、一般的なユースケースであるパラメーターとして渡されるリストと区別されます。

于 2013-05-10T01:59:36.260 に答える