예제 #1
0
        /// <summary>
        /// Given a FEN, return a list of ChessPiece objects descibed by the FEN
        /// </summary>
        /// <param name="fen">FEN input</param>
        /// <returns>ChessPieces contained in the FEN description</returns>
        public static List <ChessPiece> ExtractPieces(string fen)
        {
            string[] fenTokens = TokenizeFEN(fen);
            // The first part describes the pieces...
            string fenString = fenTokens[0];
            // Create a new list for the pieces we'll find
            List <ChessPiece> pieces = new List <ChessPiece>();

            int currentRank = 8; // 8 - back rank for Black
            int currentFile = 1; // A
            int index       = 0;

            // Token can be 1-8 characters long per rank plus separators, so not long
            while (index < fenString.Length)
            {
                char fenChar = fenString[index++]; // Save the current char

                if (Char.IsLetter(fenChar))
                {
                    // Uppercase is white, lower black
                    PieceColor color = Char.IsUpper(fenChar) ? PieceColor.White : PieceColor.Black;

                    // Create the new ChessPiece object at the given location
                    ChessPiece newPiece = new ChessPiece(color,
                                                         ChessBoard.PieceClassFromFen(fenChar), new PieceFile(currentFile), currentRank);

                    // Need to update deployed for pawns not on their home ranks
                    if (newPiece.Job == PieceClass.Pawn)
                    {
                        int homeRank = (newPiece.Color == PieceColor.White) ? 2 : 7;
                        if (newPiece.Rank != homeRank)
                        {
                            newPiece.Deployed = true;
                        }
                    }

                    pieces.Add(newPiece); // Add it to our total list of pieces
                    currentFile++;
                }
                else if (Char.IsDigit(fenChar))
                {
                    // Digits represent empty squares and are RLE (run length encoded) like a bitmap
                    // advance File the amount of the spaces specified
                    currentFile += (Convert.ToUInt16(fenChar) - Convert.ToUInt16('0'));
                }
                else if (fenChar == '/')
                {
                    // The '/' denotes the end of a rank on the chess board
                    // decrement Rank and reset the File (like a newline)
                    currentRank--;
                    currentFile = 1;
                }
            }

            // Return all of the pieces found
            return(pieces);
        }
예제 #2
0
        /// <summary>
        /// Invoked when the chess engine has responded with a move to apply to the
        /// local board
        /// </summary>
        private void OnEngineBestMoveResponse()
        {
            thinkingIndex = 0;  // reset index counter for simple progress text

            // Get the best move from the engine
            string bestMove = engine.BestMove;

            if ((String.Compare(bestMove, "(none)") == 0) || // Stockfish (and converted ones)
                (String.Compare(bestMove, "a1a1") == 0) ||   // Rybka
                (board.HalfMoveCount >= HalfMovesUntilDraw)) // Propably spinning on self play or just a draw
            {
                if (board.HalfMoveCount >= HalfMovesUntilDraw)
                {
                    Debug.WriteLine("Draw by 50 moves rule...");
                }
                GameOverHandler();
            }
            else if (GetInputState() == InputState.WaitingOnOpponentMove)
            {
                // Extract the board location from the move string
                PieceFile startFile = new PieceFile(bestMove[0]);
                int       startRank = Convert.ToInt16(bestMove[1]) - Convert.ToInt16('0');
                PieceFile destFile  = new PieceFile(bestMove[2]);
                int       destRank  = Convert.ToInt16(bestMove[3]) - Convert.ToInt16('0');

                ChessPiece      foundPiece = board.FindPieceAt(startFile, startRank);
                MoveInformation moveInfo   = new MoveInformation(
                    new BoardSquare(startFile, startRank),
                    new BoardSquare(destFile, destRank),
                    foundPiece.Deployed, board.CurrentFEN);

                moveInfo.Color          = foundPiece.Color;
                moveInfo.CastlingRights = board.ActivePlayerCastlingRights;

                // When coming from the engine, we get the promotion detection for free
                if (bestMove.Length == 5)
                {
                    // Applied on the next move
                    PieceClass promotionJob = ChessBoard.PieceClassFromFen(bestMove[4]);
                    board.PromotePiece(startFile, startRank, destFile, destRank, promotionJob, ref moveInfo);
                }

                // Move the piece on the board, and add it to the official moves list
                board.MovePiece(ref moveInfo);

                // trigger a redraw
                view.Invalidate();

                // Apply the move the engine just gave us with the engine (update it's own move)
                UpdateEnginePosition();
            }
        }