2011-08-25 23 views
6

मैं अपने स्वयं के शतरंज इंजन (कोई एआई) प्रोग्राम करने की कोशिश कर रहा हूं। मुझे पता है कि Chess Game Starter Kit है और मैंने इसे प्रेरणा प्रेरणा के लिए देखा है।शतरंज प्रोग्रामिंग (कोई एआई) - मान्यता

लेकिन जो मैंने नहीं पकड़ा वह मेरे गैर-राजा टुकड़ों को जांचने से रोकने के लिए मान्य चाल (here is moves validation) कहां है?

स्थिति की कल्पना कीजिए:
A5 - विरोधियों किश्ती
ए 4 - मेरे बिशप
A3 - मेरा राजा

अब मैं अपने बिशप स्थानांतरित नहीं कर सकते के बाद से मैं जाँच करने के लिए मिलेगा।

या आप इस स्थिति की जांच करने के लिए कैसे सुझाव देंगे?

आप

+0

आपका मतलब है कि आप कैसे वैध हैं कि एक चाल अवैध है क्योंकि ऐसा करने से यह आपको चेक में डाल देता है? – Kevin

+0

ओह, आपका मतलब है कि आप काम करना चाहते हैं कि ** लिंक ** ** उस विशेष प्रकार की सत्यापन कहां करता है? – AakashM

+0

हां, जैसा कि मैं लिंक कोड पढ़ रहा था, मैंने नहीं पकड़ा यह कहीं भी हल किया जाएगा। –

उत्तर

15

धन्यवाद किसी दिए गए बोर्ड स्थिति के लिए, सबसे शतरंज इंजन केवल छद्म वैध चालों उत्पन्न करके शुरू करते हैं। छद्म कानूनी रूप से, मेरा मतलब है एक कदम उत्पन्न हो जाएगा, भले ही वह:

  • जांच
  • में राजा छोड़ देता है वर्गों कि हमला किया जा रहा भर में
  • महल की जांच में राजा चालें

इसका कारण प्रदर्शन है। बीटा छंटनी के कारण वास्तव में कई चालों की खोज नहीं की जाएगी, आप चाल वैधता की पूरी जांच से बचकर समय बचाते हैं।

प्रत्येक चाल के लिए खोजा गया है, आपको यह जांचना होगा कि यह वास्तव में मान्य है। यह आमतौर पर IsAttacked विधि में किंग के रंग और वर्ग (और किंग के आगे किंग के आगे वर्ग) को पार करके किया जाता है। यदि वह विधि सत्य हो जाती है, तो आप जानते हैं कि चाल मान्य नहीं है और इसलिए आपको इसे अपनी खोज में शामिल नहीं करना चाहिए।

यह है IAttacked विधि अपने स्वयं के सी # शतरंज इंजन से। ध्यान रखें कि मेरा इंजन magic bitboard-आधारित है, इसलिए कोड सीधे आपके द्वारा लिंक किए गए शतरंज स्टार्टर किट पर लागू नहीं होगा। जब तक आप जादू बिटबोर्ड से परिचित न हों, अनुवाद छोटा नहीं होगा।

// 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; 
    } 
} 

और यहाँ कोड है कि क्या एक छद्म कानूनी कैसलिंग कदम की जाँच करता है है है वास्तव में कानूनी:

// 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; 
} 

यहाँ कोड का एक टुकड़ा है कि व्हाइट के लिए छद्म कानूनी कैसलिंग चाल उत्पन्न करता है

// 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

मेरे शतरंज कार्यक्रम में एक विधि है जो जांचती है कि क्या फ़ील्ड को धमकी दी जाती है। राजा के लिए चाल की गणना करते समय यह उस क्षेत्र को देखता है जब राजा उस क्षेत्र को धमकी दे सकता है।

संबंधित मुद्दे