Кратко: работает, но валидатору мой код не нравится.
package com.javarush.task.jdk13.task53.task5301;
import com.javarush.engine.cell.*;
//import java.util.Arrays;
public class Game2048 extends Game {
private static final int SIDE = 4;
private int[][] gameField = new int[SIDE][SIDE];
@Override
public void initialize() {
// rotateClockwise(); // demo
setScreenSize(SIDE, SIDE);
showGrid(false);
createGame();
drawScene();
}
private void drawScene() {
// Matrix is always defined in reverse coordinates order like (y, x), but not (x, y).
for (int y = 0; y < gameField.length; y++) {
for (int x = 0; x < gameField[y].length; x++) {
setCellColoredNumber(x, y, gameField[y][x]);
}
}
}
private void createGame() {
// compressRow(new int[]{0, 0, 2, 2}); // demo
// mergeRow(new int[]{2, 2, 2, 2}); // demo
createNewNumber();
createNewNumber();
}
private void createNewNumber() {
int percentage = getRandomNumber(10);
int randNumber = percentage < 9 ? 2 : 4;
while (true) {
int y = getRandomNumber(SIDE);
int x = getRandomNumber(SIDE);
if (gameField[y][x] != 0) continue;
gameField[y][x] = randNumber;
break;
}
}
private void setCellColoredNumber(int x, int y, int value) {
String strValue = value != 0 ? String.valueOf(value) : "";
setCellValueEx(x, y, getColorByValue(value), strValue, Color.WHITE, 25);
}
private Color getColorByValue(int value) {
if (value == 2) return Color.CYAN;
else if (value == 4) return Color.DARKCYAN;
else if (value == 8) return Color.LIGHTGREEN;
else if (value == 16) return Color.INDIGO;
else if (value == 32) return Color.KHAKI;
else if (value == 64) return Color.DARKORANGE;
else if (value == 128) return Color.BLUE;
else if (value == 256) return Color.RED;
else if (value == 512) return Color.YELLOWGREEN;
else if (value == 1024) return Color.TOMATO;
else if (value == 2048) return Color.DARKVIOLET;
return Color.WHITE;
}
private boolean compressRow(int[] row) {
boolean isChanged = false;
for (int count = 0; count < SIDE; ) {
for (int i = 0; i < row.length; i++) {
if (i - 1 >= 0 && row[i] != 0 && row[i - 1] == 0) {
isChanged = true;
int temp = row[i];
row[i] = row[i - 1];
row[i - 1] = temp;
}
}
count++;
}
return isChanged;
}
private boolean mergeRow(int[] row) {
boolean isChanged = false;
for (int i = 0; i < row.length; i++) {
if (i - 1 >= 0 && row[i] != 0 && row[i - 1] != 0 && row[i - 1] == row[i]) {
isChanged = true;
int voidValue = 0;
row[i - 1] = row[i - 1] + row[i];
row[i] = voidValue;
}
}
return isChanged;
}
@Override
public void onKeyPress(Key key) {
// super.onKeyPress(key);
if (key == Key.LEFT) {
moveLeft();
drawScene();
} else if (key == Key.UP) {
moveUp();
} else if (key == Key.DOWN) {
moveDown();
} else if (key == Key.RIGHT) {
moveRight();
}
}
private void moveRight() {
rotateClockwise();
rotateClockwise();
moveLeft();
rotateClockwise();
rotateClockwise();
drawScene();
}
private void moveUp() {
rotateClockwise();
rotateClockwise();
rotateClockwise();
moveLeft();
rotateClockwise();
drawScene();
}
private void moveDown() {
rotateClockwise();
moveLeft();
rotateClockwise();
rotateClockwise();
rotateClockwise();
drawScene();
}
private void moveLeft() {
boolean isChanged = false;
for (int i = 0; i < this.gameField.length; i++) {
boolean c1 = compressRow(this.gameField[i]);
boolean c2 = mergeRow(this.gameField[i]);
if (c1 || c2) {
isChanged = true;
compressRow(this.gameField[i]);
}
}
if (isChanged) createNewNumber();
}
private void rotateClockwise() {
int[][] tempArray = new int[this.gameField.length][this.gameField[0].length];
for (int y = 0; y < this.gameField.length; y++) { // works and I know why, finally!
for (int x = 0; x < this.gameField[y].length; x++) {
tempArray[x][tempArray.length - y - 1] = this.gameField[y][x];
}
}
for (int i = 0; i < tempArray.length; i++) {
for (int j = 0; j < tempArray[i].length; j++) {
this.gameField[i][j] = tempArray[i][j];
}
}
}
}