示例#1
0
        /// <summary>
        /// Parses one single move.
        /// </summary>
        /// <param name="_board">The current board , current opening book's game board</param>
        /// <param name="_pgnMove">the move's PGN notation</param>
        /// <param name="moves">A list of all availible moves</param>
        /// <returns>An opening move represents the parsed response.</returns>
        private static OpeningMove PGNMoveParser(Board _board, string _pgnMove, List <Move> moves)
        {
            bool isCapture = _pgnMove.Contains('x');

            bool test = false;

            if (test)
            {
                moves = MovesGenerator.GetLegalMoves(_board);
            }

            OpeningMove move = new OpeningMove();

            try
            {
                //first check if it is castle
                if (_pgnMove.StartsWith("O-O-O"))
                {
                    move.Move = moves.First(x => x.MoveType == MoveTypes.CastleQueenSide);
                }
                else if (_pgnMove.StartsWith("O-O"))
                {
                    move.Move = moves.First(x => x.MoveType == MoveTypes.CastleKingSide);
                }
                else
                {
                    int piece = PGNletterToPieceParser(_pgnMove[0], _board.CurrentPlayer);

                    var pieceMoves = moves.Where(x => x.MovingPiece == piece);



                    if (pieceMoves.Count() == 1)
                    {
                        move.Move = pieceMoves.ElementAt(0);
                    }
                    else
                    {
                        if (piece == Piece.BlackPawn || piece == Piece.WhitePawn)
                        {
                            var sourceMoves = pieceMoves.Where(x => x.SourceFile == _pgnMove[0]);
                            if (sourceMoves.Count() == 1)
                            {
                                move.Move = sourceMoves.ElementAt(0);
                            }
                            else
                            {
                                if (isCapture)
                                {
                                    string dest = _pgnMove.Substring(_pgnMove.IndexOf('x') + 1, 2);
                                    move.Move = sourceMoves.First(x => x.DestinationSquareString == dest);
                                }
                                else
                                {
                                    string dest = _pgnMove.Substring(0, 2);
                                    move.Move = sourceMoves.First(x => x.DestinationSquareString.StartsWith(dest));
                                }
                            }
                        }
                        else
                        {
                            IEnumerable <Move> destMoves;
                            if (isCapture)
                            {
                                string dest = _pgnMove.Substring(_pgnMove.IndexOf('x') + 1, 2);
                                destMoves = pieceMoves.Where(x => x.DestinationSquareString == dest);
                            }
                            else
                            {
                                int    indexDestRank = _pgnMove.LastIndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' });
                                string dest          = _pgnMove.Substring(indexDestRank - 1, 2);
                                destMoves = pieceMoves.Where(x => x.DestinationSquareString == dest);
                            }

                            switch (destMoves.Count())
                            {
                            case 1:
                                move.Move = destMoves.ElementAt(0);
                                break;

                            case 2:
                                //either rank or file ambiguity
                                if (_pgnMove[1] >= '1' && _pgnMove[1] <= '9')
                                {
                                    //rank ambiguity
                                    move.Move = destMoves.First(x => x.SourceRank == _pgnMove[1]);
                                }
                                else
                                {
                                    move.Move = destMoves.First(x => x.SourceFile == _pgnMove[1]);
                                }
                                break;

                            case 3:
                                move.Move = destMoves.First(x => x.SourceSquareString == _pgnMove.Substring(1, 2));
                                break;
                            }
                        }
                    }

                    //now get move type
                    if (_pgnMove.Contains("!!"))
                    {
                        move.MoveType = OpeningMoveType.Excellent;
                    }
                    else if (_pgnMove.Contains("!?"))
                    {
                        move.MoveType = OpeningMoveType.Interesting;
                    }
                    else if (_pgnMove.Contains("?!"))
                    {
                        move.MoveType = OpeningMoveType.Dubious;
                    }
                    else if (_pgnMove.Contains("!"))
                    {
                        move.MoveType = OpeningMoveType.Good;
                    }
                    else if (_pgnMove.Contains("??"))
                    {
                        move.MoveType = OpeningMoveType.Blunder;
                    }
                    else if (_pgnMove.Contains("?"))
                    {
                        move.MoveType = OpeningMoveType.Bad;
                    }
                }

                if (move.Move == null)
                {
                    throw new System.Exception("not found");
                }

                return(move);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
示例#2
0
        /// <summary>
        /// Parses the book string in the standard PGN format, and inserts it into the starting position node
        /// </summary>
        /// <param name="book">A standard PGN formatted string</param>
        /// <param name="startingPoint">The starting node to add responses to</param>
        private static void AnalyzeBook(string book, OpeningMove startingPoint)
        {
            try
            {
                string[] tags = book.Replace("\r\n", " ").Split(new string[] { "[" }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 6; i < tags.Length; i += 7)
                {
                    string   movesString = tags[i].Substring(tags[i].IndexOf(']') + 1);
                    string[] movesArray  = movesString.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

                    Board board = new Board();
                    board.StartingPosition();

                    //parentMove will slide, containing the parent to the move.
                    OpeningMove parentMove = startingPoint;
                    bool        abortMatch = false;

                    for (int j = 0; j < movesArray.Length && !abortMatch; j++)
                    {
                        if (j % 3 == 0)
                        {
                            continue;
                        }

                        if (parentMove.LegalMoves == null)
                        {
                            parentMove.LegalMoves = MovesGenerator.GetLegalMoves(board);
                        }

                        OpeningMove move = PGNMoveParser(board, movesArray[j], parentMove.LegalMoves);

                        if (move.MoveType != OpeningMoveType.Excellent && move.MoveType != OpeningMoveType.Good)
                        {
                            abortMatch = true;
                            break;
                        }

                        //to avoid duplicate entries problem, we make sure to use same instance of a move.
                        OpeningMove storedSameMove = parentMove.Responses.FirstOrDefault(x => x.Move.EqualMove(move.Move));

                        if (storedSameMove == null)
                        {
                            move.Count = 1;
                            parentMove.Responses.Add(move);
                        }
                        else
                        {
                            parentMove.Count++;
                            move = storedSameMove;
                        }

                        parentMove = move;

                        board.ApplyMove(move.Move);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }