Нужна помощь в программировании Селектор / Проверка местоположения линкора - PullRequest
6 голосов
/ 11 апреля 2011

Я пытаюсь разработать одностороннюю игру «Морской бой», и у меня почти все настроено. Мне нужно только включить массив, который в настоящее время содержит 5 объектов Ships. Класс, который я создал для каждого корабля, называется Ships.java. Ранее у меня были проблемы с инициализацией массива, но это было решено.

Проблема возникает, когда я пытаюсь вытянуть длину корабля (2, 3, 4 или 5) из индекса в массиве. Я не уверен, как концептуально идти о размещении кораблей.

Мне кажется, что я перепробовал каждую комбинацию do-whiles, циклов и операторов if. Даже пробовал распределительный шкаф.

Цель состоит в том, чтобы компьютер выбирал позиции для пяти кораблей и устанавливал каждую ячейку в сетке (ROWSxCOLS) равной NC_SHIP (не нажата, плюс корабль). Проблема заключается в том, что он проверяет положение ячеек рядом со случайным местоположением в сетке. Также необходимо проверить, подходит ли рассматриваемый корабль (извлечение с корабля [i] .getShipLength ()).

Вот код, который у меня есть:

int shipsPlaced = 0;

    for (int i = 0; i < ships.length; i++)
    {
        boolean shipPlaced = false;

        do
        {
            int randomRow = (int)(Math.random()*ROWS);
            int randomCol = (int)(Math.random()*COLS);
            int p = 0;

            if (randomRow - ships[p].getShipLength() >= 0 && gameBoard[(randomRow - p)][randomCol] == NC_EMPTY)
            {
                for (int x = 0; x < ships[x].getShipLength(); x++)
                {
                    gameBoard[(randomRow - x)][randomCol] = NC_SHIP;
                    shipsPlaced = shipsPlaced + 1;
                    if (x == ships[x].getShipLength())
                    {
                        shipPlaced = true;
                        p = p + 1;
                    }
                }
            }
        }while (shipPlaced == false);

    }

Все было инициализировано и установлено, если его здесь не видно. Проблема в математике / логике, используемой для размещения кораблей в «случайных» местах.

Ответы [ 3 ]

2 голосов
/ 11 апреля 2011

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

Есть два способа решения этой проблемы:

  1. Сначала подберите начальную позицию, затем посмотрите, подходит ли корабль.
  2. Сначала перечислите все доступные позиции, затем рандомизируйте для числа, равного длине списка

1 - Сделайте рекурсивный поиск случайныхначальная позиция (x, y) (которая должна быть свободной , если нет re-throw позиция).В рекурсивном методе " lookForPos " создайте randomPlacementDirection и, исходя из этого, флаг (например, isHor Horizontal). Если он не подходит (длина от начальной до конечной позиции превышает размер матрицы), re-throw .Покройте позиции (позиция, позиция + 1, позиция + 2, ..., позиция + n), где 'n' - длина вашего корабля, а позиция - пара x, y, а +1 влияет только на одного из кардиналов.(в зависимости от того, является ли горизонтальный или нет), если какой-либо из них также занят re-throw .В конце концов вы получите то, что вам нужно.

2 - Составьте список всех позиций, в которые он помещается (структура «для»), как горизонтальных, так и вертикальных, а затем рандомизируйте по длине списка.

0 голосов
/ 11 апреля 2011

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

Сначала давайте предположим, что у нас есть класс Ship:

public class Ship {

    int size;

    public Ship(int size) {
        this.size = size;
    }

    public int getSize() {
        return size;
    }

}

Затем у меня будет класс BattleshipBoard следующим образом:

public class BattleshipBoard {

    private final int rows;
    private final int cols;

    private char[][] board;

    public BattleshipBoard(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
        board = new char[rows][cols];
    }

    public void place(Ship[] ships) {

        Arrays.sort(ships, new Comparator<Ship>() {

            @Override
            public int compare(Ship s1, Ship s2) {
                return Integer.valueOf(s1.size).compareTo(Integer.valueOf(s2.size));
            }
        });

        for (int j = 0; j < rows; j++)
            for (int k = 0; k < cols; k++)
                board[j][k] = '-'; // Empty position

        char[][] checked = new char[rows][cols];
        Random random = new Random();
        for (int i = ships.length - 1; i >=0; i--) {
            for (int j = 0; j < rows; j++)
                for (int k = 0; k < cols; k++)
                    checked[j][k] = 'U'; // Unchecked position
            boolean placed = false;
            while (! placed) {
                int r = random.nextInt(rows);
                int c = random.nextInt(cols);
                if (checked[r][c] == 'U') {
                    checked[r][c] = 'C'; // Checked position
                    if (board[r][c] == '-') {
                        int direction = random.nextInt(4);
                        // 0 = North; 1 = East; 2 = South; 3 = West;
                        if (canPlace(ships[i], r, c, direction)) {
                            place(ships[i], r, c, direction);
                            placed = true;
                        }
                    }               
                }
            }
        }
    }

