Пример #1
0
        /// <summary>
        /// Alpha Beta pruning function.
        /// </summary>
        /// <param name="board">            Chess board</param>
        /// <param name="ePlayer">          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 board,
                              ChessBoard.PlayerE ePlayer,
                              int iDepth,
                              int iAlpha,
                              int iBeta,
                              int iWhiteMoveCount,
                              int iBlackMoveCount,
                              AlphaBetaInfo abInfo)
        {
            int         iRetVal;
            List <Move> moveList;
            int         iPts;
            int         iMoveCount;

            ChessBoard.PosInfoS posInfo;
            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 (board.IsEnoughPieceForCheckMate())
            {
                eBoardExtraInfo = board.ComputeBoardExtraInfo(ePlayer, true);
                iRetVal         = (abInfo.m_transTable != null) ? abInfo.m_transTable.ProbeEntry(board.CurrentZobristKey, eBoardExtraInfo, iDepth, iAlpha, iBeta) : Int32.MaxValue;
                if (iRetVal == Int32.MaxValue)
                {
                    if (iDepth == 0 || m_bCancelSearch)
                    {
                        iRetVal = board.Points(abInfo.m_searchMode, ePlayer, abInfo.m_iMaxDepth - iDepth, iWhiteMoveCount - iBlackMoveCount, abInfo.m_posInfoWhite, abInfo.m_posInfoBlack);
                        if (ePlayer == ChessBoard.PlayerE.Black)
                        {
                            iRetVal = -iRetVal;
                        }
                        abInfo.m_iPermCount++;
                        if (abInfo.m_transTable != null)
                        {
                            abInfo.m_transTable.RecordEntry(board.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, TransEntryTypeE.Exact);
                        }
                    }
                    else
                    {
                        moveList   = board.EnumMoveList(ePlayer, true, out posInfo);
                        iMoveCount = moveList.Count;
                        if (ePlayer == ChessBoard.PlayerE.White)
                        {
                            iWhiteMoveCount       = iMoveCount;
                            abInfo.m_posInfoWhite = posInfo;
                        }
                        else
                        {
                            iBlackMoveCount       = iMoveCount;
                            abInfo.m_posInfoBlack = posInfo;
                        }
                        if (iMoveCount == 0)
                        {
                            if (board.IsCheck(ePlayer))
                            {
                                iRetVal = -1000000 - iDepth;
                            }
                            else
                            {
                                iRetVal = 0;    // Draw
                            }
                            if (abInfo.m_transTable != null)
                            {
                                abInfo.m_transTable.RecordEntry(board.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, TransEntryTypeE.Exact);
                            }
                        }
                        else
                        {
                            iRetVal = iAlpha;
                            foreach (Move move in moveList)
                            {
                                eResult = board.DoMoveNoLog(move);
                                abInfo.m_arrMove[iDepth - 1] = move;
                                if (eResult == ChessBoard.RepeatResultE.NoRepeat)
                                {
                                    iPts = -AlphaBeta(board,
                                                      (ePlayer == ChessBoard.PlayerE.Black) ? ChessBoard.PlayerE.White : ChessBoard.PlayerE.Black,
                                                      iDepth - 1,
                                                      -iBeta,
                                                      -iRetVal,
                                                      iWhiteMoveCount,
                                                      iBlackMoveCount,
                                                      abInfo);
                                }
                                else
                                {
                                    iPts = 0;
                                }
                                board.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(board.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, eType);
                            }
                        }
                    }
                }
            }
            else
            {
                iRetVal = 0;
            }
            return(iRetVal);
        }
Пример #2
0
        /// <summary>
        /// Record a new entry in the table
        /// </summary>
        /// <param name="i64ZobristKey">    Zobrist key. Probably unique for this board position.</param>
        /// <param name="eExtraInfo">       Extra information about the board not contains in the Zobrist key</param>
        /// <param name="iDepth">           Current depth (reverse)</param>
        /// <param name="iValue">           Board evaluation</param>
        /// <param name="eType">            Type of the entry</param>
        public void RecordEntry(long i64ZobristKey, ChessBoard.BoardStateMaskE eExtraInfo, int iDepth, int iValue, TransEntryTypeE eType)
        {
            TransEntry entry;

            i64ZobristKey     ^= (int)eExtraInfo;
            entry.m_i64Key     = i64ZobristKey;
            entry.m_iGen       = m_iGen;
            entry.m_eExtraInfo = eExtraInfo;
            entry.m_iDepth     = iDepth;
            entry.m_iValue     = iValue;
            entry.m_eType      = eType;
            m_arrTransEntry[(UInt64)i64ZobristKey % (UInt64)m_arrTransEntry.Length] = entry;
        }
Пример #3
0
        /// <summary>
        /// Record a new entry in the table
        /// </summary>
        /// <param name="i64ZobristKey">    Zobrist key. Probably unique for this board position.</param>
        /// <param name="eExtraInfo">       Extra information about the board not contains in the Zobrist key</param>
        /// <param name="iDepth">           Current depth (reverse)</param>
        /// <param name="iValue">           Board evaluation</param>
        /// <param name="eType">            Type of the entry</param>
        public void RecordEntry(long i64ZobristKey, ChessBoard.BoardStateMaskE eExtraInfo, int iDepth, int iValue, TransEntryTypeE eType) {
            TransEntry  entry;

            i64ZobristKey      ^= (int)eExtraInfo;
            entry.m_i64Key      = i64ZobristKey;
            entry.m_iGen        = m_iGen;
            entry.m_eExtraInfo  = eExtraInfo;
            entry.m_iDepth      = iDepth;
            entry.m_iValue      = iValue;
            entry.m_eType       = eType;
            m_arrTransEntry[(UInt64)i64ZobristKey % (UInt64)m_arrTransEntry.Length] = entry;
        }