Exemplo n.º 1
0
        private MathList?BuildInternal(bool oneCharOnly, char stopChar = '\0', MathList?r = null)
        {
            if (oneCharOnly && stopChar > '\0')
            {
                throw new InvalidCodePathException("Cannot set both oneCharOnly and stopChar");
            }
            r ??= new MathList();
            MathAtom?prevAtom = null;

            while (HasCharacters)
            {
                if (Error != null)
                {
                    return(null);
                }
                MathAtom atom;
                switch (GetNextCharacter())
                {
                case var ch when oneCharOnly && (ch == '^' || ch == '}' || ch == '_' || ch == '&'):
                    SetError($"{ch} cannot appear as an argument to a command");
                    return(r);

                case var ch when stopChar > '\0' && ch == stopChar:
                    return(r);

                case '^':
                    if (prevAtom == null || prevAtom.Superscript.IsNonEmpty() || !prevAtom.ScriptsAllowed)
                    {
                        prevAtom = new Ordinary(string.Empty);
                        r.Add(prevAtom);
                    }
                    // this is a superscript for the previous atom.
                    // note, if the next char is StopChar, it will be consumed and doesn't count as stop.
                    this.BuildInternal(true, r: prevAtom.Superscript);
                    if (Error != null)
                    {
                        return(null);
                    }
                    continue;

                case '_':
                    if (prevAtom == null || prevAtom.Subscript.IsNonEmpty() || !prevAtom.ScriptsAllowed)
                    {
                        prevAtom = new Ordinary(string.Empty);
                        r.Add(prevAtom);
                    }
                    // this is a subscript for the previous atom.
                    // note, if the next char is StopChar, it will be consumed and doesn't count as stop.
                    this.BuildInternal(true, r: prevAtom.Subscript);
                    if (Error != null)
                    {
                        return(null);
                    }
                    continue;

                case '{':
                    MathList?sublist;
                    if (_currentEnvironment != null && _currentEnvironment.Name == null)
                    {
                        // \\ or \cr which do not have a corrosponding \end
                        var oldEnv = _currentEnvironment;
                        _currentEnvironment = null;
                        sublist             = BuildInternal(false, '}');
                        _currentEnvironment = oldEnv;
                    }
                    else
                    {
                        sublist = BuildInternal(false, '}');
                    }
                    if (sublist == null)
                    {
                        return(null);
                    }
                    prevAtom = sublist.Atoms.LastOrDefault();
                    r.Append(sublist);
                    if (oneCharOnly)
                    {
                        return(r);
                    }
                    continue;

#warning TODO Example
                //https://phabricator.wikimedia.org/T99369
                //https://phab.wmfusercontent.org/file/data/xsimlcnvo42siudvwuzk/PHID-FILE-bdcqexocj5b57tj2oezn/math_rendering.png
                //dt, \text{d}t, \partial t, \nabla\psi \\ \underline\overline{dy/dx, \text{d}y/\text{d}x, \frac{dy}{dx}, \frac{\text{d}y}{\text{d}x}, \frac{\partial^2}{\partial x_1\partial x_2}y} \\ \prime,
                case '}' when oneCharOnly || stopChar != 0:
                    throw new InvalidCodePathException("This should have been handled before.");

                case '}':
                    SetError("Missing opening brace");
                    return(null);

                case '\\':
                    var command = ReadCommand();
                    var done    = StopCommand(command, r, stopChar);
                    if (done != null)
                    {
                        return(done);
                    }
                    if (Error != null)
                    {
                        return(null);
                    }
                    if (ApplyModifier(command, prevAtom))
                    {
                        continue;
                    }
                    if (LaTeXSettings.FontStyles.TryGetValue(command, out var fontStyle))
                    {
                        var oldSpacesAllowed = _textMode;
                        var oldFontStyle     = _currentFontStyle;
                        _textMode         = (command == "text");
                        _currentFontStyle = fontStyle;
                        var childList = BuildInternal(true);
                        if (childList == null)
                        {
                            return(null);
                        }
                        _currentFontStyle = oldFontStyle;
                        _textMode         = oldSpacesAllowed;
                        prevAtom          = childList.Atoms.LastOrDefault();
                        r.Append(childList);
                        if (oneCharOnly)
                        {
                            return(r);
                        }
                        continue;
                    }
                    switch (AtomForCommand(command, stopChar))
                    {
                    case null:
                        SetError(Error ?? "Internal error");
                        return(null);

                    case var a:
                        atom = a;
                        break;
                    }
                    break;

                case '&': // column separation in tables
                    if (_currentEnvironment != null)
                    {
                        return(r);
                    }
                    var table = BuildTable(null, r, false, stopChar);
                    if (table == null)
                    {
                        return(null);
                    }
                    return(new MathList(table));

                case '\'': // this case is NOT in iosMath
                    int i = 1;
                    while (ExpectCharacter('\''))
                    {
                        i++;
                    }
                    atom = new Prime(i);
                    break;

                case ' ' when _textMode:
                    atom = new Ordinary(" ");
                    break;

                case var ch when ch <= sbyte.MaxValue:
                    if (LaTeXSettings.ForAscii((sbyte)ch) is MathAtom asciiAtom)
                    {
                        atom = asciiAtom;
                    }
                    else
                    {
                        continue; // Ignore ASCII spaces and control characters
                    }
                    break;

                case var ch:
                    // not a recognized character, display it directly
                    atom = new Ordinary(ch.ToStringInvariant());
                    break;
                }
                atom.FontStyle = _currentFontStyle;
                r.Add(atom);
                prevAtom = atom;
                if (oneCharOnly)
                {
                    return(r); // we consumed our character.
                }
            }
            if (stopChar > 0)
            {
                if (stopChar == '}')
                {
                    SetError("Missing closing brace");
                }
                else
                {
                    // we never found our stop character.
                    SetError("Expected character not found: " + stopChar.ToStringInvariant());
                }
            }
            return(r);
        }
