Игра Линкор - корабли перекрываются

Я пишу простую игру на линкорах на Java с использованием библиотеки ACM. После начала игры корабли должны быть размещены на холсте в случайных местах, но проблема в том, что корабли могут накрывать друг друга, и это не разрешено в игре. Как я могу избежать размещения кораблей друг над другом?

Мой код:

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);
    }
}

Как видите, я поместил цикл while внутри цикла for, но это не помогает.

3 ответа

Прежде всего, я бы предложил вам разделить слой модели и уровень представления.

Другими словами, вы можете определить класс BattleShip, этот класс будет содержать позицию, размер и другие свойства корабля, а также может содержать метод проверки, пересекается ли он с каким-либо другим кораблем.

Затем вы можете создавать экземпляры и добавлять их в коллекцию, только если экземпляр не пересекается с каким-либо экземпляром, присутствующим в коллекции.

Затем вы можете отобразить их все на экране за один раз.

Я бы создал массив и сохранял значения каждого местоположения корабля, когда вы вводите их на холст. Затем для следующего корабля, прежде чем разместить его, проверьте, занято ли это место на холсте. Очевидно, вы должны помнить, что корабли разной длины, а некоторые горизонтальные и вертикальные тоже.

Я недавно реализовал эту игру как часть интервью. Мое решение состояло в том, чтобы просто случайным образом разделить / разбить сетку на N > 3 областей, а затем разместить 3 требуемых корабля (2 линейных корабля и 1 эсминец), поместив один корабль в одну область. N областей не перекрываются попарно и, взятые вместе, они покрывают всю сетку (я думаю, это называется мозаикой сетки). Так как N областей не перекрываются, корабли тоже не перекрываются. Интервьюерам очень понравилось это решение. Кроме того, случайность была гарантирована тоже.

Альтернативное решение состояло в том, чтобы продолжать размещать корабли в случайных положениях и проверять, не перекрывает ли судно K какое-либо из ранее размещенных кораблей (1,2,3,...,K-1), но у этого были некоторые очевидные недостатки, которых я не заметил. t как: 1) сама проверка на перекрытие судна, которая должна быть сделана, не очень элегантна и чиста; 2) тот факт, что это не является детерминированной процедурой, и вы не знаете заранее, завершится ли ваш алгоритм размещения и сколько будет завершено.

Так что я просто сделал это случайное решение для разбиения / разбиения на листы, упомянутое выше.

Другие вопросы по тегам