Неверный алгоритм случайной генерации мин сапером

Знаю, знаю. Это спрашивали много раз. Я не ищу алгоритм. Я думаю, что мой алгоритм не работает должным образом.

Вот алгоритм, который я использую:

public void onFirstMove (int moveX, int moveY) {
    setFirstMove (false);
    Random r = new Random ();

    for (int i = 0 ; i < 10 ; i++) {
        int x;
        int y;
        do {
            x = r.nextInt (9);
            y = r.nextInt (9);
        } while (tileMatrix[x][y].hasMine () &&
                moveX == x && moveY == y);

        tileMatrix[x][y].setMine ();
    }

    timer.startTimer ();
}

Я поместил его в метод onFirstMove, потому что не хочу, чтобы игрок проигрывал на первом ходу. Как видите, я заставил его продолжать попытки найти координаты x и y, пока они совпадают с позицией первого хода.

while (tileMatrix[x][y].hasMine () &&
                moveX == x && moveY == y);

И теперь у него есть 2 известные ошибки:

  1. Иногда он генерирует 9 мин вместо 10. Я знаю это, потому что когда я проигрываю, он показывает, где все мины.

  2. Иногда он действительно создает мину в позиции первого хода.


person Sweeper    schedule 15.08.2015    source источник
comment
Для заинтересованных сторон я решил этот первый XD chat.stackoverflow.com/transcript/message/25104533#25104533   -  person xrisk    schedule 15.08.2015


Ответы (2)


Ошибка в вашем состоянии while. Так должно быть:

while (tileMatrix[x][y].hasMine () ||    // OR not AND
                (moveX == x && moveY == y));
person xashru    schedule 15.08.2015

Я согласен с ответом xashru (1+ к нему). Лично я бы использовал список, добавил все плитки в список, кроме плитки с первым ходом, перетасовал их, а затем выбрал первые N плиток (N - количество мин) и установил мины. например, что-то вроде:

public void onFirstMove (int moveX, int moveY) {
    setFirstMove (false);

    // assuming your tiles are of type Tile
    List<Tile> tileList = new ArrayList<>();
    for (int x = 0; x < MAX_X; x++) {
        for (int y = 0; y < MAX_Y; y++) {
            if (x != moveX || x != moveY) {
                // add all tile's except the first move
                tileList.add(tileMatrix[x][y]);
            }
        }
    }

    // randomize the collection
    java.util.Collections.shuffle(tileList);

    // set MAX_MINES tiles to have mines
    for (int i = 0; i < MAX_MINES; i++) {
        tileList.get(0).setMine();
    }
    timer.startTimer();
}

Чтобы узнать больше о MineSweeper, посмотрите мой код и ответьте на этот вопрос о MineSweeper.

person Hovercraft Full Of Eels    schedule 15.08.2015