鱼池模拟:家庭作业,我哪里错了?

时间:2013-05-10 01:30:44

标签: java

这是一个多部分问题。

限制:

  • 无法使用.clone()CollectionsSystem
  • 无法更改为其他对象类型(我的意思是我无法将ArrayList更改为List或不更改。

我认为我的问题可能是我没有完全掌握如何抛出异常。 但不确定。

这是我坚持的作业的一部分。

  

如果可能的话,将鱼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 );
        }
    }

}

这是第二种对我而言合乎逻辑的方法,但在测试中失败了。

/* 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

我已经盯着这一段时间而且我一直都陷入困境。

2 个答案:

答案 0 :(得分:0)

addFish状态不佳。删除本地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 );

}

答案 1 :(得分:0)

addFish()中有一个冗余的第二个循环,如果没有鱼可以开始,它会多次添加鱼,或者永远不会添加鱼。

WRONG:

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'或其他内容来后缀list / set / map / collection字段(不是参数),例如'fishList'。这将它们与作为参数传递的列表区分开来,这是一个常见的用例。