战列舰船不能放在边缘

时间:2013-06-11 15:20:14

标签: java android

再次是我。我正在尝试制作一个非常简单的战舰游戏。 现在我想让船只与至少一个空闲单元分开。看图片

enter image description here

如您所见,边缘完全无船只,这使得可用的放置次数要小得多(或者更少?对不起我的英语不好)。

“Field”只是一个int [10] [10]数组。

我有一种非常粗鲁的方法来检查船只的可用性: (IS_WATER const = 0)

private static boolean checkIfShipAvailable(int x, int y, int dir, int length) {
         int counter = 0;
        switch(dir) {
        case DIRECTION_RIGHT:
            try {
                if(field[x-1][y] == IS_WATER) counter++;     
                if(field[x-1][y-1] == IS_WATER) counter++;    
                if(field[x-1][y+1] == IS_WATER) counter++;    
                if(field[x][y-1] == IS_WATER) counter++;      
                if(field[x][y+1] == IS_WATER) counter++;     
                if(field[x+1][y-1] == IS_WATER) counter++;    
                if(field[x+1][y+1] == IS_WATER) counter++;    

                if(field[x+length-1][y-1] == IS_WATER) counter++;
                if(field[x+length-1][y+1] == IS_WATER) counter++;
                if(field[x+length][y] == IS_WATER) counter++;
                if(field[x+length][y-1] == IS_WATER) counter++;
                if(field[x+length][y+1] == IS_WATER) counter++;

            } catch (IndexOutOfBoundsException e) {
                counter++;
            }
            Log.d(TAG, "Direction: Right. Counter = " + counter);
            if (counter == 12)
                return true;
            break;

        case DIRECTION_DOWN:
            try {
                if(field[x-1][y-1] == IS_WATER) counter++ ;
                if(field[x][y-1] == IS_WATER) counter++ ;
                if(field[x+1][y-1] == IS_WATER) counter++ ;
                if(field[x-1][y] == IS_WATER) counter++ ;
                if(field[x+1][y] == IS_WATER) counter++ ;
                if(field[x-1][y+1] == IS_WATER) counter++ ;
                if(field[x+1][y+1] == IS_WATER) counter++ ;

                if(field[x-1][y+length-1] == IS_WATER) counter++ ;
                if(field[x+1][y+length-1] == IS_WATER) counter++ ;
                if(field[x-1][y+length] == IS_WATER) counter++ ;
                if(field[x][y+length] == IS_WATER) counter++ ;
                if(field[x+1][y+length] == IS_WATER) counter++ ;

            } catch (IndexOutOfBoundsException e) {
                counter++;
            }
            Log.d(TAG, "Direction: Down. Counter = " + counter);
            if (counter  == 12)
                return true;
            break;
        }
        return false;
    }

那是2-4艘船。对于单体船:

private static boolean checkIfOneAvailable(int x, int y) {
         int counter = 0;
         try {
                if(field[x-1][y-1] == IS_WATER) counter++ ;
                if(field[x][y-1] == IS_WATER)counter++ ;
                if(field[x+1][y-1] == IS_WATER) counter++ ;
                if(field[x-1][y] == IS_WATER) counter++ ;
                if(field[x+1][y] == IS_WATER) counter++ ;
                if(field[x-1][y+1] == IS_WATER) counter++ ;
                if(field[x+1][y+1] == IS_WATER) counter++ ;
                if(field[x][y+1] == IS_WATER) counter++ ;   
        } catch (IndexOutOfBoundsException e) {     
          counter++;
        } 
         if (counter == 8) 
             return true;
        return false;

     }

你能告诉我,错误在哪里以及如何将船只放在边缘?

2 个答案:

答案 0 :(得分:2)

不要测试水。测试另一艘船是否在那里。像这样:

private static boolean checkIfOneAvailable(int x, int y) {        
    if(x!=0 && y!=0 && field[x-1][y-1] == IS_SHIP) return false;
    if(y!=0 && field[x][y-1] == IS_SHIP) return false;
    ...
    return true;
 }

请注意,我已将对数组边界的检查添加到条件中。 使用异常进行流量控制被认为是一种坏习惯主要是因为它很慢。 使用这种方法时,您还可以从事实中获得性能提升,您不必总是检查所有周围的字段。一旦发现碰撞,就会得到结果。

对大型船舶的代码进行复制粘贴也没有意义。在您放置船舶之前,您仍然可以对大型船舶的每个油田进行相同的检查:

private static boolean checkIfAvailable(int x, int y, int dir, int length){
    for (int i = 0; i<length; i++){
        switch (dir) {
            case DIRECTION_RIGHT:
                if (!checkIfOneAvailable(x+i,y))
                    return false;
                break;
            case DIRECTION_DOWN:
                if (!checkIfOneAvailable(x,y+i))
                    return false;
                break;
        }             
    }
    return true;
}

答案 1 :(得分:1)

如果发生IndexOutOfBoundsException,则if(field...以后的catch行都不会被执行,并且计数器不会再增加。

更好的解决方案:创建一个方法,该方法获取坐标并返回field[x][y]值或特殊OUT_OF_BOUNDS值(通过捕获IndexOutOfBoundsException或检查边界)