【问题标题】:Battleship game - ships overlapping战舰游戏 - 船只重叠
【发布时间】:2014-01-18 09:03:06
【问题描述】:

我正在使用 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 循环,但它没有帮助。

【问题讨论】:

  • 那么快速的方法是检查该船将占据的任何位置是否已经被占据......
  • while 循环确保船的起点不会放在完全相同的点,但不考虑船的其余部分,因此重叠。您能否也发布您的 add 函数的代码,因为这可能是放置代码的最佳位置,包括 while 循环和随机数生成。

标签: java java-canvas acm-java-libraries


【解决方案1】:

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

换句话说,您可以定义 BattleShip 类,该类将包含船的位置、大小和其他属性,并且它还可以包含检查它是否与另一艘船相交的方法。

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

然后您可以一次性将它们全部呈现在屏幕上。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 我认为将船只放置在随机位置对游戏来说更有意义。如果你提前知道船的位置,玩游戏会有点烦人。
      • @user1455836 是的,当然,但随机性也得到保证(因为网格的分区/平铺是随机的,即我并不总是使用相同的网格平铺)。
      猜你喜欢
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      • 2018-01-05
      • 2022-01-02
      • 1970-01-01
      相关资源
      最近更新 更多