/// <summary> /// Unpack a packed board to a board /// </summary> /// <param name="packedBoard"> Packed board</param> /// <param name="peBoard"> Board array</param> public static void UnpackBoard(PackedBoard packedBoard, ChessBoard.PieceE[] peBoard) { UnpackBoardValue(packedBoard.m_lVal1, peBoard, 0); UnpackBoardValue(packedBoard.m_lVal2, peBoard, 16); UnpackBoardValue(packedBoard.m_lVal3, peBoard, 32); UnpackBoardValue(packedBoard.m_lVal4, peBoard, 48); }
/// <summary> /// Copy constructor /// </summary> /// <param name="moveHistory"> MoveHistory template</param> private MoveHistory(MoveHistory moveHistory) { m_iMoveCount = moveHistory.m_iMoveCount; m_iCountMoveDepth = moveHistory.m_iCountMoveDepth; m_iPackedBoardArraySize = moveHistory.m_iPackedBoardArraySize; m_arrPackedBoard = (PackedBoard[])moveHistory.m_arrPackedBoard.Clone(); m_arrHashCount = (byte[])moveHistory.m_arrHashCount.Clone(); m_arrCountMove = (short[])moveHistory.m_arrCountMove.Clone(); m_packedBoardCurrent = moveHistory.m_packedBoardCurrent; }
/// <summary> /// Gets the number of time this board is in the history (for the same color) /// </summary> /// <param name="board"> Board</param> /// <returns> /// Count /// </returns> private int GetBoardCount(PackedBoard board) { int iRetVal = 0; for (int iIndex = m_iMoveCount - 2; iIndex >= 0; iIndex -= 2) { if (IsTwoBoardEqual(board, m_arrPackedBoard[iIndex])) { iRetVal++; } } return(iRetVal); }
/// <summary> /// Determine if two boards are equal /// </summary> /// <param name="board1"> First board</param> /// <param name="board2"> Second board</param> /// <returns> /// true if equal, false if not /// </returns> private static bool IsTwoBoardEqual(PackedBoard board1, PackedBoard board2) { bool bRetVal; if (((board1.m_eInfo | board2.m_eInfo) & ChessBoard.BoardStateMaskE.EnPassant) != 0) { bRetVal = false; } else { bRetVal = (board1.m_eInfo == board2.m_eInfo && board1.m_lVal1 == board2.m_lVal1 && board1.m_lVal2 == board2.m_lVal2 && board1.m_lVal3 == board2.m_lVal3 && board1.m_lVal4 == board2.m_lVal4); } return(bRetVal); }
/// <summary> /// Add the current packed board to the history /// </summary> /// <param name="l64ZobristKey"> Zobrist key of the board</param> /// <param name="bPawnMoveOrPieceEaten"> true if a pawn has moved or a piece has been eaten</param> /// <returns> /// Result: NoRepeat, ThreeFoldRepeat or FiftyRuleRepeat /// </returns> public ChessBoard.RepeatResultE AddCurrentPackedBoard(long l64ZobristKey, bool bPawnMoveOrPieceEaten) { ChessBoard.RepeatResultE eRetVal = ChessBoard.RepeatResultE.NoRepeat; int iHashIndex; int iNewArraySize; byte count; PackedBoard[] arrNew; l64ZobristKey ^= (int)m_packedBoardCurrent.m_eInfo; if (m_iMoveCount >= m_iPackedBoardArraySize) { iNewArraySize = m_iPackedBoardArraySize * 2; arrNew = new PackedBoard[iNewArraySize]; Array.Copy(m_arrPackedBoard, arrNew, m_iPackedBoardArraySize); m_iPackedBoardArraySize = iNewArraySize; } iHashIndex = (int)(l64ZobristKey & 16383); count = ++m_arrHashCount[iHashIndex]; m_arrHashCount[iHashIndex] = count; if (bPawnMoveOrPieceEaten) { m_iCountMoveDepth++; m_arrCountMove[m_iCountMoveDepth] = 0; } else { if (++m_arrCountMove[m_iCountMoveDepth] >= 50) { eRetVal = ChessBoard.RepeatResultE.FiftyRuleRepeat; } else { // A count > 2 is only an indication that 3 or more identical board may exist // because 2 non-identical board can share the same slot if (count > 2 && GetBoardCount(m_packedBoardCurrent) >= 2) { eRetVal = ChessBoard.RepeatResultE.ThreeFoldRepeat; } } } m_arrPackedBoard[m_iMoveCount++] = m_packedBoardCurrent; return(eRetVal); }
//********************************************************* // /// <summary> /// Unpack a packed board to a board /// </summary> /// <param name="packedBoard"> Packed board</param> /// <param name="peBoard"> Board array</param> // //********************************************************* public static void UnpackBoard(PackedBoard packedBoard, ChessBoard.PieceE[] peBoard) { UnpackBoardValue(packedBoard.m_lVal1, peBoard, 0); UnpackBoardValue(packedBoard.m_lVal2, peBoard, 16); UnpackBoardValue(packedBoard.m_lVal3, peBoard, 32); UnpackBoardValue(packedBoard.m_lVal4, peBoard, 48); }
//********************************************************* // /// <summary> /// Compute the current packed representation of a board /// </summary> /// <param name="peBoard"> Board array</param> /// <param name="eInfo"> Board extra info</param> // //********************************************************* private void ComputeCurrentPackedBoard(ChessBoard.PieceE[] peBoard, ChessBoard.BoardStateMaskE eInfo) { m_packedBoardCurrent = ComputePackedBoard(peBoard, eInfo); }
//********************************************************* // /// <summary> /// Add the current packed board to the history /// </summary> /// <param name="l64ZobristKey"> Zobrist key of the board</param> /// <param name="bPawnMoveOrPieceEaten"> true if a pawn has moved or a piece has been eaten</param> /// <returns> /// Result: NoRepeat, ThreeFoldRepeat or FiftyRuleRepeat /// </returns> // //********************************************************* public ChessBoard.RepeatResultE AddCurrentPackedBoard(long l64ZobristKey, bool bPawnMoveOrPieceEaten) { ChessBoard.RepeatResultE eRetVal = ChessBoard.RepeatResultE.NoRepeat; int iHashIndex; int iNewArraySize; byte count; PackedBoard[] arrNew; l64ZobristKey ^= (int)m_packedBoardCurrent.m_eInfo; if (m_iMoveCount >= m_iPackedBoardArraySize) { iNewArraySize = m_iPackedBoardArraySize * 2; arrNew = new PackedBoard[iNewArraySize]; Array.Copy(m_arrPackedBoard, arrNew, m_iPackedBoardArraySize); m_iPackedBoardArraySize = iNewArraySize; } iHashIndex = (int)(l64ZobristKey & 16383); count = ++m_arrHashCount[iHashIndex]; m_arrHashCount[iHashIndex] = count; if (bPawnMoveOrPieceEaten) { m_iCountMoveDepth++; m_arrCountMove[m_iCountMoveDepth] = 0; } else { if (++m_arrCountMove[m_iCountMoveDepth] >= 50) { eRetVal = ChessBoard.RepeatResultE.FiftyRuleRepeat; } else { // A count > 2 is only an indication that 3 or more identical board may exist // because 2 non-identical board can share the same slot if (count > 2 && GetBoardCount(m_packedBoardCurrent) >= 2) { eRetVal = ChessBoard.RepeatResultE.ThreeFoldRepeat; } } } m_arrPackedBoard[m_iMoveCount++] = m_packedBoardCurrent; return(eRetVal); }
//********************************************************* // /// <summary> /// Gets the number of time this board is in the history (for the same color) /// </summary> /// <param name="board"> Board</param> /// <returns> /// Count /// </returns> // //********************************************************* private int GetBoardCount(PackedBoard board) { int iRetVal = 0; for (int iIndex = m_iMoveCount - 2; iIndex >= 0; iIndex -= 2) { if (IsTwoBoardEqual(board, m_arrPackedBoard[iIndex])) { iRetVal++; } } return(iRetVal); }
//********************************************************* // /// <summary> /// Determine if two boards are equal /// </summary> /// <param name="board1"> First board</param> /// <param name="board2"> Second board</param> /// <returns> /// true if equal, false if not /// </returns> // //********************************************************* private bool IsTwoBoardEqual(PackedBoard board1, PackedBoard board2) { bool bRetVal; if (((board1.m_eInfo | board2.m_eInfo) & ChessBoard.BoardStateMaskE.EnPassant) != 0) { bRetVal = false; } else { bRetVal = (board1.m_eInfo == board2.m_eInfo && board1.m_lVal1 == board2.m_lVal1 && board1.m_lVal2 == board2.m_lVal2 && board1.m_lVal3 == board2.m_lVal3 && board1.m_lVal4 == board2.m_lVal4); } return(bRetVal); }
/// <summary> /// Compute the current packed representation of a board /// </summary> /// <param name="peBoard"> Board array</param> /// <param name="eInfo"> Board extra info</param> private void ComputeCurrentPackedBoard(ChessBoard.PieceE[] peBoard, ChessBoard.BoardStateMaskE eInfo) { m_packedBoardCurrent = ComputePackedBoard(peBoard, eInfo); }