Which is the mistake in the code for game Minesweeper

Tags: ,



import java.awt.Point;
import java.util.*;

public class Minesweeper {

    public static void main(String[] args) {
        Minesweeper minesweeper = new Minesweeper();
        minesweeper.randomX();
        minesweeper.game();
    }

    private static final int NR_OF_FIELDS = 81;
    private static final char EMPTY_SPACE = '.';
    char[][] minesweeper = new char[9][9];
    Random randNum = new Random();
    Scanner sc = new Scanner(System.in);
    static List<Point> points = new ArrayList<>();
    static List<Point> guess = new ArrayList<>();
    static Map<Point, Character> fields = init();

    public Minesweeper() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                minesweeper[i][j] = '.';
            }
        }
    }

    boolean finished = false;

    public void game() {
        while (!finished) {
            System.out.print("Set/delete mines marks (y and x coordinates): ");
            int n = sc.nextInt();
            int m = sc.nextInt();
            int x = n - 1;
            int y = m - 1;

            if (n < 0 || n > 9 || m < 0 || m > 9) {
                System.out.println("Coordinates should be from 1 to 9!");
//set character '*'
            } else if (fields.get(new Point(x, y)) == '.' && (getCharAt(x, y) == "0" || getCharAt(x, y) == "X")) {
                fields.put(new Point(x, y), '*');
                guess.add(new Point(x, y));
                finished = checkIfFinished();
                printMinesweeper();
// delete character '*'               
 } else if (fields.get(new Point(x, y)) == '*') {
                    fields.put(new Point(x, y), '.');
                    guess.remove(new Point(x, y));
                    finished = checkIfFinished();
                    printMinesweeper();
            } else {
                System.out.println("There is a number here!");
            }
        }
        System.out.println("Congratulations! You found all mines!");
    }

    private static boolean checkIfFinished() {
        return points.equals(guess);
    }

    private static Map<Point, Character> init() {
        Map<Point, Character> fields = new HashMap<>(81);
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++)
                fields.put(new Point(i, j), '.');
        }
        return fields;
    }

    public void printMinesweeper() {
        System.out.println(" " + "|" + "123456789" + "|");
        System.out.println("-" + "|" + "---------" + "|");
        for (int i = 0; i < 9; i++) {
            System.out.print(i + 1 + "|");
            for (int j = 0; j < 9; j++) {
                if (fields.get(new Point(i, j)) == '*') {
                    System.out.print(minesweeper[i][j] = fields.get(new Point(i, j)));
                    minesweeper[i][j] = 'X';
                } else if (minesweeper[i][j] == 'X') {
                    System.out.print('.');
                } else {
                    System.out.print(getCharAt(i, j));
                }
            }
            System.out.println("|");
        }
        System.out.println("-" + "|" + "---------" + "|");
    }

    private String getCharAt(int i, int j) {
        if (mineAt(i, j)) {
            return "X";
        }

        int minesNear = countMinesNear(i, j);
        if (minesNear == 0) {
            return ".";
        } else {
            return Integer.toString(minesNear);
        }
    }

    private boolean mineAt(int i, int j) {
        return minesweeper[i][j] == 'X';
    }

    private int countMinesNear(int i, int j) {
        int mines = 0;
        for (int x = -1; x <= 1; x++) {
            for (int y = -1; y <= 1; y++) {
                if (x + i >= 0 && x + i < minesweeper.length && y + j >= 0 && y + j < minesweeper.length) {
                    if (minesweeper[x + i][y + j] == 'X') {
                        mines++;
                    }
                }
            }
        }
        return mines;
    }

    public void randomX() {
        System.out.print("How many mines do you want on the field?: ");
        int numberOfMines = sc.nextInt();
        int i = 0;
        while (i < numberOfMines) {
            int x = randNum.nextInt(9);
            int y = randNum.nextInt(9);
            points.add(new Point(x, y));
            if (minesweeper[x][y] == '.') {
                minesweeper[x][y] = 'X';
                i++;
            }
        }
        printMinesweeper();
    }
}

Good morning. In short what the code does. When game begin, the user is asked System.out.print("How many mines do you want on the field?: ");. User input a number and random are generate mines on the 2d array table. Parallel points (x, y) from 2d array where is mines are add to List<Point> points = new ArrayList<>(); points.add(new Point(x, y)); All this do public void randomX() method. After print the table public void printMinesweeper(). This method print a 2d array table with hidden mines else if (minesweeper[i][j] == 'X') {System.out.print('.');} and visible digit, how many mines are around, calculated and prints by the method else { System.out.print(getCharAt(i, j));}. After program got to the method public void game() in while loop and ask user System.out.print("Set/delete mines marks (y and x coordinates): ");.User input 2 coordinates. Above I had declared static List<Point> guess = new ArrayList<>(); and static Map<Point, Character> fields = init() // is a map with 81 cells with keys Point and value '.'; The coordinates input by user are verificated in if-else statement if (fields.get(new Point(x, y)) == '.' && (getCharAt(x, y) == "0" || getCharAt(x, y) == "X")) programm put in the fields map the character ‘*’ at this coordinates. In parallel this coordinates are added in list guess. And programm do this while game is not finished. In my code if game is finished if ckecked by the method private static boolean checkIfFinished() {return points.equals(guess);} if this is true this answer go to boolean variables finished and while see that finished is true and show System.out.println("Congratulations! You found all mines!");

My problem is: when I introduce a number of mines bigger then 3 even if I set all mines and I know that points.equals(guess) the game return false and game continue. How to resolve this.

Answer

You need to fix checkIfFinished(). In your current case, you check also if the order of your points is the same, otherwise your game won’t finish.

private static boolean checkIfFinished() {
    if (points.size() != guess.size()) {
        return false;
    }
    for (Point point : guess) {
        if (!points.contains(point)) {
            return false;
        }
    }
    return true;
}


Source: stackoverflow