Example #1
0
 /// <summary>
 /// Debugging routine
 /// </summary>
 /// <param name="iDepth">       Actual search depth</param>
 /// <param name="ePlayerColor"> Color doing the move</param>
 /// <param name="move">         Move</param>
 /// <param name="iPts">         Points for this move</param>
 protected void TraceSearch(int iDepth, ChessBoard.PlayerColorE ePlayerColor, ChessBoard.MovePosS move, int iPts)
 {
     if (m_trace != null)
     {
         m_trace.TraceSearch(iDepth, ePlayerColor, move, iPts);
     }
 }
        public void ToStringTest()
        {
            ChessBoard.MovePosS target = new ChessBoard.MovePosS();
            target.OriginalPiece = ChessBoard.PieceE.Knight | ChessBoard.PieceE.Black;
            target.StartPos      = 57;
            target.EndPos        = 42;
            target.Type          = ChessBoard.MoveTypeE.Normal;
            string expected = "Чёрный конь g8-f6";
            string actual;

            actual = target.ToString();
            Assert.AreEqual(expected, actual);
        }
Example #3
0
        /// <summary>
        /// Add a move to the stack. All redo move are discarded
        /// </summary>
        /// <param name="movePos">  New move</param>
        public void AddMove(ChessBoard.MovePosS movePos)
        {
            int iCount;
            int iPos;

            iCount = Count;
            iPos   = m_iPosInList + 1;
            while (iCount != iPos)
            {
                m_listMovePos.RemoveAt(--iCount);
            }
            m_listMovePos.Add(movePos);
            m_iPosInList = iPos;
        }
Example #4
0
        /// <summary>
        /// Convert a list of PGN positions into a moving positions
        /// </summary>
        /// <param name="eColorToPlay">     Color to play</param>
        /// <param name="arrRawMove">       Array of PGN moves</param>
        /// <param name="piMoveList">       Returned array of moving position</param>
        /// <param name="listMovePos">      Returned the list of move if not null</param>
        /// <param name="iSkip">            Skipped count</param>
        /// <param name="iTruncated">       Truncated count</param>
        private void CnvRawMoveToPosMove(ChessBoard.PlayerColorE eColorToPlay, List <string> arrRawMove, out int[] piMoveList, List <ChessBoard.MovePosS> listMovePos, ref int iSkip, ref int iTruncated)
        {
            List <int> arrMoveList;

            ChessBoard.MovePosS movePos;
            int iPos;

            movePos          = new ChessBoard.MovePosS();
            movePos.StartPos = 0;
            movePos.EndPos   = 0;
            movePos.Type     = ChessBoard.MoveTypeE.Normal;
            arrMoveList      = new List <int>(256);
            try {
                foreach (string strMove in arrRawMove)
                {
                    if (strMove == "1-0" ||
                        strMove == "0-1" ||
                        strMove == "1/2-1/2" ||
                        strMove == "*" ||
                        strMove[0] == '(')
                    {
                        break;
                    }
                    else if (strMove == "..")
                    {
                        iSkip++;
                        break;
                    }
                    CnvRawMoveToPosMove(eColorToPlay, strMove, out iPos, ref iTruncated, ref movePos);
                    if (iPos != -1)
                    {
                        arrMoveList.Add(iPos);
                        if (listMovePos != null)
                        {
                            listMovePos.Add(movePos);
                        }
                        eColorToPlay = (eColorToPlay == ChessBoard.PlayerColorE.Black) ? ChessBoard.PlayerColorE.White : ChessBoard.PlayerColorE.Black;
                    }
                    else
                    {
                        break;
                    }
                }
            } catch (PgnParserException ex) {
                ex.MoveList = arrMoveList.ToArray();
                MessageBox.Show(ex.ToString());
                throw;
            }
            piMoveList = arrMoveList.ToArray();
        }
