Итак, ваша проблема заключается в случайном размещении линкоров на доске.Интересно.Вот как я бы это сделал.
Сначала давайте предположим, что у нас есть класс 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