Ошибка: при нажатии на ячейки открывается иногда верные, иногда неверные соседние ячейки.
А если я попадаю, на пустую ячейку (нет мин рядом), то открываются все ячейки +1 мина, которая находится на границе с цифрами.
В итоге: Игра не проходима)
Игра: https://javarush.com/projects/apps/348774
Предполагаю, что ошибка в логике где-то здесь:
private void openTile(int x, int y) {
if (gameField[y][x].isOpen || gameField[y][x].isFlag || isGameStopped) return;
gameField[y][x].isOpen = true;
setCellColor(x, y, colorOpenCell);
countClosedTiles--;
if (gameField[y][x].isMine) {
setCellValueEx(x, y, colorBoomCell, MINE);
gameOver();
} else if (gameField[y][x].countMineNeighbors == 0) {
setCellValue(x, y, "");
for (GameObject neighbors : getNeighbors(gameField[x][y])) {
if (!neighbors.isOpen) {
openTile(neighbors.x, neighbors.y);
}
}
} else setCellNumber(x, y, gameField[y][x].countMineNeighbors);
if (!gameField[y][x].isMine && gameField[y][x].isOpen){
score+=5;
setScore(score);
}
Код игры:
package com.javarush.games.minesweeper;
import com.javarush.engine.cell.Color;
import com.javarush.engine.cell.Game;
import java.util.ArrayList;
import java.util.List;
public class MinesweeperGame extends Game {
private static final int SIDE = 9;
private int countMinesOnField;
private int countFlags;
private int countClosedTiles = SIDE*SIDE;
private int score;
private boolean isGameStopped;
private GameObject[][] gameField = new GameObject[SIDE][SIDE];
private static final String MINE = "\uD83D\uDCA3";
private static final String FLAG = "\uD83D\uDEA9";
private static final Color colorBackground = Color.ORANGE;
private static final Color colorOpenCell = Color.GREEN;
private static final Color colorFlagCell = Color.YELLOW;
private static final Color colorBoomCell = Color.RED;
private static final Color colorBackgroundMessage = Color.WHITE;
private static final Color colorTextMessage = Color.BLACK;
@Override
public void initialize() {
setScreenSize(SIDE, SIDE);
createGame();
}
@Override
public void onMouseLeftClick(int x, int y) {
if (isGameStopped) {
restart();
return;
}
openTile(x,y);
}
@Override
public void onMouseRightClick(int x, int y) {
markTile(x,y);
}
private void createGame() {
for (int y = 0; y < SIDE; y++) {
for (int x = 0; x < SIDE; x++) {
boolean isMine = getRandomNumber(10) < 1;
if (isMine) {
countMinesOnField++;
}
gameField[y][x] = new GameObject(x, y, isMine);
setCellColor(x, y, colorBackground);
setCellValue(x, y,"");
}
}
countMineNeighbors();
countFlags = countMinesOnField;
}
private List<GameObject> getNeighbors(GameObject gameObject) {
List<GameObject> result = new ArrayList<>();
for (int y = gameObject.y - 1; y <= gameObject.y + 1; y++) {
for (int x = gameObject.x - 1; x <= gameObject.x + 1; x++) {
if (y < 0 || y >= SIDE) {
continue;
}
if (x < 0 || x >= SIDE) {
continue;
}
if (gameField[y][x] == gameObject) {
continue;
}
result.add(gameField[y][x]);
}
}
return result;
}
private void countMineNeighbors() {
for (int y = 0; y < SIDE; y++) {
for (int x = 0; x < SIDE; x++) {
if (!gameField[y][x].isMine) {
for (GameObject neighbor : getNeighbors(gameField[y][x])) {
if (neighbor.isMine) {
gameField[y][x].countMineNeighbors++;
}
}
}
}
}
}
private void openTile(int x, int y) {
if (gameField[y][x].isOpen || gameField[y][x].isFlag || isGameStopped) return;
gameField[y][x].isOpen = true;
setCellColor(x, y, colorOpenCell);
countClosedTiles--;
if (gameField[y][x].isMine) {
setCellValueEx(x, y, colorBoomCell, MINE);
gameOver();
} else if (gameField[y][x].countMineNeighbors == 0) {
setCellValue(x, y, "");
for (GameObject neighbors : getNeighbors(gameField[x][y])) {
if (!neighbors.isOpen) {
openTile(neighbors.x, neighbors.y);
}
}
} else setCellNumber(x, y, gameField[y][x].countMineNeighbors);
if (!gameField[y][x].isMine && gameField[y][x].isOpen){
score+=5;
setScore(score);
}
if (!gameField[y][x].isMine && countClosedTiles == countMinesOnField) {
win();
}
}
private void markTile (int x, int y){
if (gameField[y][x].isOpen == true || (countFlags == 0 && gameField[y][x].isFlag == false || isGameStopped == true) ) return;
if (gameField[y][x].isFlag) {
countFlags++;
gameField[y][x].isFlag = false;
setCellValue(x, y, "");
setCellColor(x, y, colorBackground);
} else {
countFlags--;
gameField[y][x].isFlag = true;
setCellValue(x, y, FLAG);
setCellColor(x, y, colorFlagCell);
}
}
private void gameOver(){
isGameStopped = true;
showMessageDialog(colorBackgroundMessage, "YOU LOSER", colorTextMessage, 40);
}
private void win(){
isGameStopped = true;
showMessageDialog(colorBackgroundMessage, "YOU WINNER", colorTextMessage, 40);
}
private void restart(){
isGameStopped = false;
countClosedTiles = SIDE*SIDE;
score = 0;
countMinesOnField = 0;
setScore(score);
createGame();
}
}