Example #5
0
        /// <summary>
        /// Gets the description of a move
        /// </summary>
        /// <param name="movePos">  Move to describe</param>
        /// <returns>
        /// Move description
        /// </returns>
        private string GetMoveDesc(ChessBoard.MovePosS movePos)
        {
            string strRetVal;

            if (m_eDisplayMode == DisplayModeE.MovePos)
            {
                strRetVal = ChessBoard.GetHumanPos(movePos);
            }
            else
            {
                strRetVal = PgnUtil.GetPGNMoveFromMove(m_chessBoard, movePos, false);
                if ((movePos.Type & ChessBoard.MoveTypeE.MoveFromBook) == ChessBoard.MoveTypeE.MoveFromBook)
                {
                    strRetVal = "(" + strRetVal + ")";
                }
            }
            return(strRetVal);
        }
Example #6
0
        /// <summary>
        /// Deserialize from XML
        /// </summary>
        /// <param name="reader">   XML reader</param>
        void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
        {
            ChessBoard.MovePosS movePos;
            bool bIsEmpty;

            m_listMovePos.Clear();
            if (reader.MoveToContent() != XmlNodeType.Element || reader.LocalName != "MoveList")
            {
                throw new SerializationException("Unknown format");
            }
            else
            {
                bIsEmpty     = reader.IsEmptyElement;
                m_iPosInList = Int32.Parse(reader.GetAttribute("PositionInList"));
                if (bIsEmpty)
                {
                    reader.Read();
                }
                else
                {
                    if (reader.ReadToDescendant("Move"))
                    {
                        while (reader.IsStartElement())
                        {
                            movePos = new ChessBoard.MovePosS();
                            movePos.OriginalPiece = (ChessBoard.PieceE)Enum.Parse(typeof(ChessBoard.SerPieceE), reader.GetAttribute("OriginalPiece"));
                            movePos.StartPos      = (byte)Int32.Parse(reader.GetAttribute("StartingPosition"));
                            movePos.EndPos        = (byte)Int32.Parse(reader.GetAttribute("EndingPosition"));
                            movePos.Type          = (ChessBoard.MoveTypeE)Enum.Parse(typeof(ChessBoard.MoveTypeE), reader.GetAttribute("MoveType"));
                            m_listMovePos.Add(movePos);
                            reader.ReadStartElement("Move");
                        }
                    }
                    reader.ReadEndElement();
                }
            }
        }
Example #7
0
        /// <summary>
        /// Find the best move for a player using minmax search
        /// </summary>
        /// <param name="chessBoard">       Chess board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayerColor">     Color doing the move</param>
        /// <param name="moveList">         Move list</param>
        /// <param name="arrIndex">         Order of evaluation of the moves</param>
        /// <param name="posInfo">          Information about pieces attacks</param>
        /// <param name="moveBest">         Best move found</param>
        /// <param name="iPermCount">       Nb of permutations evaluated</param>
        /// <param name="iCacheHit">        Nb of cache hit</param>
        /// <param name="iMaxDepth">        Maximum depth evaluated</param>
        /// <returns>
        /// true if a move has been found
        /// </returns>
        protected override bool FindBestMove(ChessBoard chessBoard,
                                             SearchEngine.SearchMode searchMode,
                                             ChessBoard.PlayerColorE ePlayerColor,
                                             List <ChessBoard.MovePosS> moveList,
                                             int[]                      arrIndex,
                                             ChessBoard.PosInfoS posInfo,
                                             ref ChessBoard.MovePosS moveBest,
                                             out int iPermCount,
                                             out int iCacheHit,
                                             out int iMaxDepth)
        {
            bool     bRetVal = false;
            DateTime dtTimeOut;
            int      iDepth;
            int      iPermCountAtLevel;

            iPermCount = 0;
            iCacheHit  = 0;
            if (searchMode.m_iSearchDepth == 0)
            {
                dtTimeOut = DateTime.Now + TimeSpan.FromSeconds(searchMode.m_iTimeOutInSec);
                iDepth    = 0;
                do
                {
                    bRetVal     = FindBestMoveUsingMinMaxAtDepth(chessBoard, searchMode, ePlayerColor, moveList, arrIndex, iDepth + 1, ref moveBest, out iPermCountAtLevel);
                    iPermCount += iPermCountAtLevel;
                    iDepth++;
                } while (DateTime.Now < dtTimeOut);
                iMaxDepth = iDepth;
            }
            else
            {
                iMaxDepth = searchMode.m_iSearchDepth;
                bRetVal   = FindBestMoveUsingMinMaxAtDepth(chessBoard, searchMode, ePlayerColor, moveList, arrIndex, iMaxDepth, ref moveBest, out iPermCount);
            }
            return(bRetVal);
        }
