Четырехпалубный корабль будет один на игровом поле и он будет самым большим. Найти случайное место для однопалубных кораблей проще всего.
Четырехпалубный корабль будем создавать самым первым, пока игровое поле еще не заполнено другими кораблями. Палубы такого корабля будут отмечаться в двумерном массиве числом четыре 4. Вокруг такой корабль будет также окружаться значениями минус единица -1. После генерации четырехпалубного корабля в двумерном массиве получится следующее (см. рис. 11).
Рис. 11
Расположение корабля каждый раз должно выбираться случайно.
Схема генерации одного четырехпалубного корабля будет заключаться в следующем:
1. Выбираем случайную ячейку –это будет голова корабля - одна из четырех палуб (см. рис. 12).
Рис. 12
2. На пустом поле эта ячейка содержит нулевое значение. Устанавливаем в нее число четыре 4 (см. рис. 12).
3. Окружаем ячейку значением минус два-2 (см. рис. 13). При построении корабля мы будем окружать каждую палубу значением минус два -2. После завершения построения заменим минус два -2 на минус один -1.
Рис. 13
4. Далее выбираем направление построения корабля –вверх, вправо, вниз, влево.Направление должно выбираться случайным образом одно из четырех.
5. Проверяем возможность построения дополнительных трех палуб корабля в выбранном направлении. Если происходит выход за границы массива –меняем направление на противоположное.
6. Добавляем три палубы. После добавления каждой палубы выполняем ее окружение значением минус два -2 (см. рис. 14, 15, 16).
Рис. 14
Рис. 15
Рис. 16
7. После завершения построения корабля заменяем окружение значением минус два -2на значение минус один -1 (см. рис. 17).
Рис. 17
Значение минус два-2 в двумерном массиве будет обозначать, что происходит построение корабля, и оно еще не завершено.Это необходимо, чтобы отличать окружение в виде минус единиц -1 соседних кораблей.
Добавим метод для конечного окружения корабля. Метод,который заменяет все значения минус два-2 в массиве на минус один -1:
//Конечное окружение
private void okrEnd(int[][] mas) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
// Если значение элемента массива -2,
// то заменяем его на -1
if (mas[i][j] == -2)
mas[i][j] = -1;
}
}
}
Также нам понадобится метод для тестирования возможности расположения палубы корабля:
// Проверка ячейки для возможности размещения в ней палубы корабля
private boolean testNewPaluba(int[][] mas, int i, int j) {
// Если выход за границы массива
if (testMasPoz(i, j) == false)
return false;
// Если в этой ячейке 0 или -2, то она нам подходит
if ((mas[i][j] == 0) || (mas[i][j] == -2))
return true;
return false;
}
Этот метод выполняет проверку выхода за границы массива и значение в ячейке, в которой мы хотим разместить новую палубу. Если это значения0или -2, то мы можем разместить там новую палубу.
Осталось добавить метод генерации четырехпалубного корабля. Этот метод реализует схему построения четырехпалубного корабля, рассмотренную выше:
//Создание одного четырехпалубного корабля
private void make4P(int[][] mas) {
//Координаты головы корабля
int i = 0, j = 0;
//Создание первой палубы - головы корабля
//Получение случайной строки
i = (int) (Math.random() * 10);
//Получение случайной колонки
j = (int) (Math.random() * 10);
//Помещаем в ячейку число четыре 4
mas[i][j] = 4;
//Окружаем минус двойками
okrBegin(mas, i, j, -2);
//Выбираем случайное направление построения корабля
// 0 -вверх, 1 - вправо, 2 - вниз, 3 - влево
int napr = (int) (Math.random() * 4);
if (napr == 0) // вверх
{
// Если выход за границы массива
if (testNewPaluba(mas, i - 3, j) == false)
napr = 2; // меняем на вниз
}
else if (napr == 1) // вправо
{
// Если выход за границы массива
if (testNewPaluba(mas, i, j + 3) == false)
napr = 3; // меняем на влево
}
else if (napr == 2) // вниз
{
// Если выход за границы массива
if (testNewPaluba(mas, i + 3, j) == false)
napr = 0; // меняем на вверх
}
else if (napr == 3) // влево
{
// Если выход за границы массива
if (testNewPaluba(mas, i, j - 3) == false)
napr = 1; // меняем на вправо
}
if (napr == 0) // вверх
{
// Помещаем в ячейку число четыре 4
mas[i - 3][j] = 4;
// Окружаем минус двойками
okrBegin(mas, i - 3, j,-2);
// Помещаем в ячейку число четыре 4
mas[i - 2][j] = 4;
// Окружаем минус двойками
okrBegin(mas, i - 2, j,-2);
// Помещаем в ячейку число четыре 4
mas[i - 1][j] = 4;
// Окружаем минус двойками
okrBegin(mas, i - 1, j,-2);
}
else if (napr == 1) // вправо
{
// Помещаем в ячейку число четыре 4
mas[i][j + 3] = 4;
// Окружаем минус двойками
okrBegin(mas, i, j + 3,-2);
// Помещаем в ячейку число четыре 4
mas[i][j + 2] = 4;
// Окружаем минус двойками
okrBegin(mas, i, j + 2,-2);
// Помещаем в ячейку число четыре 4
mas[i][j + 1] = 4;
// Окружаем минус двойками
okrBegin(mas, i, j + 1,-2);
}
else if (napr == 2) // вниз
{
// Помещаем в ячейку число четыре 4
mas[i + 3][j] = 4;
// Окружаем минус двойками
okrBegin(mas, i + 3, j,-2);
// Помещаем в ячейку число четыре 4
mas[i + 2][j] = 4;
// Окружаем минус двойками
okrBegin(mas, i + 2, j,-2);
// Помещаем в ячейку число четыре 4
mas[i + 1][j] = 4;
// Окружаем минус двойками
okrBegin(mas, i + 1, j,-2);
}
else if (napr == 3) // влево
{
// Помещаем в ячейку число четыре 4
mas[i][j - 3] = 4;
// Окружаем минус двойками
okrBegin(mas, i, j - 3,-2);
// Помещаем в ячейку число четыре 4
mas[i][j - 2] = 4;
// Окружаем минус двойками
okrBegin(mas, i, j - 2,-2);
// Помещаем в ячейку число четыре 4
mas[i][j - 1] = 4;
// Окружаем минус двойками
okrBegin(mas, i, j - 1,-2);
}
//Конечное окружение
okrEnd(mas);
}
Чтобы этот метод выполнял свою работу, поместим его вызов в методе start():
//Запуск игры - начало игры
public void start() {
//Очищаем игровое поле игрока
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
masPlay[i][j] = 0;
}
}
//Создание четырехпалубного корабля
make4P(masPlay);
//Создание однопалубных кораблей
make1P(masPlay);
}
Обратите внимание, что построение четырехпалубного корабля идет первым!Только потом создаются однопалубные корабли. Запустим приложение (см. рис. 18).
Рис. 18
Реализация игры Морской бой для второго уровня сложности закончена. Полный программный код классаgame для второго уровня сложности выглядит так:
// Класс реализации логики игры
public class game {
// Массив для игрового поля игрока
public int[][] masPlay;
// Конструктор класса
public game() {
//Создаем массив 10x10 - игровое поле игрока
masPlay = new int[10][10];
}
// Запуск игры - начало игры
public void start() {
//Очищаем игровое поле игрока
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
masPlay[i][j] = 0;
}
}
//Создание четырехпалубного корабля
make4P(masPlay);
//Создание однопалубных кораблей
make1P(masPlay);
}
// Проверка не выхода за границы массива
private boolean testMasPoz(int i, int j) {
if (((i> = 0) && (i <= 9)) && ((j >= 0) && (j <= 9))) {
return true;
} else
return false;
}
// Запись значения в массив с проверкой границ массива
private void setMasValue(int[][] mas, int i, int j, int val) {
// Если не происходит выход за границы массива
if (testMasPoz(i, j) == true) {
// Записываем значение в массив
mas[i][j] = val;
}
}
// Установить один элемент окружения
private void setOkr(int[][] mas, int i, int j, int val) {
// Если не происходит выход за пределы массива
// и в ячейке нулевое значение
if (testMasPoz(i, j) && (mas[i][j] == 0))
// Устанавливаем необходимое значение
setMasValue(mas, i, j, val);
}
// Окружение одной ячейки вокруг
private void okrBegin(int[][] mas, int i, int j, int val) {
setOkr(mas, i - 1, j - 1, val); // сверху слева
setOkr(mas, i - 1, j, val); // сверху
setOkr(mas, i - 1, j + 1, val); // сверху справа
setOkr(mas, i, j + 1, val); // справа
setOkr(mas, i + 1, j + 1, val); // снизу справа
setOkr(mas, i + 1, j, val); // снизу
setOkr(mas, i + 1, j - 1, val); // снизу слева
setOkr(mas, i, j - 1, val); // слева
}
// Конечное окружение
private void okrEnd(int[][] mas) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
// Если значение элемента массива -2,
// то заменяем его на -1
if (mas[i][j] == -2)
mas[i][j] = -1;
}
}
}
// Создание четырех однопалубных кораблей
private void make1P(int[][] mas) {
// Циклfor делает четыре шага - для четырех кораблей
for (int k = 1; k <= 4; k++) {
// Глухой циклwhile
while (true) {
// Находим случайную позицию на игровом поле
int i = (int) (Math.random() * 10);
int j = (int) (Math.random() * 10);
// Проверяем, что там ничего нет и
// можно разместить корабль
if (mas[i][j] == 0) {
// Размещаем однопалубный корабль
mas[i][j] = 1;
// Выполняем окружение
okrBegin(mas, i, j, -1);
// Прерываем цикл
break;
}
}
}
}
// Проверка ячейки для возможности размещения в ней палубы корабля
private boolean testNewPaluba(int[][] mas, int i, int j) {
// Если выход за границы массива
if (testMasPoz(i, j) == false)
return false;
// Если в этой ячейке 0 или -2, то она нам подходит
if ((mas[i][j] == 0) || (mas[i][j] == -2))
return true;
return false;
}
// Создание одного четырехпалубного корабля
private void make4P(int[][] mas) {
//Координаты головы корабля
int i = 0, j = 0;
//Создание первой палубы - головы корабля
//Получение случайной строки
i = (int) (Math.random() * 10);
//Получение случайной колонки
j = (int) (Math.random() * 10);
//Помещаем в ячейку число четыре 4
mas[i][j] = 4;
//Окружаем минус двойками
okrBegin(mas, i, j, -2);
//Выбираем случайное направление построения корабля