public string GetLineage()
            {
                double deltaY  = Predecessor == null ? 0 : Y - Predecessor.Y;
                string past    = Predecessor == null ? "" : Predecessor.GetLineage();
                string current = ToString() + " " + deltaY + "\r\n";

                return(past + current);
            }
        public static void Test()
        {
            double        startX         = -2838;
            double        startY         = 1610.8349609375;
            double        startZ         = -42.8171844482422;
            List <double> initialHSpeeds = new List <double>()
            {
                -427922.90625, -641883.5, -962824.375, -1444235.625, -2166352.75, -3249528.25,
            };
            double goalX = 2806.789063;
            double goalY = 1033;
            double goalZ = -130.9819946;

            flatFloorTris = TriangleUtilities.GetLevelTriangles()
                            .FindAll(tri => tri.IsFloor() && tri.NormY == 1 && tri.SurfaceType != 0x0A);
            possibleAngles = Enumerable.Range(0, 4096).ToList().ConvertAll(i => 16 * i);

            List <double> moreHSpeeds = initialHSpeeds.ConvertAll(
                hSpeed => GetSuccessiveHSpeeds(hSpeed)).SelectMany(list => list).ToList();

            initialHSpeeds.AddRange(moreHSpeeds);
            initialHSpeeds = ControlUtilities.Randomize(initialHSpeeds);

            Queue <MarioPuState> queue = new Queue <MarioPuState>();

            initialHSpeeds.ForEach(hSpeed => queue.Enqueue(
                                       new MarioPuState(startX, startY, startZ, hSpeed, 0, null, 0)));

            Config.Print("START");
            int lastIndex = -1;

            while (queue.Count > 0)
            {
                MarioPuState dequeue = queue.Dequeue();
                if (dequeue.Index > lastIndex)
                {
                    lastIndex = dequeue.Index;
                    Config.Print("Now on index " + lastIndex);
                }

                List <int> anglesToUse;
                if (dequeue.Index < 2)
                {
                    anglesToUse = possibleAngles;
                }
                else
                {
                    int angle = MoreMath.NormalizeAngleTruncated(MoreMath.AngleTo_AngleUnits(goalX, goalZ, dequeue.X, dequeue.Z));
                    anglesToUse = new List <int>()
                    {
                        angle - 16, angle, angle + 16
                    };
                }

                foreach (int angle in anglesToUse)
                {
                    MarioPuState state = TestOverflowJump(dequeue, angle);
                    if (state == null)
                    {
                        continue;
                    }

                    double dist = MoreMath.GetDistanceBetween(state.X, state.Z, goalX, goalZ);
                    if (state.Index >= 2 && dist > Math.Abs(state.HSpeed))
                    {
                        continue;
                    }
                    if (dist < 1000 && state.Y == goalY)
                    {
                        Config.Print(dist);
                        Config.Print(state.GetLineage());
                    }

                    if (state.Index >= 3)
                    {
                        continue;
                    }
                    List <MarioPuState> nextStates = GetSuccessiveStates(state);
                    nextStates.Insert(0, state);
                    nextStates = ControlUtilities.Randomize(nextStates);
                    nextStates.ForEach(s => queue.Enqueue(s));
                }
            }
            Config.Print("END");
        }