再次是我。我正在尝试制作一个非常简单的战舰游戏。 现在我想让船只与至少一个空闲单元分开。看图片
如您所见,边缘完全无船只,这使得可用的放置次数要小得多(或者更少?对不起我的英语不好)。
“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;
}
你能告诉我,错误在哪里以及如何将船只放在边缘?
答案 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
或检查边界)