Пример #1
0
        private AlphaBetaResult AlphaBeta(BoardState state, int alpha, int beta, GameState parent)
        {
            var result         = new AlphaBetaResult(state.StartEstimate, alpha, beta);
            var estimatedCells = EstimateCells(state);

            //double enumeration doesn't happen - we parallelize only non-terminal states
            if (state.AllowParallelize(estimatedCells) && !AnalyzeModeOn)
            {
                Parallel.ForEach(estimatedCells, (estimatedCell, parallelLoopState) =>
                {
                    if (ProcessCell(state, parent, estimatedCell, result))
                    {
                        parallelLoopState.Stop();
                    }
                });
            }
            else
            {
                foreach (var estimatedCell in estimatedCells)
                {
                    if (ProcessCell(state, parent, estimatedCell, result))
                    {
                        break;
                    }
                }
            }
            return(result);
        }
Пример #2
0
        /// <summary>
        /// Find the best move for a player using alpha-beta in a secondary thread
        /// </summary>
        /// <param name="board">            Chess board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayer">          Color doing the move</param>
        /// <param name="iThreadId">        Thread Id (0-n)</param>
        /// <param name="moveList">         List of move to try</param>
        /// <param name="posInfoWhite">     Information about pieces attacks for the white</param>
        /// <param name="posInfoBlack">     Information about pieces attacks for the black</param>
        /// <param name="iTotalMoveCount">  Total number of moves</param>
        /// <param name="iAlpha">           Alpha bound</param>
        /// <param name="iBeta">            Beta bound</param>
        /// <returns>
        /// Points
        /// </returns>
        private AlphaBetaResult FindBestMoveUsingAlphaBetaAsync(ChessBoard board,
                                                                SearchMode searchMode,
                                                                ChessBoard.PlayerE ePlayer,
                                                                int iThreadId,
                                                                List <Move> moveList,
                                                                ChessBoard.PosInfoS posInfoWhite,
                                                                ChessBoard.PosInfoS posInfoBlack,
                                                                int iTotalMoveCount,
                                                                int iAlpha,
                                                                int iBeta)
        {
            AlphaBetaResult resRetVal;
            DateTime        dtTimeOut;
            int             iDepth;
            int             iPermCountAtLevel;
            int             iPoint;
            int             iBestMoveIndex;
            int             iDepthLimit;

            int[] arrPoints;
            System.Threading.ThreadPriority eThreadPriority;
            TransTable transTable;
            bool       bTimeOut;
            bool       bIterativeDepthFirst;

            resRetVal       = new AlphaBetaResult();
            eThreadPriority = System.Threading.Thread.CurrentThread.Priority;
            System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.BelowNormal;
            if ((searchMode.m_eOption & SearchMode.OptionE.UseTransTable) != 0)
            {
                transTable = TransTable.GetTransTable(iThreadId);
                transTable.Reset();
            }
            else
            {
                transTable = null;
            }
            bIterativeDepthFirst                = (searchMode.m_eOption.HasFlag(SearchMode.OptionE.UseIterativeDepthSearch));
            resRetVal.movePosBest.StartPos      = 255;
            resRetVal.movePosBest.EndPos        = 255;
            resRetVal.movePosBest.OriginalPiece = ChessBoard.PieceE.None;
            resRetVal.movePosBest.Type          = Move.TypeE.Normal;
            try {
                resRetVal.iPermCount = 0;
                if (searchMode.m_iSearchDepth == 0 || bIterativeDepthFirst)
                {
                    dtTimeOut      = (bIterativeDepthFirst) ? DateTime.MaxValue : DateTime.Now + TimeSpan.FromSeconds(searchMode.m_iTimeOutInSec);
                    iDepthLimit    = (bIterativeDepthFirst) ? searchMode.m_iSearchDepth : 999;
                    iDepth         = 1;
                    resRetVal.iPts = FindBestMoveUsingAlphaBetaAtDepth(board,
                                                                       searchMode,
                                                                       ePlayer,
                                                                       moveList,
                                                                       posInfoWhite,
                                                                       posInfoBlack,
                                                                       iTotalMoveCount,
                                                                       iDepth,
                                                                       iAlpha,
                                                                       iBeta,
                                                                       transTable,
                                                                       DateTime.MaxValue,
                                                                       out iPermCountAtLevel,
                                                                       out iBestMoveIndex,
                                                                       out bTimeOut,
                                                                       out arrPoints);
                    if (iBestMoveIndex != -1)
                    {
                        resRetVal.movePosBest = moveList[iBestMoveIndex];
                    }
                    resRetVal.iPermCount += iPermCountAtLevel;
                    resRetVal.iMaxDepth   = iDepth;
                    while (DateTime.Now < dtTimeOut && !m_bCancelSearch && !bTimeOut && iDepth < iDepthLimit)
                    {
                        moveList = SortMoveList(moveList, arrPoints);
                        iDepth++;
                        iPoint = FindBestMoveUsingAlphaBetaAtDepth(board,
                                                                   searchMode,
                                                                   ePlayer,
                                                                   moveList,
                                                                   posInfoWhite,
                                                                   posInfoBlack,
                                                                   iTotalMoveCount,
                                                                   iDepth,
                                                                   iAlpha,
                                                                   iBeta,
                                                                   transTable,
                                                                   dtTimeOut,
                                                                   out iPermCountAtLevel,
                                                                   out iBestMoveIndex,
                                                                   out bTimeOut,
                                                                   out arrPoints);
                        if (!bTimeOut)
                        {
                            if (iBestMoveIndex != -1)
                            {
                                resRetVal.movePosBest = moveList[iBestMoveIndex];
                            }
                            resRetVal.iPermCount += iPermCountAtLevel;
                            resRetVal.iMaxDepth   = iDepth;
                            resRetVal.iPts        = iPoint;
                        }
                    }
                }
                else
                {
                    resRetVal.iMaxDepth = searchMode.m_iSearchDepth;
                    resRetVal.iPts      = FindBestMoveUsingAlphaBetaAtDepth(board,
                                                                            searchMode,
                                                                            ePlayer,
                                                                            moveList,
                                                                            posInfoWhite,
                                                                            posInfoBlack,
                                                                            iTotalMoveCount,
                                                                            resRetVal.iMaxDepth,
                                                                            iAlpha,
                                                                            iBeta,
                                                                            transTable,
                                                                            DateTime.MaxValue,
                                                                            out resRetVal.iPermCount,
                                                                            out iBestMoveIndex,
                                                                            out bTimeOut,
                                                                            out arrPoints);
                    if (iBestMoveIndex != -1)
                    {
                        resRetVal.movePosBest = moveList[iBestMoveIndex];
                    }
                }
            } finally {
                System.Threading.Thread.CurrentThread.Priority = eThreadPriority;
            }
            return(resRetVal);
        }
