2011-08-25 2 views
6

私は自分のチェスエンジン(AIなし)をプログラムしようとしています。 私はChess Game Starter Kitがあることを知り、私はインスピレーションを開始するためにそれを見ました。チェスプログラミング(AIなし) - 検証移動

しかし、私が捕まえなかったのは、私の非キングピースのための確認された動きがどこで確認されないのですか?(here is moves validation)?

状況を想像してみて:
A5は - 対戦相手が
A4ルーク - 私の司教
A3を - 私の王

私がチェックすることになるだろうので、私は今、私の司教を移動することはできません。

この状況を確認するにはどうすればよいですか?

が与えられたボードの位置についてあなた

+0

あなたは、あなたがチェックしているので、動きが違法であることをどのように検証するのですか? – Kevin

+0

ああ、**リンクされた**コードがその特定の種類のバリデーションを行う場所を見つけ出すことを意味しますか? – AakashM

+0

はい、私はリンクされたコードを読んでいたので、これはどこにでも解決されるとは思いませんでした。 –

答えて

15

ありがとう、ほとんどのチェスエンジンは唯一の疑似法的動きを生成することから始めます。疑似法的なことで、私は動きがあっても生成されます意味:

  • がチェック
  • で王葉攻撃されている正方形を越えチェックに
  • 城の王を移動

この理由はパフォーマンスです。ベータプルーニングのために多くの動きが実際には検索されないため、移動の有効性の完全なチェックを避けることで時間を節約できます。

であるたびに、実際に有効であることを確認する必要があります。これは通常、王の色と四角形(および城の移動のために王の隣の四角形)をIsAttackedメソッドに渡すことによって行われます。そのメソッドがtrueを返す場合、移動が有効ではないことを知っているので、検索に含めるべきではありません。

これは、自分のC#チェスエンジンのメソッドです。これは、IsAttackedです。私のエンジンはmagic bitboardベースであることを覚えておいてください。リンクされたチェススターターキットにコードは直接適用されません。あなたが魔法のビットボードに精通していない限り、翻訳はささいなことではありません。

