public class Game2048 extends Game { int[][] arrayCell = new int[4][4]; int[][] oldArrayCell = new int[4][4]; int currentScore = 0; @Override public void initialize() {/*Аналог метода main*/ setScreenSize(4, 4);/*задает размер игрового поля*/ for (int x = 0; x < 4; x++) { /*Окрашивает все клетки поля в белый*/ for (int y = 0; y < 4; y++) { arrayCell[x][y] = 0; } } addNewTile(); setTurnTimer(10); } public boolean noAdjacentEqualCells(int[][] cell) {//проверка смежных равных ячеек boolean ask = true; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (cell[i][j] == 0) ask = false; // Если есть пустые клетки — игра не окончена // Проверяем соседа справа if (j < 3 && cell[i][j] == cell[i][j + 1]) ask = false; // Проверяем соседа снизу if (i < 3 && cell[i][j] == cell[i + 1][j]) ask = false; } } return ask; } public boolean oneCellNull(int[][] cell){ int zeroCount = 0; // Счетчик для нулей // Проходим по строкам for (int i = 0; i < cell.length; i++) { // Проходим по столбцам в текущей строке for (int j = 0; j < cell[i].length; j++) { if (cell[i][j] == 0) { zeroCount++; // Увеличиваем счетчик, если нашли 0 // Если найдено больше одного нуля, сразу возвращаем false if (zeroCount > 1) { return false; } } } } // После прохода по всему массиву, проверяем, был ли найден ровно один ноль return zeroCount == 1; } public boolean isFieldChanged(int[][] oldField, int[][] newField) { for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (oldField[x][y] != newField[x][y]) { return true; } } } return false; } public void addNewTile() { List<Point> freeCells = new ArrayList<>(); for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (arrayCell[x][y] == 0) { freeCells.add(new Point(x, y)); } } } // Проверка победы for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (arrayCell[x][y] == 2048) { showMessageDialog(Color.GREEN, "ПОБЕДА", Color.WHITE, 80); return; } } } // Добавляем новую плитку на случайную пустую клетку Point p = freeCells.get(getRandomNumber(0, freeCells.size())); int value = (getRandomNumber(0, 100) <= 9) ? 4 : 2; arrayCell[p.x][p.y] = value; updateCells(); } public void updateCells() { // Обновляем игровое поле for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (arrayCell[x][y] == 0) { setCellValueEx(x, y, Color.WHITE, ""); } else if (arrayCell[x][y] == 2) { setCellValueEx(x, y, Color.ALICEBLUE, "2"); } else if (arrayCell[x][y] == 4) { setCellValueEx(x, y, Color.ANTIQUEWHITE, "4"); } else if (arrayCell[x][y] == 8) { setCellValueEx(x, y, Color.BLUE, "8"); } else if (arrayCell[x][y] == 16) { setCellValueEx(x, y, Color.BLUEVIOLET, "16"); } else if (arrayCell[x][y] == 32) { setCellValueEx(x, y, Color.CADETBLUE, "32"); } else if (arrayCell[x][y] == 64) { setCellValueEx(x, y, Color.BURLYWOOD, "64"); } else if (arrayCell[x][y] == 128) { setCellValueEx(x, y, Color.CHARTREUSE, "128"); } else if (arrayCell[x][y] == 256) { setCellValueEx(x, y, Color.CORNSILK, "256"); } else if (arrayCell[x][y] == 512) { setCellValueEx(x, y, Color.DODGERBLUE, "512"); } else if (arrayCell[x][y] == 1024) { setCellValueEx(x, y, Color.FLORALWHITE, "1024"); } else if (arrayCell[x][y] == 2048) { setCellValueEx(x, y, Color.GREEN, "2048"); } } } // Здесь можно также обновлять счет, если он есть setScore(currentScore); } public void checkGameOver() { boolean noMoves = noAdjacentEqualCells(arrayCell) && noEmptyCells(arrayCell); if (noMoves) { showMessageDialog(Color.RED, "ПОРАЖЕНИЕ", Color.WHITE, 80); // Можно завершать игру здесь } } public boolean noEmptyCells(int[][] field) { for (int[] row : field) { for (int cell : row) { if (cell == 0) return false; } } return true; } @Override public void onKeyPress(Key key) { // 1. Считываем текущее состояние (если нужно, но лучше избегать getCellNumber) // Я оставил его, так как вы его используете, но это потенциальный источник ошибок. for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { arrayCell[x][y] = getCellNumber(x, y); } } // 2. Копируем данные в oldArrayCell (Корректное глубокое копирование) for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { oldArrayCell[x][y] = arrayCell[x][y]; } } boolean currentMoveChanged = false; // --- UP --- if (key == Key.UP) { for (int x = 0; x < 4; x++) { int[] column = new int[4]; int index = 0; // Сбор for (int y = 0; y < 4; y++) { if (arrayCell[x][y] != 0) { column[index++] = arrayCell[x][y]; } } // Объединение for (int i = 0; i < index - 1; i++) { if (column[i] == column[i + 1]) { column[i] *= 2; column[i + 1] = 0; currentScore += column[i]; setScore(currentScore); i++; } } // Упаковка вверх int[] newColumn = new int[4]; int newIndex = 0; for (int i = 0; i < 4; i++) { if (column[i] != 0) { newColumn[newIndex++] = column[i]; } } // Запись обратно for (int y = 0; y < 4; y++) { if (arrayCell[x][y] != newColumn[y]) { arrayCell[x][y] = newColumn[y]; currentMoveChanged = true; } } } } // --- DOWN --- if (key == Key.DOWN) { for (int x = 0; x < 4; x++) { int[] column = new int[4]; int index = 0; // Сбор (снизу вверх) for (int y = 3; y >= 0; y--) { if (arrayCell[x][y] != 0) { column[index++] = arrayCell[x][y]; } } // Объединение for (int i = 0; i < index - 1; i++) { if (column[i] == column[i + 1]) { column[i] *= 2; column[i + 1] = 0; currentScore += column[i]; setScore(currentScore); i++; } } // Упаковка вниз int[] newColumn = new int[4]; int newIndex = 3; for (int i = 0; i < 4; i++) { if (column[i] != 0) { newColumn[newIndex--] = column[i]; } } // Запись обратно (сверху вниз) for (int y = 0; y < 4; y++) { // Итерируем y от 0 до 3 if (arrayCell[x][y] != newColumn[y]) { arrayCell[x][y] = newColumn[y]; currentMoveChanged = true; } } } } // --- LEFT --- if (key == Key.LEFT) { for (int y = 0; y < 4; y++) { int[] row = new int[4]; int index = 0; // Сбор (слева направо) for (int x = 0; x < 4; x++) { if (arrayCell[x][y] != 0) { row[index++] = arrayCell[x][y]; } } // Объединение for (int i = 0; i < index - 1; i++) { if (row[i] != 0 && row[i] == row[i + 1]) { row[i] *= 2; row[i + 1] = 0; currentScore += row[i]; setScore(currentScore); i++; } } // Упаковка влево int[] newRow = new int[4]; int newIndex = 0; for (int i = 0; i < 4; i++) { if (row[i] != 0) { newRow[newIndex++] = row[i]; } } // Запись обратно for (int x = 0; x < 4; x++) { if (arrayCell[x][y] != newRow[x]) { arrayCell[x][y] = newRow[x]; currentMoveChanged = true; } } } } // --- RIGHT --- if (key == Key.RIGHT) { for (int y = 0; y < 4; y++) { int[] row = new int[4]; int index = 0; // Сбор (справа налево) for (int x = 3; x >= 0; x--) { if (arrayCell[x][y] != 0) { row[index++] = arrayCell[x][y]; } } // Объединение for (int i = 0; i < index - 1; i++) { if (row[i] != 0 && row[i] == row[i + 1]) { row[i] *= 2; row[i + 1] = 0; currentScore += row[i]; setScore(currentScore); i++; } } // Упаковка вправо int[] newRow = new int[4]; int newIndex = 3; for (int i = 0; i < 4; i++) { if (row[i] != 0) { newRow[newIndex--] = row[i]; } } // Запись обратно for (int x = 0; x < 4; x++) { if (arrayCell[x][y] != newRow[x]) { arrayCell[x][y] = newRow[x]; currentMoveChanged = true; } } } } // 3. Финальная обработка (УСЛОВИЕ ИСПРАВЛЕНО) if (currentMoveChanged) { // Обновляем поле updateCells(); // Добавляем новую плитку addNewTile(); } checkGameOver(); } }