Если заявления не работают, как задумано

По сути, в настоящее время я пытаюсь сделать реверси-игру для Android, и мои операторы if вызывают у меня небольшую головную боль, кажется, что если условия подходят для более чем одного, то это только прохождение одного из утверждений и просто уход другой. Мой код выглядит так:

if (check[position] == 0
                            && (check[position - 8] == 2
                                    || check[position + 8] == 2
                                    || check[position + 1] == 2
                                    || check[position - 1] == 2
                                    || check[position - 9] == 2
                                    || check[position + 9] == 2
                                    || check[position - 7] == 2 || check[position + 7] == 2)) {

                        if (check[position + 8] == 2) {
                            for (int i = position; i < 56; i += 8) {
                                if (check[i] == 1) {
                                    for (int j = position; j < i; j += 8) {
                                        check[j] = 1;
                                    }
                                    playerno = 2;
                                    break;
                                } else
                                    break;
                            }
                        } else if (check[position - 8] == 2) {
                            for (int i = position; i > 8; i -= 8) {
                                if (check[i] == 1) {
                                    for (int j = position; j > i; j -= 8) {
                                        check[j] = 1;
                                    }
                                    playerno = 2;
                                    break;
                                } else
                                    break;
                            }
                        } else if (check[position + 1] == 2) {
                            for (int i = position; i < board.length; i++) {
                                if (check[i] == 1) {
                                    for (int j = position; j < i; j++) {
                                        check[j] = 1;
                                    }
                                    playerno = 2;
                                    break;
                                }
                                if (i == 7 || i == 15 || i == 23 || i == 31
                                        || i == 39 || i == 47 || i == 55
                                        || i == 63) {
                                    break;
                                }
                            }
                        } else if (check[position - 1] == 2) {
                            for (int i = position; i > 0; i--) {
                                if (check[i] == 1) {
                                    for (int j = position; j > i; j--) {
                                        check[j] = 1;
                                    }
                                    playerno = 2;
                                    break;
                                }
                                if (i == 0 || i == 8 || i == 16 || i == 24
                                        || i == 32 || i == 40 || i == 48
                                        || i == 56) {
                                    break;
                                }
                            }
                        }

Check - это просто массив int, который отмечает, какой игрок держит этот конкретный фрагмент на доске. Теперь по какой-то причине, если у меня есть позиция, которая удовлетворяет двум из этих условий, он проходит только через одно из выражений if, и чаще всего это приводит к игре. рассматривая это как недействительный ход, мне было интересно, как я могу обойти это?

3 ответа

если у меня есть позиция, которая удовлетворяет двум из этих условий, она проходит только через одно из операторов if

Вы имеете в виду это утверждение?

if (conditionA) {
  BlockA
} else if (conditionB) {
  BlockB
}  else if (conditionC) {
  BlockC
}  else if (conditionD) {
  BlockD
}

Если вы это сделаете, неудивительно, что выполняется только один из блоков if. Только блок первого условия оценивается как true выполнен.

Если вы хотите разрешить выполнение более одного блока, измените его на:

if (conditionA) {
  BlockA
} 
if (conditionB) {
  BlockB
} 
if (conditionC) {
  BlockC
}
if (conditionD) {
  BlockD
}

AlexR прав, ваша логика слишком запутанная, а форматирование делает ваш код чрезвычайно трудным для чтения, что затрудняет его отладку.

Я не собираюсь решать все за вас, но вот некоторые предлагаемые изменения. Главным образом, вы должны разбить свою логику на куски размером с укус.

Редактировать: согласно моему комментарию выше, реализовать доску как класс:

class Board {
    private final int[] check = new int[BOARD_WIDTH*BOARD_HEIGHT];
    public Board() { for (int i=0; i < BOARD_WIDTH*BOARD_HEIGHT; check[i++] = 0); }
    public final int get(int x, int y) { return check[y*BOARD_WIDTH + x]; }
    public final void set(int x, int y, int val) { check[y*BOARD_WIDTH+x] = val; }

    /**
     * Return true if this square is free
     */
    public final boolean isFree(int x, int y) {
      if (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) return false;
      int position = y*BOARD_WIDTH + x;
      return check[position] == 0;
    }

    /**
     * Return true if this square is occupied by opponent
     */
    public final boolean isOccupiedBy2(int x, int y) {
      if (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) return false;
      int position = y*BOARD_WIDTH + x;
      return check[position] == 2;
    }

    /**
     * Return true if any neighboring square is occupied by opponent
     */
    final boolean isNeighborOccupied(int x, int y) {
      for (int i=x-1; i >= x+1; ++i)
        for (int j=y-1; j >= y+1; ++j)
          if ((i != x || j != y) && isOccupiedBy2(i,j)) return true;
      return false;
    }
    // etc.
}

Теперь переписайте свою логику выше:

if (board.isFree(x,y) && board.isNeighborOccupied(x,y)) {
    if (board.isOccupiedBy2(x,y+1)) {
        ...
    }
    else if (board.isOccupiedBy2(x,y-1)) {
        ...
    }
    else if (board.isOccupiedBy2(x+1,y)) {
        ...
    }
    else if (board.isOccupiedBy2(x-1,y)) {
        ...
    }
}

Видите, насколько легче это читать? Это будет намного легче отлаживать.

Наконец, посмотрите, не является ли сообщение Эрана вашей ошибкой. Только одно из этих четырех условий будет выполнено. Поскольку вы тестируете только четыре из восьми соседних квадратов, я предполагаю, что вы имели в виду тестирование вверх, влево, вниз, вправо, поэтому, возможно, второе "другое" было ошибкой.

Во-первых, ваши условия чрезвычайно сложны и трудны для чтения. Попробуйте упростить их. Попробуйте разделить одно сложное условие на несколько простых выражений. И использовать отладчик.

Другие вопросы по тегам