战舰游戏-战舰重叠



我正在使用ACM库用Java编写一个简单的战舰游戏。游戏开始后,船只应该被放在画布上的随机位置,但问题是船只可能会相互覆盖,这在游戏中是不允许的。我怎样才能避免这些船被放在一起?

我的代码是:

private void putSmallShips() {
for (int i = 0; i < SMALL_SHIP_QUANTITY; i++){
smallShip = new GRect(SMALL_SHIP_WIDTH, SHIP_HEIGHT);
int x = rgen.nextInt(10, 510);
int y = rgen.nextInt(10, 510);
while (true){
gobj = getElementAt(x, y);
if (gobj == null) break;
x = rgen.nextInt(10, 510);
y = rgen.nextInt(10, 510);
}
smallShip.setLocation(x, y);
add(smallShip);
}
}
private void putMiddleShips() {
for (int i = 0; i < MIDDLE_SHIP_QUANTITY; i++){
middleShip = new GRect(MIDDLE_SHIP_WIDTH, SHIP_HEIGHT);
int x = rgen.nextInt(10, 530);
int y = rgen.nextInt(10, 530);
while (true){
gobj = getElementAt(x, y);
if (gobj == null) break;
System.out.println("opa!");
x = rgen.nextInt(10, 530);
y = rgen.nextInt(10, 530);
}
x = x + i * 10;
y = y + i * 10;
middleShip.setLocation(x, y);
add(middleShip);
}
}
private void putBigShips() {
for (int i = 0; i < BIG_SHIP_QUANTITY; i++){
bigShip = new GRect(BIG_SHIP_WIDTH, SHIP_HEIGHT);
int x = rgen.nextInt(10, 550);
int y = rgen.nextInt(10, 550);
while (true){
gobj = getElementAt(x, y);
if (gobj == null) break;
x = rgen.nextInt(10, 550);
y = rgen.nextInt(10, 550);
}
bigShip.setLocation(x, y);
add(bigShip);
}
}

正如你所看到的,我在for循环中放了一个while循环,但它没有帮助。

首先,我建议您拆分模型层和表示层。

换句话说,你可以定义类BattleShip,该类将保存船只的位置、大小和其他属性,它还可以包含检查它是否与其他船只相交的方法。

然后,只有当实例与集合中的任何实例都不相交时,才能创建实例并将其添加到集合中。

然后您可以一次在屏幕上渲染所有这些。

我会创建一个数组,并在您将每个船舶位置的值输入到画布上时存储这些值。然后,对于下一艘船,在放置之前,请检查该位置是否已在画布上。显然,你必须记住,船只有不同的长度,有些也是水平的和垂直的。

我最近在一次采访中实现了这个游戏。我的解决方案是随机分区/平铺将网格划分为N>3个区域,然后放置所需的3艘舰艇(2艘战列舰和1艘驱逐舰),把一艘船放在一个区域。N个区域不成对重叠,合在一起覆盖整个网格(我认为这叫做网格的平铺)。因此,由于N区域不重叠,船只也不会重叠。面试官非常喜欢这种解决方案。此外,随机性也得到了保证。

另一种解决方案是将船只随机放置,并不断检查船只K是否与之前放置的任何船只(1、2、3、…、K-1)重叠,但这有一些明显的缺点,我不喜欢:1)必须进行的船只重叠检查本身并不优雅干净;2) 事实上,这不是一个确定性的过程,你事先不知道你的放置算法是否会终止,以及它是否会在多少步中终止。

所以我只是做了上面提到的这个随机分区/平铺解决方案。

最新更新