// IsAttacked is primarily used as a move legality test to see if a set of 
// one or more squares is under attack from the side to move. 
// It returns true as soon as an attack is detected, otherwise returns false. 
// It can be used for check detection, castling legality, or simply to 
// detect whether a specific square is attacked. 
internal bool IsAttacked(Board board, UInt64 targetSquares, bool whiteAttacking) 
{ 
    UInt64 slidingAttackers; Int32 targetSquare; 
    UInt64 remainingTargetSquares = targetSquares; 

    // Test for attacks by WHITE on any of the target squares. 
    if (whiteAttacking) 
    { 
     // For the remaining target squares... 
     while (remainingTargetSquares != 0) 
     { 
      // Find the next square in the list. 
      targetSquare = BitOperations.BitScanForward(remainingTargetSquares); 

      // Is this square attacked by a pawn, knight, or king? 
      if ((board.WhitePawns & Constants.BLACK_PAWN_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.WhiteKnights & Constants.KNIGHT_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.WhiteKing & Constants.KING_ATTACKS[targetSquare]) != 0) return true; 

      // Is this square attacked by a queen or rook along a file or rank? 
      slidingAttackers = board.WhiteQueens | board.WhiteRooks; 
      if (slidingAttackers != 0) 
      { 
       if (this.RankMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.FileMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // Is this square attacked by a queen or bishop along a diagonal? 
      slidingAttackers = board.WhiteQueens | board.WhiteBishops; 
      if (slidingAttackers != 0) 
      { 
       if (this.DiagonalA8H1Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.DiagonalA1H8Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // This square isn't attacked - remove and move on to next target square. 
      remainingTargetSquares ^= Constants.BITSET[targetSquare]; 
     } 
    } 

    // Test for attacks by BLACK on any of the target squares. 
    else 
    { 
     // For the remaining target squares... 
     while (remainingTargetSquares != 0) 
     { 
      // Find the next square in the list. 
      targetSquare = BitOperations.BitScanForward(remainingTargetSquares); 

      // Is this square attacked by a pawn, knight, or king? 
      if ((board.BlackPawns & Constants.WHITE_PAWN_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.BlackKnights & Constants.KNIGHT_ATTACKS[targetSquare]) != 0) return true; 
      if ((board.BlackKing & Constants.KING_ATTACKS[targetSquare]) != 0) return true; 

      // Is this square attacked by a queen or rook along a file or rank? 
      slidingAttackers = board.BlackQueens | board.BlackRooks; 
      if (slidingAttackers != 0) 
      { 
       if (this.RankMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.FileMoves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // Is this square attacked by a queen or bishop along a diagonal? 
      slidingAttackers = board.BlackQueens | board.BlackBishops; 
      if (slidingAttackers != 0) 
      { 
       if (this.DiagonalA8H1Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
       if (this.DiagonalA1H8Moves(board.OccupiedSquares, slidingAttackers, targetSquare) != 0) return true; 
      } 

      // This square isn't attacked - remove and move on to next target square. 
      remainingTargetSquares ^= Constants.BITSET[targetSquare]; 
     } 
    } 

    // None of the target squares are attacked. 
    return false; 
} 

ここでは白のための疑似法的キャスリングが動く生成するコードの断片です:

// If White can still castle kingside... 
if ((board.WhiteCastlingStatus & Board.EnumCastlingStatus.CanCastleOO) != 0) 
{ 
    // And the White kingside castling squares (F1/G1) aren't occupied... 
    if ((Constants.MASK_FG[Constants.WHITE_MOVE] & board.OccupiedSquares) == 0) 
    { 
     board.MoveBuffer[moveIndex++] = Constants.WHITE_CASTLING_OO; 
    } 
} 

// If White can still castle queenside... 
if ((board.WhiteCastlingStatus & Board.EnumCastlingStatus.CanCastleOOO) != 0) 
{ 
    // And the White queenside castling squares (D1/C1/B1) aren't occupied... 
    if ((Constants.MASK_BD[Constants.WHITE_MOVE] & board.OccupiedSquares) == 0) 
    { 
     board.MoveBuffer[moveIndex++] = Constants.WHITE_CASTLING_OOO; 
    } 
} 

をそしてここで擬似法的キャスリングの動きが実際に合法であるかどうかをチェックするコードがあります:

// Checks whether the King is moving from or into check. 
// Checks whether the King is moving across attacked squares. 
internal bool IsCastlingMoveLegal(Board board, Move move) 
{ 
    if (move.IsCastlingOO) 
    { 
     if (move.IsWhiteMove) 
     { 
      // Are any of the White kingside castling squares (E1/F1/G1) attacked? 
      return !this.IsAttacked(board, Constants.MASK_EG[Constants.WHITE_MOVE], false); 
     } 
     else 
     { 
      // Are any of the Black kingside castling squares (E8/F8/G8) attacked? 
      return !this.IsAttacked(board, Constants.MASK_EG[Constants.BLACK_MOVE], true); 
     } 
    } 
    else if (move.IsCastlingOOO) 
    { 
     if (move.IsWhiteMove) 
     { 
      // Are any of the White queenside castling squares (E1/D1/C1) attacked? 
      return !this.IsAttacked(board, Constants.MASK_CE[Constants.WHITE_MOVE], false); 
     } 
     else 
     { 
      // Are any of the Black queenside castling squares (E8/D8/C8) attacked? 
      return !this.IsAttacked(board, Constants.MASK_CE[Constants.BLACK_MOVE], true); 
     } 
    } 
    // Not a castling move! 
    else 
    { 
     Debug.Assert(false, "Not a castling move!"); 
     return true; 
    } 
} 
0

私のチェスプログラムには、フィールドが脅かされているかどうかをチェックする方法があります。王のための動きを計算するときに、そのフィールドが脅かされると、王が移動する可能性のあるすべてのフィールドをチェックします。

関連する問題