Example #8
0
        /// <summary>
        /// Convert a PGN position into a moving position
        /// </summary>
        /// <param name="ePlayerColor">     Color moving</param>
        /// <param name="strMove">          Move</param>
        /// <param name="iPos">             Returned moving position</param>
        /// <param name="iTruncated">       Truncated count</param>
        /// <param name="movePos">          Move position</param>
        private void CnvRawMoveToPosMove(ChessBoard.PlayerColorE ePlayerColor, string strMove, out int iPos, ref int iTruncated, ref ChessBoard.MovePosS movePos)
        {
            string strPureMove;
            int    iIndex;
            int    iStartCol;
            int    iStartRow;
            int    iEndPos;
            int    iOfs;

            ChessBoard.PieceE    ePiece;
            ChessBoard.MoveTypeE eMoveType;

            eMoveType   = ChessBoard.MoveTypeE.Normal;
            iPos        = 0;
            strPureMove = strMove.Replace("x", "").Replace("#", "").Replace("ep", "").Replace("+", "");
            iIndex      = strPureMove.IndexOf('=');
            if (iIndex != -1)
            {
                if (strPureMove.Length > iIndex + 1)
                {
                    switch (strPureMove[iIndex + 1])
                    {
                    case 'Q':
                        eMoveType = ChessBoard.MoveTypeE.PawnPromotionToQueen;
                        break;

                    case 'R':
                        eMoveType = ChessBoard.MoveTypeE.PawnPromotionToRook;
                        break;

                    case 'B':
                        eMoveType = ChessBoard.MoveTypeE.PawnPromotionToBishop;
                        break;

                    case 'N':
                        eMoveType = ChessBoard.MoveTypeE.PawnPromotionToKnight;
                        break;

                    case 'P':
                        eMoveType = ChessBoard.MoveTypeE.PawnPromotionToPawn;
                        break;

                    default:
                        iPos = -1;
                        iTruncated++;
                        break;
                    }
                    if (iPos != -1)
                    {
                        strPureMove = strPureMove.Substring(0, iIndex);
                    }
                }
                else
                {
                    iPos = -1;
                    iTruncated++;
                }
            }
            if (iPos == 0)
            {
                if (strPureMove == "O-O")
                {
                    iPos = FindCastling(ePlayerColor, true, ref iTruncated, strMove, ref movePos);
                }
                else if (strPureMove == "O-O-O")
                {
                    iPos = FindCastling(ePlayerColor, false, ref iTruncated, strMove, ref movePos);
                }
                else
                {
                    iOfs = 1;
                    switch (strPureMove[0])
                    {
                    case 'K':   // King
                        ePiece = ChessBoard.PieceE.King;
                        break;

                    case 'N':   // Knight
                        ePiece = ChessBoard.PieceE.Knight;
                        break;

                    case 'B':   // Bishop
                        ePiece = ChessBoard.PieceE.Bishop;
                        break;

                    case 'R':   // Rook
                        ePiece = ChessBoard.PieceE.Rook;
                        break;

                    case 'Q':   // Queen
                        ePiece = ChessBoard.PieceE.Queen;
                        break;

                    default:    // Pawn
                        ePiece = ChessBoard.PieceE.Pawn;
                        iOfs   = 0;
                        break;
                    }
                    DecodeMove(strPureMove.Substring(iOfs), out iStartCol, out iStartRow, out iEndPos);
                    iPos = FindPieceMove(ePlayerColor, ePiece, iStartCol, iStartRow, iEndPos, eMoveType, strMove, ref iTruncated, ref movePos);
                }
            }
        }
