8

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 ループを入れましたが、役に立ちません。

4

3 に答える 3

4

まず、モデル レイヤーとプレゼンテーション レイヤーを分割することをお勧めします。

つまり、BattleShip クラスを定義できます。このクラスは、船の位置、サイズ、および別のプロパティを保持し、別の船と交差するかどうかを確認するメソッドを含めることもできます。

次に、インスタンスがコレクションに存在するインスタンスと交差しない場合にのみ、インスタンスを作成してコレクションに追加できます。

次に、それらすべてを一度に画面にレンダリングできます。

于 2013-12-31T12:15:12.330 に答える
2

配列を作成し、キャンバスに入力した各船の場所の値を保存します。次に、次の船については、配置する前に、その場所がキャンバス上で既に取得されているかどうかを確認します. 明らかに、船の長さはさまざまで、水平と垂直の船もあることを覚えておく必要があります。

于 2013-12-31T12:23:42.990 に答える
1

私は最近、インタビューの一環としてこのゲームを実装しました。私の解決策は、グリッドを N > 3 のエリアにランダムに分割/タイル化し、必要な 3 隻の船 (戦艦 2 隻と駆逐艦 1 隻) を 1 つのエリアに配置することでした。N 個の領域はペアごとに重なり合うことはなく、まとめてグリッド全体をカバーします (これはグリッドのタイリングと呼ばれます)。N エリアが重ならないので、船も重ならない。インタビュアーはこのソリューションをとても気に入りました。また、ランダム性も保証されました。

別の解決策は、船をランダムな位置に配置し続け、船 K が以前に配置された船 (1、2、3、...、K-1) のいずれかと重複しているかどうかを確認し続けることでしたが、これにはいくつかの明らかな欠点がありました。好きなこと: 1) 作成しなければならない船舶のオーバーラップ チェック自体は、あまりエレガントでもクリーンでもありません。2) これは決定論的な手順ではなく、配置アルゴリズムが終了するかどうか、終了する場合は何ステップで終了するかが事前にわからないという事実。

そのため、上記のランダムなパーティショニング/タイリング ソリューションを実行しました。

于 2013-12-31T12:28:15.903 に答える