    private void place(Ship ship, int row, int col, int direction) {
        int size = ship.getSize();
        switch (direction) {
        case 0: // North
            for (int  i = row; i >= row - (size - 1); i--)
                board[i][col] = 'S';
            break;

        case 1: // East
            for (int i = col; i <= col + (size - 1); i++)
                board[row][i] = 'S';
            break;

        case 2: // South
            for (int i = row; i <= row + (size - 1); i++)
                board[i][col] = 'S';
            break;

        default: // West
            for (int i = col; i >= col - (size - 1); i--) 
                board[row][i] = 'S';
            break;
        }       
    }

    private boolean canPlace(Ship ship, int row, int col, int direction) {
        int size = ship.getSize();
        boolean thereIsRoom = true;
        switch (direction) {
        case 0: // North
            if (row - (size - 1) < 0)
                thereIsRoom = false;
            else 
                for (int  i = row; i >= row - (size - 1) && thereIsRoom; i--)
                    thereIsRoom = thereIsRoom & (board[i][col] == '-');
            break;

        case 1: // East
            if (col + (size - 1) >= cols)
                thereIsRoom = false;
            else
                for (int i = col; i <= col + (size - 1) && thereIsRoom; i++)
                    thereIsRoom = thereIsRoom & (board[row][i] == '-');
            break;

        case 2: // South
            if (row + (size - 1) >= rows)
                thereIsRoom = false;
            else
                for (int i = row; i <= row + (size - 1) && thereIsRoom; i++)
                    thereIsRoom  = thereIsRoom & (board[i][col] == '-');
            break;

        default: // West
            if (col - (size - 1) < 0) 
                thereIsRoom = false;
            else
                for (int i = col; i >= col - (size - 1) && thereIsRoom; i--) 
                    thereIsRoom = thereIsRoom & (board[row][i] == '-');
            break;
        }
        return thereIsRoom;
    }

    public void printBoard() {
        for (int i = 0; i < rows; i++)
            System.out.println(Arrays.toString(board[i]));
    }

}

Тогда, если у вас есть что-то вроде этого:

public static void main(String[] args) {
    Ship[] ships = new Ship[] {
            new Ship(1),
            new Ship(3),
            new Ship(2),
            new Ship(3)
    };
    BattleshipBoard battleshipBoard = new BattleshipBoard(7, 7);
    battleshipBoard.place(ships);
    battleshipBoard.printBoard();
}

, вы можете получить следующий вывод (в зависимости от вашего Random генератора):

[-, -, -, -, -, -, -]
[-, -, -, -, -, -, -]
[-, -, S, -, -, -, -]
[-, -, -, -, -, -, -]
[-, S, -, S, S, -, -]
[-, S, -, -, -, -, -]
[-, S, -, -, S, S, S]

, что является случайным размещением четырех кораблей размером 1, 2, 3 и 3.

Несколько комментариев:

  • метод place() пытаетсяслучайное размещение кораблей путем выбора случайной стартовой позиции (r,c) и случайного direction

  • массива ships сортируется, так что мы начинаем с самых больших кораблей в первую очередь (легче разместитьих, когда у нашей доски меньше занятых позиций)

  • матрица checked используется, чтобы избежать проверки одной и той же случайной позиции (r,c) более одного раза при попытке разместить корабль

  • метод canPlace() возвращает true, если переданный ship может быть помещен в board, начиная с позиции(r,c) и движение к пройденному direction

  • метод place() помещает пройденный ship в board, начиная с позиции (r,c) и идя к пройденномуdirection

0 голосов
/ 11 апреля 2011

Что бы я сделал:

  1. найдите случайное место, чтобы попытаться разместить там свой корабль.- как вы сделали

  2. В цикле итерации до этой точки (пройти весь массив - кажется, что вам нужно 2 цикла - один до конца массива, а затемодин от начала до этой точки)

  3. вызывать методы freeRowsInARow() и freeColsInARow() witch возвращает номер самого большого корабля, который может быть вставлен туда, начиная с данной точки (x, y)

  4. Проверьте, есть ли у вашего корабля size <= returnedValue (из методов, упомянутых выше), если да - вызовите метод, вставив его туда (выберите путь - вертикальный или горизонтальный) и разрыв цикла return);если нет - ofc продолжить поиск.

...