Example #9
0
        /// <summary>
        /// Find a move using the specification
        /// </summary>
        /// <param name="ePlayerColor">     Color moving</param>
        /// <param name="ePiece">           Piece moving</param>
        /// <param name="iStartCol">        Starting column of the move or -1 if not specified</param>
        /// <param name="iStartRow">        Starting row of the move or -1 if not specified</param>
        /// <param name="iEndPos">          Ending position of the move</param>
        /// <param name="eMoveType">        Type of move. Use for discriminating between different pawn promotion.</param>
        /// <param name="strMove">          Move</param>
        /// <param name="iTruncated">       Truncated count</param>
        /// <param name="movePos">          Move position</param>
        /// <returns>
        /// Moving position or -1 if error
        /// </returns>
        private int FindPieceMove(ChessBoard.PlayerColorE ePlayerColor, ChessBoard.PieceE ePiece, int iStartCol, int iStartRow, int iEndPos, ChessBoard.MoveTypeE eMoveType, string strMove, ref int iTruncated, ref ChessBoard.MovePosS movePos)
        {
            int iRetVal = -1;
            List <ChessBoard.MovePosS> arrMovePos;
            int iCol;
            int iRow;

            ePiece     = ePiece | ((ePlayerColor == ChessBoard.PlayerColorE.Black) ? ChessBoard.PieceE.Black : ChessBoard.PieceE.White);
            arrMovePos = m_chessBoard.EnumMoveList(ePlayerColor);
            foreach (ChessBoard.MovePosS move in arrMovePos)
            {
                if ((int)move.EndPos == iEndPos && m_chessBoard[(int)move.StartPos] == ePiece)
                {
                    if (eMoveType == ChessBoard.MoveTypeE.Normal || (move.Type & ChessBoard.MoveTypeE.MoveTypeMask) == eMoveType)
                    {
                        iCol = (int)move.StartPos & 7;
                        iRow = (int)move.StartPos >> 3;
                        if ((iStartCol == -1 || iStartCol == iCol) &&
                            (iStartRow == -1 || iStartRow == iRow))
                        {
                            if (iRetVal != -1)
                            {
                                throw new PgnParserException("More then one piece found for this move - " + strMove, GetCodeInError());
                            }
                            movePos = move;
                            iRetVal = (int)move.StartPos + ((int)move.EndPos << 8);
                            m_chessBoard.DoMove(move);
                        }
                    }
                }
            }
            if (iRetVal == -1)
            {
                if (m_bDiagnose)
                {
                    throw new PgnParserException("Unable to find compatible move - " + strMove, GetCodeInError());
                }
                iTruncated++;
            }
            return(iRetVal);
        }
