Всем привет! Прошу намекнуть на ошибку, а не отправлять готовое решение :)
У меня не проходят два требования: третье и пятое.
1) Не понимаю, почему не проходит третье требование. В методе createGame() я первым делом проверяю, остановлена ли игра, и если да, то присваиваю матрице новую ссылку на пустой массив:
if (isGameStopped) {
gameField = new int[SIDE][SIDE];
}
2) Понимаю, почему не проходит пятое требование.
Пока у меня реализовано так: если игра остановлена, то в бесконечном цикле я проверяю, не нажал ли пользователь на пробел. Но по сути я сравниваю одно и то же значение, т.к. после первой проверки я не ожидаю, что пользователь нажмет новую клавишу.
Подскажите, пожалуйста, как можно реализовать идею того, что код ждет нового значения нажатой клавиши?package com.javarush.games.game2048;
import com.javarush.engine.cell.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Game2048 extends Game {
private static final int SIDE = 4;
private int[][] gameField = new int[SIDE][SIDE];
private boolean isGameStopped;
@Override
public void initialize() {
setScreenSize(SIDE, SIDE);
createGame();
drawScene();
}
private void createGame() {
if (isGameStopped) {
gameField = new int[SIDE][SIDE];
}
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 randomX;
int randomY;
do {
randomX = getRandomNumber(SIDE);
randomY = getRandomNumber(SIDE);
} while (gameField[randomX][randomY] != 0);
int randomValue = getRandomNumber(10);
if (randomValue == 9) {
gameField[randomX][randomY] = 4;
} else {
gameField[randomX][randomY] = 2;
}
}
private void setCellColoredNumber(int x, int y, int value) {
Color color = getColorByValue(value);
if (value == 0) {
setCellValueEx(x, y, color, "");
} else {
setCellValueEx(x, y, color, String.valueOf(value));
}
}
private Color getColorByValue(int value) {
switch (value) {
case 0:
return Color.WHITE;
case 2:
return Color.LIGHTBLUE;
case 4:
return Color.PINK;
case 8:
return Color.LIGHTCORAL;
case 16:
return Color.CRIMSON;
case 32:
return Color.CORNFLOWERBLUE;
case 64:
return Color.PLUM;
case 128:
return Color.HONEYDEW;
case 256:
return Color.POWDERBLUE;
case 512:
return Color.MOCCASIN;
case 1024:
return Color.SEAGREEN;
case 2048:
return Color.SEASHELL;
}
return null;
}
private boolean compressRow(int[] row) {
int[] rowFirstVersion = Arrays.copyOf(row, row.length);
List<Integer> copyOfRow = new ArrayList<>();
for (int k : row) {
copyOfRow.add(k);
}
Integer element;
for (int i = 0; i < copyOfRow.size(); i++) {
element = copyOfRow.get(i);
if (element == 0) {
int sum = 0;
Integer nextElement;
for (int j = i + 1; j < copyOfRow.size(); j++) {
nextElement = copyOfRow.get(j);
sum += nextElement;
}
if (sum == 0) break;
copyOfRow.add(element);
copyOfRow.remove(i);
i--;
}
}
for (int i = 0; i < row.length; i++) {
row[i] = copyOfRow.get(i);
}
for (int i = 0; i < row.length; i++) {
if (rowFirstVersion[i] != row[i]) {
return true;
}
}
return false;
}
private boolean mergeRow(int[] row) {
boolean wasAnyAction = false;
for (int i = 0; i < row.length; i++) {
if (!(row[i] == 0 || i == row.length - 1) && (row[i] == row[i + 1])) {
row[i] = row[i] + row[i + 1];
row[i + 1] = 0;
wasAnyAction = true;
}
}
return wasAnyAction;
}
@Override
public void onKeyPress(Key key) {
if (isGameStopped) {
boolean keyIsSpace = false;
do {
keyIsSpace = key == Key.SPACE;
} while (keyIsSpace);
initialize();
isGameStopped = false;
return;
}
if (!canUserMove()) {
gameOver();
return;
}
switch (key) {
case LEFT: moveLeft();
break;
case RIGHT: moveRight();
break;
case UP: moveUp();
break;
case DOWN: moveDown();
break;
default: return;
}
drawScene();
}
private void moveLeft() {
boolean flag = false;
for (int[] ints : gameField) {
if (compressRow(ints) | mergeRow(ints) | compressRow(ints)) {
flag = true;
}
}
if (flag) {
createNewNumber();
}
}
private void rotateClockwise() {
int[][] copyOfGameField = new int[gameField.length][];
for (int i = 0; i < gameField.length; i++) {
copyOfGameField[i] = Arrays.copyOf(gameField[i], gameField[i].length);
}
for (int i = 0; i < copyOfGameField.length; i++) {
for (int j = 0; j < copyOfGameField[i].length; j++) {
gameField[j][i] = copyOfGameField[copyOfGameField.length - i - 1][j];
}
}
}
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 int getMaxTileValue() {
int maxTileValue = 0;
for (int i = 0; i < gameField.length; i++) {
for (int j = 0; j < gameField[i].length; j++) {
if (gameField[i][j] > maxTileValue) {
maxTileValue = gameField[i][j];
}
}
}
return maxTileValue;
}
private void win() {
isGameStopped = true;
showMessageDialog(Color.LIGHTGREEN, "Вы победили!", Color.GREENYELLOW, 16);
}
private boolean canUserMove() {
boolean canUserMove = false;
boolean canCompressOrMergeRow = false;
int countOfZero = 0;
for (int i = 0; i < gameField.length; i++) {
for (int j = 0; j < gameField[i].length; j++) {
if (gameField[i][j] == 0) {
countOfZero++;
break;
} else if ((j < gameField[i].length - 1 && gameField[i][j] == gameField[i][j + 1])
|| (i < gameField.length - 1 && gameField[i][j] == gameField[i + 1][j])) {
canCompressOrMergeRow = true;
}
}
}
if (countOfZero > 0 || canCompressOrMergeRow) {
canUserMove = true;
}
return canUserMove;
}
private void gameOver() {
isGameStopped = true;
showMessageDialog(Color.ROSYBROWN, "Вы проиграли!", Color.MISTYROSE, 16);
}
}