Валидатор засчитывает только после изменения значения измененной плитки! В принципе это правильно, но об этом не сказано. Считаю правильным сначала производить действие в программе (или игре), а потом показывать это изменение.
Валидатор принял это:
private boolean mergeRow(int[] row) {
int length = row.length;
boolean ret = false;
for (int i = 0; i < length - 1; i++) {
if (row[i] == 0) {
continue;
} else if (row[i] == row[i + 1]) {
row[i] *= 2;
score += row[i];
setScore(score);
row[i + 1] = 0;
ret = true;
i++;
}
}
return ret;
}package com.javarush.games.game2048;
import com.javarush.engine.cell.*;
import java.util.ArrayList;
import java.util.Arrays;
public class Game2048 extends Game {
private static final int SIDE = 4;
private int[][] gameField = new int[SIDE][SIDE];
private boolean isGameStopped = false;
private int score;
@Override
public void initialize() {
setScreenSize(SIDE, SIDE);
createGame();
drawScene();
}
@Override
public void onKeyPress(Key key) {
if (key == Key.SPACE) {
isGameStopped = false;
createGame();
drawScene();
}
if (!canUserMove()) {
gameOver();
return;
}
if (!isGameStopped) {
if (key == Key.LEFT) {
moveLeft();
drawScene();
} else if (key == Key.RIGHT) {
moveRight();
drawScene();
} else if (key == Key.UP) {
moveUp();
drawScene();
} else if (key == Key.DOWN) {
moveDown();
drawScene();
}
}
}
private void createGame() {
score = 0;
for (int[] row : gameField) {
Arrays.fill(row, 0);
}
createNewNumber();
createNewNumber();
}
private void drawScene() {
for (int i = 0; i < gameField.length; i++) {
for (int j = 0; j < gameField[i].length; j++) {
setCellColoredNumber(i, j, gameField[j][i]);
}
}
}
private void createNewNumber() {
if (getMaxTileValue() == 2048) {
win();
}
int randomNumber = getRandomNumber(10);
while (true) {
int x = getRandomNumber(SIDE);
int y = getRandomNumber(SIDE);
if (gameField[x][y] == 0) {
if (randomNumber < 9) {
gameField[x][y] = 2;
return;
} else {
gameField[x][y] = 4;
return;
}
}
}
}
private Color getColorByValue(int value) {
if (value == 2) return Color.LIGHTPINK;
if (value == 4) return Color.SLATEBLUE;
if (value == 8) return Color.DODGERBLUE;
if (value == 16) return Color.TURQUOISE;
if (value == 32) return Color.MEDIUMSEAGREEN;
if (value == 64) return Color.LIMEGREEN;
if (value == 128) return Color.ORANGE;
if (value == 256) return Color.SALMON;
if (value == 512) return Color.ORANGERED;
if (value == 1024) return Color.DEEPPINK;
if (value == 2048) return Color.MEDIUMVIOLETRED;
return Color.SEASHELL;
}
private void setCellColoredNumber(int x, int y, int value) {
setCellValueEx(x, y, getColorByValue(value), value == 0 ? "" : "" + value);
}
private boolean compressRow(int[] row) {
int length = row.length;
int[] rowTemp = new int[length];
int tek = 0;
for (int i = 0; i < length; i++) {
if (row[i] != 0) {
rowTemp[tek] = row[i];
tek++;
}
}
if (!Arrays.equals(row, rowTemp)) {
for (int i = 0; i < length; i++) {
row[i] = rowTemp[i];
}
return true;
} else return false;
}
private boolean mergeRow(int[] row) {
int length = row.length;
boolean ret = false;
for (int i = 0; i < length - 1; i++) {
if (row[i] == 0) {
continue;
} else if (row[i] == row[i + 1]) {
row[i] *= 2;
score += row[i];
setScore(score);
row[i + 1] = 0;
ret = true;
i++;
}
}
return ret;
}
private void moveLeft() {
boolean step = false;
for (int i = 0; i < gameField.length; i++) {
if (compressRow(gameField[i])) step = true;
if (mergeRow(gameField[i])) {
step = true;
if (compressRow(gameField[i])) step = true;
}
}
if (step) {
createNewNumber();
}
}
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() {
int[][] temp = new int[SIDE][SIDE];
for (int i = 0; i < SIDE; i++) {
for (int j = 0; j < SIDE; j++) {
temp[i][j] = gameField[SIDE - 1 - j][i];
}
}
for (int i = 0; i < SIDE; i++) {
for (int j = 0; j < SIDE; j++) {
gameField[i][j] = temp[i][j];
}
}
}
private int getMaxTileValue() {
int maxValue = 0;
for (int i = 0; i < SIDE; i++) {
for (int j = 0; j < SIDE; j++) {
if (maxValue < gameField[i][j]) maxValue = gameField[i][j];
}
}
return maxValue;
}
private void win() {
isGameStopped = true;
showMessageDialog(Color.RED, "ПОБЕДА!", Color.BLACK, 75);
}
private boolean canUserMove() {
for (int i = 0; i < SIDE; i++) {
for (int j = 0; j < SIDE; j++) {
if (gameField[i][j] == 0) return true;
}
}
for (int i = 0; i < SIDE; i++) {
for (int j = 0; j < SIDE; j++) {
if (i + 1 < SIDE && gameField[i][j] == gameField[i + 1][j]) {
return true;
}
if (j + 1 < SIDE && gameField[i][j] == gameField[i][j + 1]) {
return true;
}
}
}
return false;
}
private void gameOver() {
isGameStopped = true;
showMessageDialog(Color.RED, "ИГРА ЗАКОНЧЕНА", Color.BLACK, 75);
}
}