Example #10
0
        /// <summary>
        /// Find a castle move
        /// </summary>
        /// <param name="ePlayerColor">     Color moving</param>
        /// <param name="bShortCastling">   true for short, false for long</param>
        /// <param name="iTruncated">       Truncated count</param>
        /// <param name="strMove">          Move</param>
        /// <param name="movePos">          Returned moved if found</param>
        /// <returns>
        /// Moving position or -1 if error
        /// </returns>
        private int FindCastling(ChessBoard.PlayerColorE ePlayerColor, bool bShortCastling, ref int iTruncated, string strMove, ref ChessBoard.MovePosS movePos)
        {
            int iRetVal = -1;
            int iWantedDelta;
            int iDelta;
            List <ChessBoard.MovePosS> arrMovePos;

            arrMovePos   = m_chessBoard.EnumMoveList(ePlayerColor);
            iWantedDelta = bShortCastling ? 2 : -2;
            foreach (ChessBoard.MovePosS move in arrMovePos)
            {
                if ((move.Type & ChessBoard.MoveTypeE.MoveTypeMask) == ChessBoard.MoveTypeE.Castle)
                {
                    iDelta = ((int)move.StartPos & 7) - ((int)move.EndPos & 7);
                    if (iDelta == iWantedDelta)
                    {
                        iRetVal = (int)move.StartPos + ((int)move.EndPos << 8);
                        movePos = move;
                        m_chessBoard.DoMove(move);
                    }
                }
            }
            if (iRetVal == -1)
            {
                if (m_bDiagnose)
                {
                    throw new PgnParserException("Unable to find compatible move - " + strMove, GetCodeInError());
                }
                iTruncated++;
            }
            return(iRetVal);
        }
        /// <summary>
        /// Find the best move for a player using alpha-beta
        /// </summary>
        /// <param name="chessBoard">       Chess board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayerColor">     Color doing the move</param>
        /// <param name="moveList">         Move list</param>
        /// <param name="arrIndex">         Order of evaluation of the moves</param>
        /// <param name="posInfo">          Information about pieces attacks</param>
        /// <param name="moveBest">         Best move found</param>
        /// <param name="iPermCount">       Total permutation evaluated</param>
        /// <param name="iCacheHit">        Number of moves found in the translation table cache</param>
        /// <param name="iMaxDepth">        Maximum depth to use</param>
        /// <returns>
        /// true if a move has been found
        /// </returns>
        protected override bool FindBestMove(ChessBoard chessBoard,
                                             SearchEngine.SearchMode searchMode,
                                             ChessBoard.PlayerColorE ePlayerColor,
                                             List <ChessBoard.MovePosS> moveList,
                                             int[]                      arrIndex,
                                             ChessBoard.PosInfoS posInfo,
                                             ref ChessBoard.MovePosS moveBest,
                                             out int iPermCount,
                                             out int iCacheHit,
                                             out int iMaxDepth)
        {
            bool bRetVal = false;
            bool bMultipleThread;
            bool bUseTransTable;

            ChessBoard[]                 arrChessBoard;
            Task <AlphaBetaResult>[]     taskArray;
            List <ChessBoard.MovePosS>[] arrMoveList;
            AlphaBetaResult              alphaBetaRes;

            ChessBoard.PosInfoS posInfoWhite;
            ChessBoard.PosInfoS posInfoBlack;
            int iAlpha;
            int iBeta;
            int iThreadCount;

            //TODO Enable transposition table when bug on 3 repetition move draw will be found.
            if (ePlayerColor == ChessBoard.PlayerColorE.White)
            {
                posInfoWhite = posInfo;
                posInfoBlack = ChessBoard.s_posInfoNull;
            }
            else
            {
                posInfoWhite = ChessBoard.s_posInfoNull;
                posInfoBlack = posInfo;
            }
            searchMode.m_eOption &= ~SearchMode.OptionE.UseTransTable;
            bUseTransTable        = ((searchMode.m_eOption & SearchMode.OptionE.UseTransTable) != 0);
            iCacheHit             = 0;
            iMaxDepth             = 0;
            iPermCount            = 0;
            iAlpha          = -10000000;
            iBeta           = +10000000;
            bMultipleThread = (searchMode.m_eThreadingMode == SearchMode.ThreadingModeE.OnePerProcessorForSearch);
            iThreadCount    = System.Environment.ProcessorCount;
            if (bMultipleThread && iThreadCount < 2)
            {
                bMultipleThread = false;    // No reason to go with multi-threading if only one processor
            }
            if (bMultipleThread)
            {
                arrChessBoard = new ChessBoard[iThreadCount];
                arrMoveList   = new List <ChessBoard.MovePosS> [iThreadCount];
                taskArray     = new Task <AlphaBetaResult> [iThreadCount];
                for (int iIndex = 0; iIndex < iThreadCount; iIndex++)
                {
                    arrChessBoard[iIndex] = chessBoard.Clone();
                    arrMoveList[iIndex]   = new List <ChessBoard.MovePosS>(moveList.Count / iThreadCount + 1);
                    for (int iStep = iIndex; iStep < moveList.Count; iStep += iThreadCount)
                    {
                        arrMoveList[iIndex].Add(moveList[arrIndex[iStep]]);
                    }
                }
                for (int iIndex = 0; iIndex < iThreadCount; iIndex++)
                {
                    taskArray[iIndex] = Task <AlphaBetaResult> .Factory.StartNew((param) => {
                        int iStep = (int)param;
                        return(FindBestMoveUsingAlphaBetaAsync(arrChessBoard[iStep],
                                                               searchMode,
                                                               ePlayerColor,
                                                               iStep,
                                                               arrMoveList[iStep],
                                                               posInfoWhite,
                                                               posInfoBlack,
                                                               moveList.Count,
                                                               iAlpha,
                                                               iBeta));
                    }, iIndex);
                }
                iMaxDepth = 999;
                for (int iStep = 0; iStep < iThreadCount; iStep++)
                {
                    alphaBetaRes = taskArray[iStep].Result;
                    if (alphaBetaRes.movePosBest.StartPos != 255)
                    {
                        iPermCount += alphaBetaRes.iPermCount;
                        iMaxDepth   = Math.Min(iMaxDepth, alphaBetaRes.iMaxDepth);
                        if (bUseTransTable)
                        {
                            iCacheHit += TransTable.GetTransTable(iStep).CacheHit;
                        }
                        if (alphaBetaRes.iPts > iAlpha)
                        {
                            iAlpha   = alphaBetaRes.iPts;
                            moveBest = alphaBetaRes.movePosBest;
                            bRetVal  = true;
                        }
                    }
                }
                if (iMaxDepth == 999)
                {
                    iMaxDepth = -1;
                }
            }
            else
            {
                ChessBoard chessBoardTmp;
                List <ChessBoard.MovePosS> moveListTmp;

                chessBoardTmp = chessBoard.Clone();
                moveListTmp   = new List <ChessBoard.MovePosS>(moveList.Count);
                for (int iIndex = 0; iIndex < moveList.Count; iIndex++)
                {
                    moveListTmp.Add(moveList[arrIndex[iIndex]]);
                }
                alphaBetaRes = FindBestMoveUsingAlphaBetaAsync(chessBoardTmp,
                                                               searchMode,
                                                               ePlayerColor,
                                                               0,  // ThreadId
                                                               moveListTmp,
                                                               posInfoWhite,
                                                               posInfoBlack,
                                                               moveList.Count,
                                                               iAlpha,
                                                               iBeta);
                iPermCount = alphaBetaRes.iPermCount;
                iMaxDepth  = alphaBetaRes.iMaxDepth;
                if (alphaBetaRes.movePosBest.StartPos != 255)
                {
                    if (bUseTransTable)
                    {
                        iCacheHit += TransTable.GetTransTable(0).CacheHit;
                    }
                    moveBest = alphaBetaRes.movePosBest;
                    bRetVal  = true;
                }
            }
            return(bRetVal);
        }
