package com.codegym.games.game2048;
import com.codegym.engine.cell.Game;
import com.codegym.engine.cell.*;
import java.util.*;
import java.util.function.IntPredicate;
public class Game2048 extends Game {
private static final int SIDE = 4;
private boolean isGameStopped = false;
private int[][] gameField;
@Override
public void initialize() {
setScreenSize(SIDE, SIDE);
createGame();
drawScene();
}
private void createGame() {
gameField = new int[SIDE][SIDE];
createNewNumber();
createNewNumber();
}
private void drawScene() {
for (int x = 0; x < SIDE; x++) {
for (int y = 0; y < SIDE; y++) {
setCellColoredNumber(x, y, gameField[y][x]);
}
}
}
private void createNewNumber() {
if (getMaxTileValue() == 2048) {
win();
}
int x;
int y;
do {
x = getRandomNumber(SIDE);
y = getRandomNumber(SIDE);
} while (gameField[y][x]!=0);
if (getRandomNumber(10) == 9) {
gameField[y][x] = 4;
} else {
gameField[y][x] = 2;
}
}
private Color getColorByValue(int value) {
if (value == 0) {
return Color.YELLOW;
}
if (value == 2) {
return Color.RED;
}
if (value == 4) {
return Color.BLUE;
}
if (value == 6) {
return Color.ALICEBLUE;
}
if (value == 8) {
return Color.ANTIQUEWHITE;
}
if (value == 16) {
return Color.AQUAMARINE;
}
if (value == 32) {
return Color.AZURE;
}
if (value == 64) {
return Color.BEIGE;
}
if (value == 128) {
return Color.BISQUE;
}
if (value == 256) {
return Color.BLANCHEDALMOND;
}
if (value == 512) {
return Color.BURLYWOOD;
}
if (value == 1024) {
return Color.CORNSILK;
}
return Color.GREENYELLOW;
}
private void setCellColoredNumber(int x, int y, int value) {
if (value == 0) {
setCellValueEx(x, y, getColorByValue(value), "");
} else {
setCellValueEx(x, y, getColorByValue(value), ""+value);
}
}
private boolean compressRow(int[] row) {
int firstIndexOfZero = row.length;
boolean flag = false;
for (int i = 0; i < row.length; i++) {
if (row[i] == 0) {
firstIndexOfZero = i;
break;
}
}
for (int i = firstIndexOfZero+1; i < row.length; i++) {
if (row[i] != 0) {
row[firstIndexOfZero++] = row[i];
row[i] = 0;
flag = true;
}
}
return flag;
}
private boolean mergeRow(int[] row) {
boolean flag = false;
for (int i = 1; i < row.length; i++) {
if (row[i] == row[i - 1] && row[i] != 0) {
row[i-1] += row[i];
row[i] = 0;
flag = true;
}
}
return flag;
}
@Override
public void onKeyPress(Key key) {
if (isGameStopped) {
if (key == Key.SPACE) {
isGameStopped = false;
createGame();
drawScene();
} else {
return;
}
}
if (!canUserMove()) {
gameOver();
return;
}
if (key == Key.UP) {
moveUp();
} else if (key == Key.RIGHT) {
moveRight();
} else if (key == Key.DOWN) {
moveDown();
} else if (key == Key.LEFT) {
moveLeft();
} else {
return;
}
drawScene();
}
private void moveUp() {
for (int i = 0; i < 3; i++) {
rotateClockwise();
}
moveLeft();
rotateClockwise();
}
private void moveDown() {
rotateClockwise();
moveLeft();
for (int i = 0; i < 3; i++) {
rotateClockwise();
}
}
private void moveLeft() {
boolean flag = false;
for (int[] ints : gameField) {
boolean wasCompressed = compressRow(ints);
boolean wasMerged = mergeRow(ints);
if (wasMerged) {
compressRow(ints);
}
if (wasCompressed || wasMerged) {
flag = true;
}
}
if (flag) {
createNewNumber();
}
}
private void moveRight() {
for (int i = 0; i < 2; i++) {
rotateClockwise();
}
moveLeft();
for (int i = 0; i < 2; i++) {
rotateClockwise();
}
}
private void rotateClockwise() {
int[][] temp = new int[SIDE][SIDE];
for (int i = 0; i < SIDE; i++) {
for (int i1 = 0; i1 < SIDE; i1++) {
temp[i1][SIDE-1-i] = gameField[i][i1];
}
}
gameField = temp;
}
private int getMaxTileValue() {
return Arrays.stream(Arrays.stream(gameField).max(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
int max1 = Arrays.stream(o1).max().getAsInt();
int max2 = Arrays.stream(o2).max().getAsInt();
if (max1 > max2) {
return 1;
}
if (max1 < max2) {
return - 1;
}
return 0;
}
}).get()).max().getAsInt();
}
private void win() {
isGameStopped = true;
showMessageDialog(Color.RED,"YOU WIN",Color.WHITE, 15);
}
private boolean canUserMove() {
for (int[] ints : gameField) {
if (Arrays.stream(ints).anyMatch(new IntPredicate() {
@Override
public boolean test(int value) {
if (value == 0) {
return true;
}
return false;
}
})) {
return true;
}
}
for (int y = 0; y < SIDE; y++) {
for (int x = 0; x < SIDE; x++) {
if (y < SIDE - 1 && gameField[y][x] == gameField[y + 1][x]) {
return true;
} else if ((x < SIDE - 1) && gameField[y][x] == gameField[y][x + 1]) {
return true;
}
}
}
return false;
}
private void gameOver() {
isGameStopped = true;
showMessageDialog(Color.GRAY,"GameOver",Color.WHITE, 15);
}
}
![]()