Содержание
Описание
Цель работы – разработать приложение, представляющее собой компьютерную реализацию игры «Пятнашки». В классическом варианте игра представляет собой набор одинаковых квадратных костяшек с нанесёнными числами, заключённых в квадратную коробку. Длина стороны коробки в четыре раза больше длины стороны костяшек для набора из 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
Nekit203