Example #12
0
        /// <summary>
        /// Find the best move for a player using minmax search
        /// </summary>
        /// <param name="chessBoard">       Chess board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayerColor">     Color doing the move</param>
        /// <param name="moveList">         Move list</param>
        /// <param name="arrIndex">         Order of evaluation of the moves</param>
        /// <param name="iDepth">           Maximum depth</param>
        /// <param name="moveBest">         Best move found</param>
        /// <param name="iPermCount">       Total permutation evaluated</param>
        /// <returns>
        /// true if a move has been found
        /// </returns>
        private bool FindBestMoveUsingMinMaxAtDepth(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, List <ChessBoard.MovePosS> moveList, int[] arrIndex, int iDepth, ref ChessBoard.MovePosS moveBest, out int iPermCount)
        {
            bool bRetVal = false;

            ChessBoard.MovePosS move;
            int iPts;
            int iWhiteMoveCount;
            int iBlackMoveCount;
            int iBestPts;

            ChessBoard.RepeatResultE eResult;

            iPermCount = 0;
            iBestPts   = Int32.MinValue;
            if (ePlayerColor == ChessBoard.PlayerColorE.White)
            {
                iWhiteMoveCount = moveList.Count;
                iBlackMoveCount = 0;
            }
            else
            {
                iWhiteMoveCount = 0;
                iBlackMoveCount = moveList.Count;
            }
            foreach (int iIndex in arrIndex)
            {
                move    = moveList[iIndex];
                eResult = chessBoard.DoMoveNoLog(move);
                if (eResult == ChessBoard.RepeatResultE.NoRepeat)
                {
                    iPts = -MinMax(chessBoard,
                                   searchMode,
                                   (ePlayerColor == ChessBoard.PlayerColorE.Black) ? ChessBoard.PlayerColorE.White : ChessBoard.PlayerColorE.Black,
                                   iDepth - 1,
                                   iWhiteMoveCount,
                                   iBlackMoveCount,
                                   ref iPermCount);
                }
                else
                {
                    iPts = 0;
                }
                chessBoard.UndoMoveNoLog(move);
                if (iPts > iBestPts)
                {
                    TraceSearch(iDepth, ePlayerColor, move, iPts);
                    iBestPts = iPts;
                    moveBest = move;
                    bRetVal  = true;
                }
            }
            return(bRetVal);
        }