Exemplo n.º 2
0
 void Start()
 {
     anim  = general.GetComponent <Animator>();
     anim2 = Helmet.GetComponent <Animator>();
     anim3 = Ordinary.GetComponent <Animator>();
 }
Exemplo n.º 3
0
        public override List <Move> GenerateMoves(Board board)
        {
            var  moves = new List <Move>();
            Move move;

            if (Color == Color.White)
            {
                var upSquare = From.To(Coordinate.Directions.North);
                if (upSquare.IsEmpty(board) && From.Rank != 7)//Pawn can go up if it is empty square
                {
                    move = new Ordinary(board, this, upSquare);
                    moves.Add(move);
                    var twoUpSquare = upSquare.To(Coordinate.Directions.North);
                    if (From.Rank == 2 && twoUpSquare.IsEmpty(board))//Check can jump 2 square when it is on rank 2
                    {
                        move = new Ordinary(board, this, twoUpSquare);
                        moves.Add(move);
                    }
                }

                if (From.Rank != 7)
                {
                    Coordinate crossSquare = From.To(Coordinate.Directions.NorthEast);
                    //Check for capture
                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.Black)
                    {
                        moves.Add(new Ordinary(board, this, crossSquare));
                    }

                    crossSquare = From.To(Coordinate.Directions.NorthWest);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.Black)
                    {
                        moves.Add(new Ordinary(board, this, crossSquare));
                    }
                }
                if (From.Rank == 5)//Check possibility of enpassant move
                {
                    var crossSquare = From.To(Coordinate.Directions.NorthEast);

                    if (crossSquare.IsOnboard() && crossSquare.Equals(board.EnPassantSquare))
                    {
                        moves.Add(new EnPassant(board, this, crossSquare));
                    }
                    else
                    {
                        crossSquare = From.To(Coordinate.Directions.NorthWest);

                        if (crossSquare.IsOnboard() && crossSquare.Equals(board.EnPassantSquare))
                        {
                            moves.Add(new EnPassant(board, this, crossSquare));
                        }
                    }
                }
                if (From.Rank == 7)//Check pawn promotions
                {
                    upSquare = From.To(Coordinate.Directions.North);

                    if (upSquare.IsEmpty(board))
                    {
                        moves.AddRange(Promote.AllPossiblePromotions(board, this, upSquare));
                    }

                    var crossSquare = From.To(Coordinate.Directions.NorthEast);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.Black)
                    {
                        moves.AddRange(Promote.AllPossiblePromotions(board, this, crossSquare));
                    }

                    crossSquare = From.To(Coordinate.Directions.NorthWest);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.Black)
                    {
                        moves.AddRange(Promote.AllPossiblePromotions(board, this, crossSquare));
                    }
                }
            }
            else // For black pawn
            {
                var downSquare = From.To(Coordinate.Directions.South);
                if (downSquare.IsEmpty(board) && From.Rank != 2)
                {
                    moves.Add(new Ordinary(board, this, downSquare));

                    var twoDownSquare = downSquare.To(Coordinate.Directions.South);

                    if (From.Rank == 7 && twoDownSquare.IsEmpty(board))
                    {
                        moves.Add(new Ordinary(board, this, twoDownSquare));
                    }
                }

                if (From.Rank != 2)
                {
                    var crossSquare = From.To(Coordinate.Directions.SouthEast);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.White)
                    {
                        moves.Add(new Ordinary(board, this, crossSquare));
                    }

                    crossSquare = From.To(Coordinate.Directions.SouthWest);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.White)
                    {
                        moves.Add(new Ordinary(board, this, crossSquare));
                    }
                }

                if (From.Rank == 4)
                {
                    var crossSquare = From.To(Coordinate.Directions.SouthEast);

                    if (crossSquare.IsOnboard() && crossSquare.Equals(board.EnPassantSquare))
                    {
                        moves.Add(new EnPassant(board, this, crossSquare));
                    }
                    else
                    {
                        crossSquare = From.To(Coordinate.Directions.SouthWest);
                        if (crossSquare.IsOnboard() && crossSquare.Equals(board.EnPassantSquare))
                        {
                            moves.Add(new EnPassant(board, this, crossSquare));
                        }
                    }
                }
                if (From.Rank == 2)
                {
                    downSquare = From.To(Coordinate.Directions.South);

                    if (downSquare.IsEmpty(board))
                    {
                        moves.AddRange(Promote.AllPossiblePromotions(board, this, downSquare));
                    }

                    var crossSquare = From.To(Coordinate.Directions.SouthEast);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.White)
                    {
                        moves.AddRange(Promote.AllPossiblePromotions(board, this, crossSquare));
                    }

                    crossSquare = From.To(Coordinate.Directions.SouthWest);

                    if (crossSquare.IsOnboard() && !crossSquare.IsEmpty(board) && crossSquare.GetPiece(board).Color == Color.White)
                    {
                        moves.AddRange(Promote.AllPossiblePromotions(board, this, crossSquare));
                    }
                }
            }

            return(moves);
        }