Exemplo n.º 1
0
    /// Returns a list of moves given a pgn string.
    /// Note that Board should be set to whatever starting position of pgn is.
    public static List <ushort> MovesFromPGN(string pgn)
    {
        List <string> moveStrings = MoveStringsFromPGN(pgn);
        List <ushort> allMoves    = new List <ushort> ();

        MoveGenerator moveGen = new MoveGenerator();

        for (int i = 0; i < moveStrings.Count; i++)
        {
            string moveString = moveStrings[i];

            moveString = moveString.Replace("+", "");            // remove check symbol
            moveString = moveString.Replace("#", "");            // remove mate symbol
            moveString = moveString.Replace("x", "");            // remove capture symbol
            string moveStringLower = moveStrings[i].ToLower();

            ushort[] movesInPosition = moveGen.GetMoves(false, false).moves;
            ushort   move            = 0;
            for (int j = 0; j < movesInPosition.Length; j++)
            {
                move = movesInPosition[j];
                int moveFromIndex = move & 127;
                int moveToIndex   = (move >> 7) & 127;
                int movePieceType = Board.boardArray[moveFromIndex] & ~1;
                int colourCode    = Board.boardArray[moveFromIndex] & 1;


                if (moveStringLower == "oo")                   // castle kingside
                {
                    if (movePieceType == Board.kingCode && moveToIndex - moveFromIndex == 2)
                    {
                        break;
                    }
                }
                else if (moveStringLower == "ooo")                   // castle queenside
                {
                    if (movePieceType == Board.kingCode && moveToIndex - moveFromIndex == -2)
                    {
                        break;
                    }
                }
                else if (Definitions.fileNames.Contains(moveString[0] + ""))                   // pawn move if starts with any file indicator (e.g. 'e'4. Note that uppercase B is used for bishops)
                {
                    if (movePieceType != Board.pawnCode)
                    {
                        continue;
                    }
                    if (Definitions.FileNumberFromAlgebraicName(moveStringLower[0]) == Board.FileFrom128(moveFromIndex)) // correct starting file
                    {
                        if (moveString.Contains("="))                                                                    // is promotion
                        {
                            char promotionChar = moveStringLower[moveStringLower.Length - 1];

                            int promotionPieceIndex = move >> 14 & 3;
                            int promotionPieceCode  = Board.pieceCodeArray [promotionPieceIndex];

                            if ((promotionPieceCode == Board.queenCode && promotionChar != 'q') || (promotionPieceCode == Board.rookCode && promotionChar != 'r') ||
                                (promotionPieceCode == Board.bishopCode && promotionChar != 'b') || (promotionPieceCode == Board.knightCode && promotionChar != 'n'))
                            {
                                continue;                                 // skip this move, incorrect promotion type
                            }
                            break;
                        }
                        else
                        {
                            char targetFile = moveString[moveString.Length - 2];
                            char targetRank = moveString[moveString.Length - 1];

                            if (Definitions.FileNumberFromAlgebraicName(targetFile) == Board.FileFrom128(moveToIndex))                               // correct ending file
                            {
                                if (Definitions.RankNumberFromAlgebraicName(targetRank) == Board.RankFrom128(moveToIndex))                           // correct ending rank
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                else                   // regular piece move

                {
                    char movePieceChar = moveString[0];
                    if (!(movePieceType == Board.queenCode && movePieceChar == 'Q') && !(movePieceType == Board.rookCode && movePieceChar == 'R') &&
                        !(movePieceType == Board.bishopCode && movePieceChar == 'B') && !(movePieceType == Board.knightCode && movePieceChar == 'N') && !(movePieceType == Board.kingCode && movePieceChar == 'K'))
                    {
                        continue;                         // skip this move, incorrect move piece type
                    }

                    char targetFile = moveString[moveString.Length - 2];
                    char targetRank = moveString[moveString.Length - 1];
                    if (Definitions.FileNumberFromAlgebraicName(targetFile) == Board.FileFrom128(moveToIndex))     // correct ending file
                    {
                        if (Definitions.RankNumberFromAlgebraicName(targetRank) == Board.RankFrom128(moveToIndex)) // correct ending rank
                        {
                            if (moveString.Length == 4)                                                            // addition char present for disambiguation (e.g. Nbd7 or R7e2)
                            {
                                char disambiguationChar = moveString[1];

                                if (Definitions.fileNames.Contains(disambiguationChar + ""))                                             // is file disambiguation
                                {
                                    if (Definitions.FileNumberFromAlgebraicName(disambiguationChar) != Board.FileFrom128(moveFromIndex)) // incorrect starting file
                                    {
                                        continue;
                                    }
                                }
                                else                                                                                                     // is rank disambiguation
                                {
                                    if (Definitions.RankNumberFromAlgebraicName(disambiguationChar) != Board.RankFrom128(moveFromIndex)) // incorrect starting rank
                                    {
                                        continue;
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            }
            if (move == 0)               // move is illegal; discard and return moves up to this point
            {
                UnityEngine.Debug.Log(moveString);
                break;
            }
            else
            {
                allMoves.Add(move);
            }
            Board.MakeMove(move);
        }
        for (int i = allMoves.Count - 1; i >= 0; i--)
        {
            Board.UnmakeMove(allMoves[i]);
        }

        return(allMoves);
    }