Содержание
Описание
Цель работы – разработать приложение, представляющее собой компьютерную реализацию игры «Пятнашки». В классическом варианте игра представляет собой набор одинаковых квадратных костяшек с нанесёнными числами, заключённых в квадратную коробку. Длина стороны коробки в четыре раза больше длины стороны костяшек для набора из 15 элементов, соответственно в коробке остаётся незаполненным одно квадратное поле. Цель игры — перемещая костяшки по коробке, добиться упорядочивания их по номерам, желательно сделав как можно меньше перемещений. Приложение должно быть разработано на языке Java (строго типизированный объектно-ориентированный язык программирования) и использовать JavaFX (платформа для создания RIA, позволяет строить унифицированные приложения с насыщенным графическим интерфейсом пользователя) и Scene builder (приложение для редактирования экранных форм JavaFX). Приложение должно иметь графический интерфейс, все действия в игре должны осуществляться при помощи «мыши». Приложение должно реализовать как классический вариант игры в пятнашки (поле 4 на 4), так и позволять пользователю устанавливать свободный размер поля. Приложение должно вести статистику - отображать количество сделанных ходов на поле, а также выводить количество времени, пройденного с начала игры.
Пример кода
package barleybreak;
import java.util.Random;
import java.util.ArrayList;
import java.util.Date;
// Класс основных операций с игрой
public class GameController {
// Реализуем паттерн "Одиночка"
private static GameController instance;
public static GameController getInstance() {
if (instance == null) {
instance = new GameController();
}
return instance;
}
// Игровое поле, размером rows на cols
private int[][] field;
// Количество рядов
private int rows;
// Количество колонок
private int cols;
// Число пройденных шагов с начала игры
private int totalSteps;
// Время начала игры
private long startTime = 0;
// Время окончания игры
private long endTime = 0;
// Флаг - игра запущена
private boolean isRunning = false;
// Возвращает количество рядов
public int getRows() {
return this.rows;
}
// Возвращает количество колонок
public int getCols() {
return this.cols;
}
// Возвращает значение в текущей ячейки игрового поля, 0 - ячейка пустая, иначе иммется элемент
public int getIndex(int row, int col) {
return this.field[row][col];
}
// Возвращает текущее состояние игры
public boolean getIsRunning() {
return this.isRunning;
}
// Возвращает число пройденных шагов с начала игры
public int getTotalSteps() {
return this.totalSteps;
}
// Возвращает строку в формате MM:SS - количество минут и секунд, прошедших с начала игры
public String getElapsedTime() {
// Проверка начата ли игра
if (startTime == 0) {
return "";
}
// Получаем текущее время
long curentTime = new Date().getTime();
// Если игра закончена ,то текущее время = время окончания игры
if (!this.isRunning)
curentTime = this.endTime;
// Находи разницу между началом и текущим временем
long diff = curentTime - startTime;
long diffSeconds = (diff / 1000) % 60;
long diffMinutes = (diff - diffSeconds) / (60 * 1000);
// Формируем строку, выводим результат
String result = String.format("%d:%02d", diffMinutes, diffSeconds);
return result;
}
// Метод запуска новой игры с параметрами размера поля, rowsCount - кол-во рядов, colsCount - кол-во колонок
public void startNewGame(int rowsCount, int colsCount) {
// Инициализируем новое поле с новыми размерами
this.rows = rowsCount;
this.cols = colsCount;
this.field = new int[this.rows][this.cols];
// Получаем время начала
this.startTime = new Date().getTime();
// Устанавливаем флаг начала игры
this.isRunning = true;
// Сбрасываем счетчики
this.totalSteps = 0;
// Инициализируем ячейки поля
initializeField();
// Перемешиваем ячейки поля
shuffleItems();
}
// Метод инициализации ячеек поля
private void initializeField() {
// Перебериаем все ряды и столбцы
for (int i = 0; i < this.rows; i++) {
for (int j = 0; j < this.cols; j++) {
if (i == this.rows - 1 && j == this.cols - 1) {
// Если это последний ряд и ячейка, то это пустое поле - ставим 0
this.field[i][j] = 0;
} else {
// Иначе присваиваем очередное значение
this.field[i][j] = i + this.rows * j + 1;
}
}
}
}
// Метод перемещивания элементов на поле
private void shuffleItems() {
// Инициализируем генератор случайных чисел
Random random = new Random();
// Определем число перемешиваний = длина * ширина * 10
int attempts = this.rows * this.cols * 10;
// Определяем положение пустой клетки
int row0 = this.rows - 1;
int col0 = this.cols - 1;
// Повторяем процедуру перемешивания
for (int i = 0; i < attempts; i++) {
// Формируем массив возможных передвижений на пустую клетку из текущего положения 1 - вниз, 2 - вверх, 3 - вправо, 4 - влево
ArrayList<Integer> randomList = new ArrayList<>();
randomList.clear();
if (row0 > 0) {
// Если есть ячейка сверху, то в массив движение вниз
randomList.add(1);
}
if (row0 < this.rows - 1) {
// Если есть ячейка снизу, то в массив движение вверх
randomList.add(2);
}
if (col0 > 0) {
// Если есть ячейка слева, то в массив движение вправо
randomList.add(3);
}
if (col0 < this.cols - 1) {
// Если есть ячейка справа, то в массив движение влево
randomList.add(4);
}
// Получаем случайное движение из списка
int rnd = random.nextInt(randomList.size());
if (randomList.get(rnd) == 1) {
// Если это движение вниз, то передвигаем вернюю ячейку вниз
this.field[row0][col0] = this.field[row0 - 1][col0];
row0 = row0 - 1;
} else if (randomList.get(rnd) == 2) {
// Если это движение вверх, то передвигаем нижнюю ячейку вверх
this.field[row0][col0] = this.field[row0 + 1][col0];
row0 = row0 + 1;
} else if (randomList.get(rnd) == 3) {
// Если это движение вправо, то передвигаем левую ячейку вправо
this.field[row0][col0] = this.field[row0][col0 - 1];
col0 = col0 - 1;
} else if (randomList.get(rnd) == 4) {
// Если это движение влево, то передвигаем правую ячейку влево
this.field[row0][col0] = this.field[row0][col0 + 1];
col0 = col0 + 1;
}
// В новую пустую клетку пишем значение 0
this.field[row0][col0] = 0;
}
}
// Метод проверки законичлась ли игра
public boolean checkEnd() {
// Проверем запущена ли сейчас игра
if(!this.isRunning)
return false;
// Перебериаем все ряды и столбцы
for (int i = 0; i < this.rows; i++) {
for (int j = 0; j < this.cols; j++) {
if (i == this.rows - 1 && j == this.cols - 1) {
// Если это последний ряд и ячейка, то проверем что на этом месте должен быть 0
if (this.field[i][j] != 0)
return false;
} else {
// Иначе проверяем очередное значение
if (this.field[i][j] != i + this.rows * j + 1)
return false;
}
}
}
// Если вся проверка пройдена и все элементы находятся на своих местах, то считаем что игра завершена
this.isRunning = false;
this.endTime = new Date().getTime();
return true;
}
// Функция перемещения ячейки в координате row, col в соседнюю пустую ячейку, если такая есть. Вохвращает результат перемещения.
public boolean moveItem(int row, int col) {
// Проверка если индексы вне границ массива
if (row > this.rows || col > this.cols) {
return false;
}
if (row > 0 && this.field[row - 1][col] == 0) {
// Если ячейка сверху есть и она пустая, то производим обмен
this.field[row - 1][col] = this.field[row][col];
this.field[row][col] = 0;
totalSteps++;
return true;
} else if (row < this.rows - 1 && this.field[row + 1][col] == 0) {
// Если ячейка снизу есть и она пустая, то производим обмен
this.field[row + 1][col] = this.field[row][col];
this.field[row][col] = 0;
totalSteps++;
return true;
} else if (col > 0 && this.field[row][col - 1] == 0) {
// Если ячейка слева есть и она пустая, то производим обмен
this.field[row][col - 1] = this.field[row][col];
this.field[row][col] = 0;
totalSteps++;
return true;
} else if (col < this.cols - 1 && this.field[row][col + 1] == 0) {
// Если ячейка справа есть и она пустая, то производим обмен
this.field[row][col + 1] = this.field[row][col];
this.field[row][col] = 0;
totalSteps++;
return true;
}
// Если свободных ячееек нет, то возвращаем отрицательный результат
return false;
}
}
Содержание архива
- текстовая часть
- проект в netbeans
Телеграм
-