Example #1
0
        /// <summary>
        /// Find the best move for a player using a specific method
        /// </summary>
        /// <param name="board">            Board</param>
        /// <param name="searchMode">       Search mode</param>
        /// <param name="ePlayer">          Player making the move</param>
        /// <param name="dispatcher">       Dispatcher of the main thread if function is called on a background thread</param>
        /// <param name="actionFoundMove">  Action to call with the found move</param>
        /// <param name="cookie">           Cookie to pass to the action</param>
        private void FindBestMove <T>(ChessBoard board,
                                      SearchMode searchMode,
                                      ChessBoard.PlayerE ePlayer,
                                      Dispatcher dispatcher,
                                      Action <T, MoveExt> actionFoundMove,
                                      T cookie)
        {
            bool        bRetVal = false;
            List <Move> moveList;
            MoveExt     moveExt;
            Move        move;

            int[]  arrIndex;
            int    iSwapIndex;
            int    iTmp;
            int    iPermCount;
            int    iCacheHit;
            int    iMaxDepth;
            Random rnd;

            ChessBoard.PosInfoS posInfo;

            moveList = board.EnumMoveList(ePlayer, true /*bMoveList*/, out posInfo);
            arrIndex = new int[moveList.Count];
            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;
                }
            }
            move.StartPos         = 0;
            move.EndPos           = 0;
            move.OriginalPiece    = ChessBoard.PieceE.None;
            move.Type             = Move.TypeE.Normal;
            bRetVal               = FindBestMove(board, searchMode, ePlayer, moveList, arrIndex, posInfo, ref move, out iPermCount, out iCacheHit, out iMaxDepth);
            moveExt               = new MoveExt(move, "", iPermCount, iMaxDepth, iMaxDepth, 0);
            m_searchEngineWorking = null;
            if (dispatcher != null)
            {
                dispatcher.Invoke(actionFoundMove, cookie, moveExt);
            }
            else
            {
                actionFoundMove(cookie, moveExt);
            }
        }
Example #2
0
        /// <summary>
        /// Add a move to the stack. All redo move are discarded
        /// </summary>
        /// <param name="move"> New move</param>
        public void AddMove(MoveExt move)
        {
            int iCount;
            int iPos;

            iCount = Count;
            iPos   = m_iPosInList + 1;
            while (iCount != iPos)
            {
                m_listMovePos.RemoveAt(--iCount);
            }
            m_listMovePos.Add(move);
            m_iPosInList = iPos;
        }
Example #3
0
        /// <summary>
        /// Gets a PGN move from a MovePosS structure and a chessboard.
        /// </summary>
        /// <param name="chessBoard">       Chessboard before the move has been done.</param>
        /// <param name="move">             Move to convert</param>
        /// <param name="bIncludeEnding">   true to include ending</param>
        /// <returns>
        /// PGN move
        /// </returns>
        public static string GetPGNMoveFromMove(ChessBoard chessBoard, MoveExt move, bool bIncludeEnding)
        {
            string strRetVal;
            string strStartPos;

            ChessBoard.PieceE ePiece;
            PGNAmbiguity      eAmbiguity;

            ChessBoard.PlayerE ePlayerToMove;

            if (move.Move.Type == Move.TypeE.Castle)
            {
                strRetVal = (move.Move.EndPos == 1 || move.Move.EndPos == 57) ? "O-O" : "O-O-O";
            }
            else
            {
                ePiece        = chessBoard[move.Move.StartPos] & ChessBoard.PieceE.PieceMask;
                ePlayerToMove = chessBoard.CurrentPlayer;
                eAmbiguity    = FindMoveAmbiguity(chessBoard, move.Move, ePlayerToMove);
                switch (ePiece)
                {
                case ChessBoard.PieceE.King:
                    strRetVal = "K";
                    break;

                case ChessBoard.PieceE.Queen:
                    strRetVal = "Q";
                    break;

                case ChessBoard.PieceE.Rook:
                    strRetVal = "R";
                    break;

                case ChessBoard.PieceE.Bishop:
                    strRetVal = "B";
                    break;

                case ChessBoard.PieceE.Knight:
                    strRetVal = "N";
                    break;

                case ChessBoard.PieceE.Pawn:
                    strRetVal = "";
                    break;

                default:
                    strRetVal = "";
                    break;
                }
                strStartPos = GetPGNSquareID(move.Move.StartPos);
                if ((eAmbiguity & PGNAmbiguity.ColMustBeSpecify) == PGNAmbiguity.ColMustBeSpecify)
                {
                    strRetVal += strStartPos[0];
                }
                if ((eAmbiguity & PGNAmbiguity.RowMustBeSpecify) == PGNAmbiguity.RowMustBeSpecify)
                {
                    strRetVal += strStartPos[1];
                }
                if ((move.Move.Type & Move.TypeE.PieceEaten) == Move.TypeE.PieceEaten)
                {
                    if (ePiece == ChessBoard.PieceE.Pawn &&
                        (eAmbiguity & PGNAmbiguity.ColMustBeSpecify) == (PGNAmbiguity)0 &&
                        (eAmbiguity & PGNAmbiguity.RowMustBeSpecify) == (PGNAmbiguity)0)
                    {
                        strRetVal += strStartPos[0];
                    }
                    strRetVal += 'x';
                }
                strRetVal += GetPGNSquareID(move.Move.EndPos);
                switch (move.Move.Type & Move.TypeE.MoveTypeMask)
                {
                case Move.TypeE.PawnPromotionToQueen:
                    strRetVal += "=Q";
                    break;

                case Move.TypeE.PawnPromotionToRook:
                    strRetVal += "=R";
                    break;

                case Move.TypeE.PawnPromotionToBishop:
                    strRetVal += "=B";
                    break;

                case Move.TypeE.PawnPromotionToKnight:
                    strRetVal += "=N";
                    break;

                case Move.TypeE.PawnPromotionToPawn:
                    strRetVal += "=P";
                    break;

                default:
                    break;
                }
            }
            chessBoard.DoMoveNoLog(move.Move);
            switch (chessBoard.GetCurrentResult())
            {
            case ChessBoard.GameResultE.OnGoing:
                break;

            case ChessBoard.GameResultE.Check:
                strRetVal += "+";
                break;

            case ChessBoard.GameResultE.Mate:
                strRetVal += "#";
                if (bIncludeEnding)
                {
                    if (chessBoard.CurrentPlayer == ChessBoard.PlayerE.Black)
                    {
                        strRetVal += " 1-0";
                    }
                    else
                    {
                        strRetVal += " 0-1";
                    }
                }
                break;

            case ChessBoard.GameResultE.ThreeFoldRepeat:
            case ChessBoard.GameResultE.FiftyRuleRepeat:
            case ChessBoard.GameResultE.TieNoMove:
            case ChessBoard.GameResultE.TieNoMatePossible:
                if (bIncludeEnding)
                {
                    strRetVal += " 1/2-1/2";
                }
                break;

            default:
                break;
            }
            chessBoard.UndoMoveNoLog(move.Move);
            return(strRetVal);
        }