需要帮助实现en passant Pawn捕获和促销

时间:2014-07-10 21:42:12

标签: java chess

我正在制作一个国际象棋游戏,并且能够使我的Pawn棋子向前移动一个和两个方格,防止它在第一次移动后向前移动两个方格。此外,Pawn Piece能够对角地捕捉棋子,但不会执行enpassant捕捉和典当推广。对于典当促销,我需要一个关于如何在其targetRow == 0或7时将棋子与另一个棋子交换的想法。如果有人可以帮助我了解如何实现这两个功能的逻辑或想法,我将不胜感激。

这是我的代码:

    private boolean isValidPawnMove(int sourceRow, int sourceColumn, int targetRow, int   
    targetColumn){

    boolean isValid = false;

    if(isTargetLocationFree()){

        if(sourceColumn == targetColumn){
            //same column
            if(sourcePiece.getColor() == Piece.YELLOW_COLOR){
                //yellow
                if(sourceRow + 1 == targetRow ){
                    //move one up
                    isValid = true;

                }else if(sourceRow == 1 && targetRow == 3){
                    if(sourceRow + 2 == targetRow) {
                    isValid = true;
                    }                   
                }else{
                    //not moving one up
                    isValid = false;
                }

            }else{
                //brown
                if(sourceRow - 1 == targetRow){
                    //move one down
                    isValid = true;

                }else if(sourceRow == 6 && targetRow == 4){
                    if(sourceRow - 2 == targetRow) {
                       isValid = true;
                    }
                }else{
                    //not moving one down
                    isValid = false;
                }                   
            }
        }else{
            //not the same column
            isValid = false;
        }
    }else if(isTargetLocationCaptureable()){

        if(sourceColumn + 1 == targetColumn || sourceColumn - 1 == targetColumn ){
            //one column to the right or left
            if(sourcePiece.getColor() == Piece.YELLOW_COLOR){
                //yellow
                if(sourceRow + 1 == targetRow){
                    //move one up
                    isValid = true;
                }else{

                    //not moving one up
                    isValid = false;
                }
            }else{
                //brown
                if(sourceRow - 1 == targetRow ){
                    //move one down
                    isValid = true;
                }else{
                    //not moving one down                       
                    isValid = false;
                }
            }
        }else{
            //One column to the left or right
            isValid = false;
        }   
    }

        return isValid;
}

private boolean isTargetLocationCaptureable(){
if(targetPiece == null){
    return false;
}else if( targetPiece.getColor() != sourcePiece.getColor()){
    return true;
}else{
    return false;
}
}

private boolean isTargetLocationFree(){
return targetPiece == null;
}

4 个答案:

答案 0 :(得分:3)

有许多国际象棋动作,其验证需要更多当前的董事会状态。在您的情况下,我没有看到验证以下动作所需的其他信息。

  • Castling:需要涉及车和国王的历史。可以通过hasMovedBefore标志来完成。
  • en Passant:了解最后采取的行动。可以通过保留lastMove数据结构或保留以前的板状态来适应。
  • 五十步行规则:需要最后一次捕获或典当移动的历史记录。可以通过lastPawnMoveOrCapture计数器
  • 完成
  • 三倍重复:要求自上次城堡,典当移动或捕获以来所有以前的棋盘状态。可以选择先前状态的哈希列表。 (谢谢dfeuer)

答案 1 :(得分:0)

移动到最后一行/第一行仍然需要是一个有效的移动,所以我会在“return isValid;”之前处理这一部分。这样你就可以使用isValid布尔值。

if(isValid && sourcePiece.getColor()==Piece.YELLOW_COLOR && targetRow==0){
//change targetRow,targetColumn to a queen or Piece.Type = "Queen" or however you have it setup
}

我认为你不需要在国际象棋规则中用一个被捕获的棋子“交换”这件作品。你可以在棋盘上有两个皇后。玩家可能想要的另一件(罕见)是车。我没有玩家选择会值得你的时间。

答案 2 :(得分:0)

' en passant'捕获有点棘手,你必须跟踪前一个对手的移动,并且当且仅当对手棋子移动了2个方格并且现在有列=你的pawn列+或 - 1,并且row =你的pawn行,那么移动到对手的行列和行+ 1(或黑色的-1)是允许的,它将捕获对手的棋子。你不需要检查目的地广场是否为空,因为对手的棋子刚刚移动了2个方格,它是。

升级是直截了当的,如果新行是0或7,那么pawn必须成为一块,你只需要一个用户界面供玩家选择,但你的算法已经将这些noves返回为有效。

对于现有代码,可能更容易阅读:

private boolean isValidPawnMove(int sourceRow, int sourceColumn, 
                                int targetRow, int targetColumn) {
    int startRow;
    int direction;
    if (sourcePiece.getColor() == Piece.YELLOW_COLOR) {
      startRow = 1;
      directon = 1;
    } else {
      startRow = 6;
      directon = -1;
    }
    if (isTargetLocationFree() && sourceColumn == targetColumn) {
      return (targetRow == sourceRow + direction) ||
             (sourceRow == startRow && targetRow == startRow + 2 * direction);
    }
    if (isTargetLocationCaptureable()) {
      return ((targetColumn == sourceColumn + 1 || targetColumn == sourceColumn - 1 ))
              && (targetRow == sourceRow + direction);
    }
    return false;
}


注意:我假设所有输入变量都已经有效,并且您没有拐角情况,例如targetColumn = -1。

答案 3 :(得分:0)

我对enpassant捕获的建议:

  • 当一个棋子向前移动两行时,让它分成两个棋子。 "真实"移动两行并具有常规颜色(黄色或棕色)的pawn,以及一个" ghost" pawn只移动一行并具有不同的颜色(浅黄色或浅棕色)。

  • 黄色球员移动后,清除棋盘上的所有浅棕色棋子(并在棕色球员移动后对淡黄色棋子做同样的操作)。

  • 在isTargetLocationFree()中,忽略淡黄色和浅棕色的棋子。

  • 在isTargetLocationCaptureable()中,如果目标部分是黄色棋子,如果目标位置的部分是棕色或浅棕色,则返回true。否则,仅当目标位置的部分为棕色时才返回true。做类似检查棕色片。

  • 最后,如果pawn捕获了一个" ghost" pawn,请务必删除相应的" real"董事会的典当。