Пример #3
0
 private static bool ShouldBreak(BoardState state, AlphaBetaResult res, int minMax)
 {
     return(BreakOnDoubleThreat(state.ItIsFirstsTurn, minMax) ||
            res.Beta <= res.Alpha);
 }
Пример #4
0
        private bool ProcessCell(BoardState state, GameState parent, EstimatedCell estimatedCell, AlphaBetaResult res)
        {
            var cell      = estimatedCell.Cell;
            var currEstim = estimatedCell.Estimate * state.Multiplier;

            var gameState = new GameState(estimatedCell);

            OnStateChanged(gameState, parent);
            var cellResult = ShoudNotGoDeeper(state, estimatedCell)
                ? new AlphaBetaResult(currEstim)
                : AlphaBeta(state.GetNextState(estimatedCell.BoardState), res.Alpha, res.Beta, gameState);

            gameState.Estimate = cellResult.MinMax;
            if (state.ItIsFirstsTurn && cellResult.MinMax > res.MinMax)
            {
                res.MinMax = cellResult.MinMax;
                res.Alpha  = cellResult.MinMax;
                res.Move   = cell;
            }
            if (!state.ItIsFirstsTurn && cellResult.MinMax < res.MinMax)
            {
                res.MinMax = cellResult.MinMax;
                res.Beta   = cellResult.MinMax;
                res.Move   = cell;
            }
            return(ShouldBreak(state, res, cellResult.MinMax));
        }
        /// <summary>
        /// Find the best move for a player using alpha-beta in a secondary thread
        /// </summary>
        /// <param name="chessBoard">       Chess board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayerColor">     Color doing the move</param>
        /// <param name="iThreadId">        Thread Id (0-n)</param>
        /// <param name="moveList">         List of move to try</param>
        /// <param name="posInfoWhite">     Information about pieces attacks for the white</param>
        /// <param name="posInfoBlack">     Information about pieces attacks for the black</param>
        /// <param name="iTotalMoveCount">  Total number of moves</param>
        /// <param name="iAlpha">           Alpha bound</param>
        /// <param name="iBeta">            Beta bound</param>
        /// <returns>
        /// Points
        /// </returns>
        private AlphaBetaResult FindBestMoveUsingAlphaBetaAsync(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, int iThreadId, List<ChessBoard.MovePosS> moveList, ChessBoard.PosInfoS posInfoWhite, ChessBoard.PosInfoS posInfoBlack, int iTotalMoveCount, int iAlpha, int iBeta)
        {
            AlphaBetaResult                 resRetVal;
            DateTime                        dtTimeOut;
            int                             iDepth;
            int                             iPermCountAtLevel;
            int                             iPoint;
            int                             iBestMoveIndex;
            int                             iDepthLimit;
            int[]                           arrPoints;
            System.Threading.ThreadPriority eThreadPriority;
            TransTable                      transTable;
            bool                            bTimeOut;
            bool                            bIterativeDepthFirst;

            resRetVal                                       = new AlphaBetaResult();
            eThreadPriority                                = System.Threading.Thread.CurrentThread.Priority;
            System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.BelowNormal;
            if ((searchMode.m_eOption & SearchMode.OptionE.UseTransTable) != 0) {
                transTable = TransTable.GetTransTable(iThreadId);
                transTable.Reset();
            } else {
                transTable = null;
            }
            bIterativeDepthFirst                = ((searchMode.m_eOption & SearchMode.OptionE.UseIterativeDepthSearch) == SearchMode.OptionE.UseIterativeDepthSearch);
            resRetVal.movePosBest.StartPos      = 255;
            resRetVal.movePosBest.EndPos        = 255;
            resRetVal.movePosBest.OriginalPiece = ChessBoard.PieceE.None;
            resRetVal.movePosBest.Type          = ChessBoard.MoveTypeE.Normal;
            try {
                resRetVal.iPermCount  = 0;
                if (searchMode.m_iSearchDepth == 0 || bIterativeDepthFirst) {
                    dtTimeOut           = (bIterativeDepthFirst) ? DateTime.MaxValue : DateTime.Now + TimeSpan.FromSeconds(searchMode.m_iTimeOutInSec);
                    iDepthLimit         = (bIterativeDepthFirst) ? searchMode.m_iSearchDepth : 999;
                    iDepth              = 1;
                    resRetVal.iPts      = FindBestMoveUsingAlphaBetaAtDepth(chessBoard, searchMode, ePlayerColor, moveList, posInfoWhite, posInfoBlack, iTotalMoveCount, iDepth, iAlpha, iBeta, transTable, DateTime.MaxValue, out iPermCountAtLevel, out iBestMoveIndex, out bTimeOut, out arrPoints);
                    if (iBestMoveIndex != -1) {
                        resRetVal.movePosBest = moveList[iBestMoveIndex];
                    }
                    resRetVal.iPermCount   += iPermCountAtLevel;
                    resRetVal.iMaxDepth     = iDepth;
                    while (DateTime.Now < dtTimeOut && !m_bCancelSearch && !bTimeOut && iDepth < iDepthLimit) {
                        moveList = SortMoveList(moveList, arrPoints);
                        iDepth++;
                        iPoint  = FindBestMoveUsingAlphaBetaAtDepth(chessBoard, searchMode, ePlayerColor, moveList, posInfoWhite, posInfoBlack, iTotalMoveCount, iDepth, iAlpha, iBeta, transTable, dtTimeOut, out iPermCountAtLevel, out iBestMoveIndex, out bTimeOut, out arrPoints);
                        if (!bTimeOut) {
                            if (iBestMoveIndex != -1) {
                                resRetVal.movePosBest = moveList[iBestMoveIndex];
                            }
                            resRetVal.iPermCount   += iPermCountAtLevel;
                            resRetVal.iMaxDepth     = iDepth;
                            resRetVal.iPts          = iPoint;
                        }
                    }
                } else {
                    resRetVal.iMaxDepth = searchMode.m_iSearchDepth;
                    resRetVal.iPts      = FindBestMoveUsingAlphaBetaAtDepth(chessBoard, searchMode, ePlayerColor, moveList, posInfoWhite, posInfoBlack, iTotalMoveCount, resRetVal.iMaxDepth, iAlpha, iBeta, transTable, DateTime.MaxValue, out resRetVal.iPermCount, out iBestMoveIndex, out bTimeOut, out arrPoints);
                    if (iBestMoveIndex != -1) {
                        resRetVal.movePosBest = moveList[iBestMoveIndex];
                    }
                }
            } finally {
                System.Threading.Thread.CurrentThread.Priority = eThreadPriority;
            }
            return(resRetVal);
        }