I have no ideas anymore, The last one doesn't work Requirements: The private void gameOver() method must be created in the Game2048 class. The isGameStopped variable must be set to true in the gameOver() method. The showMessageDialog(Color, String, Color, int) method must be called in the gameOver() method. The onKeyPress(Key) method must call the gameOver() method and do nothing else, if the canUserMove() method returns false.
package com.codegym.games.game2048;

import com.codegym.engine.cell. *;

import java.util.Arrays;

public class Game2048 extends Game {

    private static final int SIDE = 4;
    private boolean isGameStopped = false;
    @Override
    public void initialize() {
        setScreenSize(SIDE, SIDE);
        super.initialize();
        createGame();
        drawScene();

    }

    private int [][] gameField = new int[SIDE][SIDE];

    private void createGame() {
        createNewNumber();
        createNewNumber();
    }

    private void drawScene() {
        for(int x = 0; x < SIDE; x++) {
            for(int y = 0 ; y < SIDE; y++){
                setCellColoredNumber(y, x, gameField[x][y]);
            }
        }
    }
    private void createNewNumber() {
        int x;
        int y;
        do {
            x = getRandomNumber(SIDE);
            y = getRandomNumber(SIDE);
        } while (gameField[x][y] != 0);

        int chance = getRandomNumber(10);

        if (chance == 9) gameField[x][y] = 4;
        else gameField[x][y] = 2;

        if (getMaxTileValue() == 2048){
            getMaxTileValue();
            win();
         }

    }
    private Color getColorByValue (int value) {
        switch (value) {
            case 0:
                return Color.WHITE;
            case 2:
                return Color.BLUE;
            case 4:
                return Color.RED;
            case 8:
                return Color.GREEN;
            case 16:
                return Color.CYAN;
            case 32:
                return Color.GRAY;
            case 64:
                return Color.MAGENTA;
            case 128:
                return Color.ORANGE;
            case 256:
                return Color.PINK;
            case 512:
                return Color.YELLOW;
            case 1024:
                return Color.PURPLE;
            case 2048:
                return Color.BROWN;
            default:
                return Color.WHITE;
        }
    }
    private void setCellColoredNumber(int y, int s, int value) {
      if(value != 0)
          setCellValueEx(y, s, getColorByValue(value), Integer.toString(value));
      else
          setCellValueEx(y, s, getColorByValue(value), "");
    }
     private boolean compressRow (int [] row) {
        int temp = 0;
        int [] rowTemp = row.clone();
        boolean isChanged = false;
        for(int i = 0; i < row.length; i++) {
            for(int j = 0; j < row.length - i - 1; j++) {
                if(row[j] == 0){
                    temp = row[j];
                    row[j] = row[j + 1];
                    row[j + 1] = temp;
                }
            }
        }
        if(!Arrays.equals(row, rowTemp))
            isChanged = true;
        return isChanged;
    }
    private boolean mergeRow(int[] row) {
        boolean moved = false;
        for (int i=0; i< row.length-1;i++)
            if ((row[i] == row[i+1])&&(row[i]!=0)) {
                row[i] = 2 * row[i];
                row[i + 1] = 0;
                moved = true;
            }
        return moved;
    }
    private void moveLeft() {
        boolean counter = false;

        for (int[] row : gameField) {

            boolean compressed = compressRow(row);
            boolean merged = mergeRow(row);
            boolean compressed1 = compressRow(row);

            if ((merged || compressed || compressed1) && !counter) {

                createNewNumber();
                counter = true;

            }

            for (int num : row) {

                System.out.print(num);
            }
        }
    }
    private void moveRight() {
        rotateClockwise();
        rotateClockwise();
        moveLeft();
        rotateClockwise();
        rotateClockwise();
    }
    private void moveUp() {
        rotateClockwise();
        rotateClockwise();
        rotateClockwise();
        moveLeft();
        rotateClockwise();
    }
    private void moveDown() {
        rotateClockwise();
        moveLeft();
        rotateClockwise();
        rotateClockwise();
        rotateClockwise();
    }
    private void rotateClockwise() {
        for (int i = 0; i < SIDE / 2; i++)
        {
            for (int j = i; j < SIDE - i - 1; j++)
            {
                int temp = gameField[i][j];
                gameField[i][j] = gameField[SIDE - 1 - j][i];
                gameField[SIDE - 1 - j][i] = gameField[SIDE - 1 - i][SIDE - 1 - j];
                gameField[SIDE - 1 - i][SIDE - 1 - j] = gameField[j][SIDE - 1 - i];
                gameField[j][SIDE - 1 - i] = temp;
            }
        }
    }
    private int getMaxTileValue() {
        int dlugosc = gameField.length;
        int max = gameField[0][0];
        for(int i = 0; i < dlugosc; i++) {
            for(int j = 0; j < dlugosc; j++) {
                if (gameField[i][j] > max)
                    max = gameField[i][j];
            }
        }
        return max;
    }
    private void win() {
        isGameStopped = true;
        showMessageDialog(Color.PERU, "Wygrałeś gratulację", Color.TAN, SIDE);
    }
    private void gameOver() {
        isGameStopped = true;
        showMessageDialog(Color.PERU, "Nie masz więcej ruchów. Przegrałeś! ;(", Color.TAN, SIDE);
    }
    private boolean canUserMove() {
        boolean movesLeft = false;
        for (int i = 0 ; i < SIDE; i++)
            for (int j = 0 ; j<SIDE; j++) {
                if (gameField[i][j] == 0) {
                    movesLeft = true;
                }
                if ((i - 1) > 0 && (gameField[i][j] == gameField[i - 1][j])) {
                    movesLeft = true;
                }
                if ((i + 1) < SIDE && (gameField[i][j] == gameField[i + 1][j])) {
                    movesLeft = true;
                }
                if ((j + 1) < SIDE && (gameField[i][j] == gameField[i][j + 1])) {
                    movesLeft = true;
                }
                if ((j - 1) > 0 && (gameField[i][j] == gameField[i][j - 1])) {
                    movesLeft = true;
                }
            }
        return movesLeft;
    }


    @Override
    public void onKeyPress(Key key) {
        super.onKeyPress(key);
        gameOver();

        if(canUserMove() == false)
            gameOver();

        if (key == Key.LEFT) {
            moveLeft();
            drawScene();
        }
        if (key == Key.RIGHT) {
            moveRight();
            drawScene();
        }
        if (key == Key.UP) {
            moveUp();
            drawScene();
        }
        if (key == Key.DOWN) {
            moveDown();
            drawScene();
        }
    }

}