2015-05-02 2 views
0

Я пытаюсь создать настольную игру, где все части могут перемещаться так же, как ладья в шахматы. (то есть по горизонтали или по вертикали как можно больше пробелов)Программирование Chess Rook Movement

Моя доска представляет собой простой массив из 2-х целых чисел со значениями 0,1,2 в зависимости от того, пустое ли пространство, красная часть или черная часть.

Мой код для движения до сих пор показано ниже, это создает истинное или ложное значение, если движение разрешено или нет:

int[][] board; 

public boolean validMove(int fromRow, int fromCol, int toRow, int toCol) { 
    if(pieceAt(toRow, toCol) != EMPTY) { 
     return false; 
    } 
    else if(fromRow - toRow == 0 && fromCol - toCol != 0) { 
     return true; 
    } 
    else if(fromCol - toCol == 0 && fromRow - toRow != 0) { 
     for(int i = fromRow; i < toRow; i++) { // Trying to add piece collision code 
      if(pieceAt(toCol, i) != EMPTY) return false; // Trying to add piece collision code 
     } 
     return true; 
    } 
    else return false; 
} 

Моя проблема пытается создать обнаружение столкновений, если другой кусок в способе, которым он не сможет пройти мимо него, однако с моим кодом в настоящее время он может. Может ли кто-нибудь помочь мне сделать это?

ответ

1

Попробуйте код ниже. Это довольно наивно (а также не проверено), но я думаю, что он должен работать так же, как есть. А также я думаю, что это очень хорошо иллюстрирует эту идею (см. Комментарии). Он находится на C, но я уверен, что вы можете легко преобразовать его в Java (или на любой язык, который вы используете).

bool validMove(int fromRow, int fromCol, int toRow, int toCol) 
{ 
    int i; 

    // Attempt to move to the same cell 
    if (fromRow == toRow && fromCol == toCol) 
     return false; 

    // Collision detection 
    if (fromRow == toRow) { 
     // Horizontal move 
     if (fromCol < toCol) { 
      // Move right 
      for (i = fromCol + 1; i <= toCol; ++i) 
       if (pieceAt(fromRow, i) != EMPTY) 
        return false; 
     } else { 
      // Move left 
      for (i = fromCol - 1; i >= toCol; --i) 
       if (pieceAt(fromRow, i) != EMPTY) 
        return false; 
     } 
    } else if (fromCol == toCol) { 
     // Vertical move 
     if (fromRow < toRow) { 
      // Move down 
      for (i = fromRow + 1; i <= toRow; ++i) 
       if (pieceAt(i, fromCol) != EMPTY) 
        return false; 
     } else { 
      // Move up 
      for (i = fromRow - 1; i >= toRow; --i) 
       if (pieceAt(i, fromCol) != EMPTY) 
        return false; 
     } 
    } else { 
     // Not a valid rook move (neither horizontal nor vertical) 
     return false; 
    } 

    return true; 
} 

EDIT

Вы также можете оптимизировать код за счет уменьшения conditional statement счета, используя метод, предложенный Toon Krijthe. Основная идея заключается в использовании значений «delta» (dx/dy) для увеличения или уменьшения индексов ячеек. В этом случае ячейка адресата должна быть явно указана.

Код:

bool validMove(int fromRow, int fromCol, int toRow, int toCol) 
{ 
    int i; 

    // Attempt to move to the same cell 
    if (fromRow == toRow && fromCol == toCol) 
     return false; 

    // Check if destination cell is free 
    if (pieceAt(toRow, toCell) != EMPTY) 
     return false; 

    // Collision detection 
    if (fromRow == toRow) { // Horizontal move 
     int dx = (fromCol < toCol) ? 1 : -1; 

     for (i = fromCol + dx; i != toCol; i += dx) 
      if (pieceAt(fromRow, i) != EMPTY) 
       return false; 

    } else if (fromCol == toCol) { // Vertical move 
     int dy = (fromRow < toRow) ? 1 : -1; 

     for (i = fromRow + dy; i != toRow; i += dy) 
      if (pieceAt(i, fromCol) != EMPTY) 
       return false; 
    } else { // Not a valid rook move 
     return false; 
    } 

    return true; 
} 
0

у вас может быть двумерная матрица с каждой ячейкой, представляющей позицию на доске. там вы можете иметь символ для трех состояний позиции (белый/красный/пустой).

Другой способ, о котором я могу думать, - это перед каждым движением проверять с началаPosition, пока endPosition не позиционирует свои состояния. но производительность мудрая я думаю, что какой-то массив будет намного лучше

0

Вы можете просто «прогулка» каждое поле, чтобы проверить, если он пуст. Например:

int[][] board; 

public boolean validMove(int fromRow, int fromCol, int toRow, int toCol) 
{ 
    if (pieceAt(toRow, toCol) != EMPTY) return false; 
    else if (fromRow == toRow) 
    { 
    // horizontal move 
    if (fromCol == toCol) return false; // same position 
    int dx, x; 
    if (fromCol < toCol) 
     dx = 1; 
    else 
     dx = -1; 

    for (x = fromCol + dx; x != toCol; x += dx) 
    { 
     if (pieceAt(toRow, x) != EMPTY) return false; // occupied 
    } 
    } 
    else if (fromCol == toCol) 
    { 
    // vertical move 
    int dy, y; 
    if (fromRow < toRow) 
     dy = 1; 
    else 
     dy = -1; 

    for (y = fromRow + dy; y != toRow; y += dy) 
    { 
     if (pieceAt(y, toCol) != EMPTY) return false; // occupied 

     return true; // free path 
    } 
    } 
    else return false; // no horizontal or vertical move 

}

+0

В условиях вашего 'for' Loops': Я думаю, вы должны заменить' х = (токол-ах) 'с' х = toCol'!. То же самое относится ко второму циклу. '! =' уже отменяет проверку для ячейки назначения. Выполнение таких вещей, как 'x! = (ToCol-dx)', является ошибкой: он будет пропускать одну ячейку из проверки. –

+0

Непонятно, можете ли вы взять любую деталь. Кроме того, вопрос заключался в том, как определить, есть ли части между ними, поэтому я пропустил ячейку назначения. –

+0

Выполнение 'x! = (ToCol-dx)' вы пропускаете не только ячейку назначения, но и ячейку рядом с ней. Чтобы пропустить ячейку назначения, вы должны сделать 'x! = ToCol'. Например, этот код: 'for (i = 1; i! = 5 - 1; i ++)' будет проверять только 1-й, 2-й и 3-й элементы. Кроме того, вы не пропустили ячейку назначения, она проверяется этой строкой в ​​вашем коде: 'if (pieceAt (toRow, toCol)! = EMPTY) возвращает false;' –