//********************************************************* // /// <summary> /// Create a new game using the specified list of moves /// </summary> /// <param name="chessBoardStarting"> Starting board or null if standard board</param> /// <param name="listMove"> List of moves</param> /// <param name="eStartingColor"> Board starting color</param> // //********************************************************* public void CreateGameFromMove(ChessBoard chessBoardStarting, List<MovePosS> listMove, PlayerColorE eStartingColor) { BoardStateMaskE eMask; if (chessBoardStarting != null) { CopyFrom(chessBoardStarting); eMask = chessBoardStarting.ComputeBoardExtraInfo(PlayerColorE.White, false); ResetInitialBoardInfo(eStartingColor, false, eMask, chessBoardStarting.m_iPossibleEnPassantAt); } else { ResetBoard(); } foreach (MovePosS movePos in listMove) { DoMove(movePos); } }
//********************************************************* // /// <summary> /// Alpha Beta pruning function. /// </summary> /// <param name="chessBoard"> Chess board</param> /// <param name="ePlayerColor"> Color doing the move</param> /// <param name="iDepth"> Actual search depth</param> /// <param name="iAlpha"> Alpha limit</param> /// <param name="iBeta"> Beta limit</param> /// <param name="iWhiteMoveCount"> Number of moves white can do</param> /// <param name="iBlackMoveCount"> Number of moves black can do</param> /// <param name="abInfo"> Supplemental information</param> /// <returns> /// Points to give for this move or Int32.MinValue for timed out /// </returns> // //********************************************************* private int AlphaBeta(ChessBoard chessBoard, ChessBoard.PlayerColorE ePlayerColor, int iDepth, int iAlpha, int iBeta, int iWhiteMoveCount, int iBlackMoveCount, AlphaBetaInfo abInfo) { int iRetVal; List<ChessBoard.MovePosS> moveList; int iPts; int iMoveCount; int iAttackedPos; int iAttackedPieces; TransEntryTypeE eType = TransEntryTypeE.Alpha; ChessBoard.BoardStateMaskE eBoardExtraInfo; ChessBoard.RepeatResultE eResult; if (abInfo.m_dtTimeOut != DateTime.MaxValue && DateTime.Now >= abInfo.m_dtTimeOut) { iRetVal = Int32.MinValue; // Time out! } else if (chessBoard.IsEnoughPieceForCheckMate()) { eBoardExtraInfo = chessBoard.ComputeBoardExtraInfo(ePlayerColor, true); iRetVal = (abInfo.m_transTable != null) ? abInfo.m_transTable.ProbeEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iAlpha, iBeta) : Int32.MaxValue; if (iRetVal == Int32.MaxValue) { if (iDepth == 0 || m_bCancelSearch) { if (ePlayerColor == ChessBoard.PlayerColorE.White) { iAttackedPos = abInfo.m_iAttackedPos; iAttackedPieces = abInfo.m_iAttackedPieces; } else { iAttackedPos = -abInfo.m_iAttackedPos; iAttackedPieces = -abInfo.m_iAttackedPieces; } iRetVal = (ePlayerColor == ChessBoard.PlayerColorE.Black) ? -chessBoard.Points(abInfo.m_searchMode, ePlayerColor, iWhiteMoveCount - iBlackMoveCount, iAttackedPos, iAttackedPieces) : chessBoard.Points(abInfo.m_searchMode, ePlayerColor, iWhiteMoveCount - iBlackMoveCount, iAttackedPos, iAttackedPieces); abInfo.m_iPermCount++; if (abInfo.m_transTable != null) { abInfo.m_transTable.RecordEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, TransEntryTypeE.Exact); } } else { moveList = chessBoard.EnumMoveList(ePlayerColor, true, out abInfo.m_iAttackedPos, out abInfo.m_iAttackedPieces); iMoveCount = moveList.Count; if (ePlayerColor == ChessBoard.PlayerColorE.White) { iWhiteMoveCount = iMoveCount; } else { iBlackMoveCount = iMoveCount; } if (iMoveCount == 0) { if (chessBoard.IsCheck(ePlayerColor)) { iRetVal = -1000000 - iDepth; } else { iRetVal = 0; // Draw } if (abInfo.m_transTable != null) { abInfo.m_transTable.RecordEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, TransEntryTypeE.Exact); } } else { iRetVal = iAlpha; foreach (ChessBoard.MovePosS move in moveList) { eResult = chessBoard.DoMoveNoLog(move); abInfo.m_arrMovePos[iDepth - 1] = move; if (eResult == ChessBoard.RepeatResultE.NoRepeat) { iPts = -AlphaBeta(chessBoard, (ePlayerColor == ChessBoard.PlayerColorE.Black) ? ChessBoard.PlayerColorE.White : ChessBoard.PlayerColorE.Black, iDepth - 1, -iBeta, -iRetVal, iWhiteMoveCount, iBlackMoveCount, abInfo); } else { iPts = 0; } chessBoard.UndoMoveNoLog(move); if (iPts == Int32.MinValue) { iRetVal = iPts; break; } else { if (iPts > iRetVal) { iRetVal = iPts; eType = TransEntryTypeE.Exact; } if (iRetVal >= iBeta) { iRetVal = iBeta; eType = TransEntryTypeE.Beta; break; } } } if (abInfo.m_transTable != null && iRetVal != Int32.MinValue) { abInfo.m_transTable.RecordEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, eType); } } } } } else { iRetVal = 0; } return(iRetVal); }