Example #13
0
        /// <summary>
        /// Find the best move for a player using a specific method
        /// </summary>
        /// <param name="chessBoard">       Chess board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayerColor">     Color doing the move</param>
        /// <param name="moveBest">         Best move found</param>
        /// <param name="iPermCount">       Total permutation evaluated</param>
        /// <param name="iCacheHit">        Number of moves found in the translation table cache</param>
        /// <param name="iMaxDepth">        Maximum depth reached</param>
        /// <returns>
        /// true if a move has been found
        /// </returns>
        public bool FindBestMove(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, out ChessBoard.MovePosS moveBest, out int iPermCount, out int iCacheHit, out int iMaxDepth)
        {
            bool bRetVal = false;
            List <ChessBoard.MovePosS> moveList;

            int[]  arrIndex;
            int    iSwapIndex;
            int    iTmp;
            Random rnd;

            ChessBoard.PosInfoS posInfo;

            iCacheHit       = 0;
            moveList        = chessBoard.EnumMoveList(ePlayerColor, true, out posInfo);
            arrIndex        = new int[moveList.Count];
            m_bCancelSearch = false;
            for (int iIndex = 0; iIndex < moveList.Count; iIndex++)
            {
                arrIndex[iIndex] = iIndex;
            }
            if (searchMode.m_eRandomMode != SearchMode.RandomModeE.Off)
            {
                rnd = (searchMode.m_eRandomMode == SearchMode.RandomModeE.OnRepetitive) ? m_rndRep : m_rnd;
                for (int iIndex = 0; iIndex < moveList.Count; iIndex++)
                {
                    iSwapIndex           = rnd.Next(moveList.Count);
                    iTmp                 = arrIndex[iIndex];
                    arrIndex[iIndex]     = arrIndex[iSwapIndex];
                    arrIndex[iSwapIndex] = iTmp;
                }
            }
            moveBest.StartPos      = 0;
            moveBest.EndPos        = 0;
            moveBest.OriginalPiece = ChessBoard.PieceE.None;
            moveBest.Type          = ChessBoard.MoveTypeE.Normal;
            bRetVal = FindBestMove(chessBoard, searchMode, ePlayerColor, moveList, arrIndex, posInfo, ref moveBest, out iPermCount, out iCacheHit, out iMaxDepth);
            return(bRetVal);
        }
Example #14
0
 /// <summary>
 /// Find the best move using a specific search method
 /// </summary>
 /// <param name="chessBoard">       Chess board</param>
 /// <param name="searchMode">       Search mode</param>
 /// <param name="ePlayerColor">     Color doing the move</param>
 /// <param name="moveList">         Move list</param>
 /// <param name="arrIndex">         Order of evaluation of the moves</param>
 /// <param name="posInfo">          Position information</param>
 /// <param name="moveBest">         Best move found</param>
 /// <param name="iPermCount">       Total permutation evaluated</param>
 /// <param name="iCacheHit">        Number of moves found in the translation table cache</param>
 /// <param name="iMaxDepth">        Maximum depth to use</param>
 /// <returns>
 /// true if a move has been found
 /// </returns>
 protected abstract bool FindBestMove(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, List <ChessBoard.MovePosS> moveList, int[] arrIndex, ChessBoard.PosInfoS posInfo, ref ChessBoard.MovePosS moveBest, out int iPermCount, out int iCacheHit, out int iMaxDepth);