Example #1
0
    /// <summary>
    /// Read the notations in the provided string.
    /// </summary>
    /// <param name="curgame">the string to decipher.</param>
    public void Read(string curgame)
    {
        int          lastIndex = 0;
        int          nextIndex = 0;
        string       move      = curgame.Substring(lastIndex, nextIndex);
        NotationType ntype     = NotationType.Algebraic; //= NotationType.Coordinate;

        //Debug.Log("first move:" + move);
        //if (move.Contains("-")) ntype = NotationType.Coordinate;
        moves = new List <cgSimpleMove>();
        if (ntype == NotationType.Coordinate)
        {
            while (lastIndex != -1)
            {
                byte fromp = board.IndexFromCellName(move.Substring(0, 2));
                byte top   = board.IndexFromCellName(move.Substring(3, 2));
                moves.Add(new cgSimpleMove(fromp, top));
                nextIndex = curgame.IndexOf(" ", lastIndex + 1);
                if (nextIndex == -1)
                {
                    break;
                }
                move      = curgame.Substring(lastIndex + 1, nextIndex - lastIndex);
                lastIndex = nextIndex;
                //Debug.Log("current move being analyzed="+move);
            }
        }
        else if (ntype == NotationType.Algebraic)
        {
            cgBoard      disambBoard = new cgBoard();
            cgSimpleMove chosenMove;
            while (lastIndex != -1)
            {
                chosenMove = null;

                nextIndex = curgame.IndexOf(" ", nextIndex + 1);
                if (nextIndex == -1 || lastIndex == -1)
                {
                    break;
                }
                move = curgame.Substring(lastIndex + 1, nextIndex - lastIndex);
                bool legitMove = (!move.Contains(".") && move.Length > 1 && !move.Contains("\n")) ? true : false;

                move = move.Trim(' ');
                //move = move.Trim('\n');
                //Debug.Log("trimmed:" + move+" contains .:"+move.Contains(".")+" contains newline:"+move.Contains("\n")+" legit move:"+legitMove);
                if (move.Contains("{"))
                {
                    nextIndex = curgame.IndexOf("}", lastIndex + 1);
                }
                else if (move.Contains("["))
                {
                    nextIndex = curgame.IndexOf("]", lastIndex + 1);
                }
                else if (legitMove)
                {
                    //Debug.Log("found to be legit move.");
                    byte tosquare;
                    byte pushback = 2;
                    byte type     = 1;
                    //bool promotion = false;
                    bool shortCastling = (move == "O-O");
                    bool longCastling  = (move == "O-O-O");
                    if (move.Contains("="))
                    {
                        //promotion = true;
                        move.Remove(move.IndexOf("="), 2);
                    }
                    else if (move.Contains("+"))
                    {
                        move.Remove(move.IndexOf("+"), 1);
                    }
                    else if (move.Contains("!"))
                    {
                        move.Remove(move.IndexOf("!"), 1);
                    }
                    else if (move.Contains("?"))
                    {
                        move.Remove(move.IndexOf("?"), 1);
                    }
                    tosquare = board.IndexFromCellName(move.Substring(move.Length - pushback, 2));
                    if (move[0] == 'R')
                    {
                        type = 2;
                    }
                    if (move[0] == 'N')
                    {
                        type = 3;
                    }
                    if (move[0] == 'B')
                    {
                        type = 4;
                    }
                    if (move[0] == 'Q')
                    {
                        type = 5;
                    }
                    if (move[0] == 'K')
                    {
                        type = 6;
                    }

                    List <cgSimpleMove> ambiguousMoves = new List <cgSimpleMove>();
                    foreach (cgSimpleMove legalMove in disambBoard.findLegalMoves(disambBoard.whiteTurnToMove))
                    {
                        if (shortCastling && legalMove is cgCastlingMove)
                        {
                            if (legalMove.to == 6 || legalMove.to == 62)
                            {
                                chosenMove = legalMove;
                                break;
                            }
                        }
                        else if (longCastling && legalMove is cgCastlingMove)
                        {
                            if (legalMove.to == 2 || legalMove.to == 58)
                            {
                                chosenMove = legalMove;
                                break;
                            }
                        }
                        if (Math.Abs(disambBoard.squares[legalMove.from]) == type && legalMove.to == tosquare)
                        {
                            ambiguousMoves.Add(legalMove);
                        }
                    }
                    if (ambiguousMoves.Count == 0 && chosenMove == null)
                    {
                        //Debug.WriteLine("found no matching move for the string: " + move+" type:"+type+" tosquare:"+tosquare+" chosenMove:"+chosenMove+" castling:"+shortCastling);
                        break;
                    }
                    else if (ambiguousMoves.Count == 1)
                    {
                        chosenMove = ambiguousMoves[0];
                    }
                    else if (ambiguousMoves.Count > 1)
                    {
                        //UnityEngine.Debug.Log("2 or mroe ambiguousmoves");
                        //2 or more ambiguous moves in which the piece type matches and the destination square matches. Further disambiguation needed.
                        List <cgSimpleMove> matching = new List <cgSimpleMove>();
                        foreach (cgSimpleMove mov in ambiguousMoves)
                        {
                            if (board.SquareNames[mov.from].Contains(move.Substring(1 + (type == 1?-1:0), 1)))
                            {
                                matching.Add(mov);
                            }
                        }

                        if (matching.Count == 1)
                        {
                            chosenMove = matching[0];                     //only 1 of the ambiguous moves have the correct rank and/or file.
                        }
                        else
                        {
                            foreach (cgSimpleMove mov in ambiguousMoves)
                            {
                                if (board.SquareNames[mov.from].Contains(move.Substring(1, 2)))
                                {
                                    chosenMove = ambiguousMoves[0];
                                    break;
                                }
                            }
                        }
                    }
                    if (chosenMove != null)
                    {
                        disambBoard.move(chosenMove);
                        moves.Add(chosenMove);
                    }
                }
                Debug.WriteLine("legitmove:" + legitMove);
                lastIndex = nextIndex;
            }
        }
    }