Home > Software design >  SOLVED C# OutOfRangeException that should be impossible
SOLVED C# OutOfRangeException that should be impossible

Time:07-06

Solution: I was making a new list depended on another list that got modified, I had to make a clone of the other list first.

I am so confessed right now I don't even know how to properly form this question. I have some code (as shown below) that is run on a different thread with the variable i not being referenced anywhere else that could interfere with it here. I just don't understand what is happening to cause this error, I put some watchers down with visual studio code and the values all seem to be fine and in range but almost randomly out of nowhere I will get this error.

Is it possible that this is caused by another section of code despite to my best knowledge being completely isolated from it? I even went as far to rename all other uses of i to different letters and I still get this problem.

Is it just something with for loops?

Am I somehow modifying i without even know it?

I just don't even know what to ask.

My code

Here is the full code `

using SFML.Graphics;
using SFML.Window;
using System.Diagnostics;
using System.Numerics;

namespace RenderEngine
{
    public class Program
    {

        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            PhysicsEngine re = new PhysicsEngine();
            for (int i = 0; i < 100; i  )
            {
                Debug.WriteLine(i);
            }

        }
    }
    public class PhysicsEngine
    {
        Solver solver = new Solver();
        public void RenderEngine2()
        {
            ContextSettings settings = new ContextSettings();
            settings.AntialiasingLevel = 8;
            RenderWindow window = new RenderWindow(new VideoMode(2000, 1000), "Poop", Styles.Default, settings);
            SFML.Graphics.Color color = new SFML.Graphics.Color(0, 0, 0, 0);
            window.SetVerticalSyncEnabled(true);
            CircleShape shape = new CircleShape(5);
            shape.FillColor = new SFML.Graphics.Color(0, 0, 255, 255);
            window.Closed  = handelclose;
            int drawcount = 0;
            while (window.IsOpen)
            {
                window.Clear(color);
                window.DispatchEvents();
                try
                {
                    foreach (Partical partical in solver.Particals)
                    {
                        shape.Position = new SFML.System.Vector2f((partical.position.X), (partical.position.Y));
                        window.Draw(shape);
                        drawcount  ;
                    }
                    drawcount = 0;
                }
                catch
                {
                    Debug.WriteLine("notready yet");
                }

                window.Display();

            }
            void handelclose(object sender, EventArgs e)
            {
                window.Close();
                Environment.Exit(Environment.ExitCode);
            }
        }
        List<Partical> todraw = new List<Partical>();
        void EngineLoop()
        {
            while (true)
            {
                foreach (Partical partical in solver.Particals)
                {
                    int x = (int)Math.Round(partical.position.X/10);
                    int y = (int)Math.Round(partical.position.Y/10);
                    List<int> ts = solver.Grid[x, y];
                    if (ts != null)
                    {
                        for (int brokenint = 0; brokenint < ts.Count; brokenint  )
                        {
                            Debug.WriteLine(partical.ID);
                            Debug.WriteLine(ts[brokenint]);
                            if (partical.ID != ts[brokenint])
                            {
                                
                                Vector2 pos = new Vector2(partical.ID, ts[brokenint]);
                                if (solver.Collision.Count > 0)
                                {
                                    if (!solver.Collision.Contains(pos))
                                        solver.Collision.Add(pos);
                                }
                                else
                                {
                                    solver.Collision.Add(pos);
                                }
                            }
                        }
                    }
                }
            }
        }
        private int particalcount = 10;
        bool canstart = false;
        public PhysicsEngine()
        {
            Parallel.Invoke(() =>
            {
                while (!canstart) { Thread.Sleep(100); }
                Debug.WriteLine("third thread");
                RenderEngine2();

            },
            () =>
            {
                while (!canstart) { Thread.Sleep(100); }
                Debug.WriteLine("engine started");
                EngineLoop();
            },
            () =>
            {
                Debug.WriteLine("first thread");
                PhysicsLoop(this);
            }
            );
        }
        void PhysicsLoop(PhysicsEngine PhyEng)
        {
            int frames = 0;
            long second = 0;
            PhysicsStart(PhyEng);
            Thread.Sleep(1000);
            Stopwatch sw = Stopwatch.StartNew();
            solver.startupdate();
            while (true)
            {
                sw.Start();
                todraw = solver.Particals;
                solver.update();
                frames  ;
                if (second != (Stopwatch.GetTimestamp() / Stopwatch.Frequency))
                {
                    second = (Stopwatch.GetTimestamp() / Stopwatch.Frequency);
                    Debug.WriteLine(frames);
                    frames = 0;
                }
                sw.Stop();
                sw.Reset();
                if (sw.ElapsedMilliseconds < 15)
                    Thread.Sleep(15 - (int)sw.ElapsedMilliseconds);
            }
        }
        void PhysicsStart(PhysicsEngine phyeng)
        {
            for (int i = 0; i < 210; i  )
            {
                for (int j = 0; j < 110; j  )
                {
                    solver.Grid[i,j] = new List<int>();
                }
            }

            Random rand = new Random();
            for (int i = 0; i < particalcount; i  )
            {
                Partical partical = new Partical();
                partical.position = new Vector2(rand.Next(0, 2000), rand.Next(0, 1000));
                partical.oldposition = partical.position;
                partical.ID = i;
                int x1 = (int)Math.Round((partical.position.X   5) / 10);
                int y1 = (int)Math.Round((partical.position.Y   5) / 10);
                int x2 = (int)Math.Round((partical.position.X - 5) / 10);
                int y2 = (int)Math.Round((partical.position.Y - 5) / 10);
                solver.Grid[x1, y1].Add(partical.ID);
                solver.Grid[x2, y1].Add(partical.ID);
                solver.Grid[x1, y2].Add(partical.ID);
                solver.Grid[x2, y2].Add(partical.ID);
                solver.Particals.Add(partical);
            }
            canstart = true;
        }
    }
    public class Partical
    {
        public Vector2 position = new Vector2(0, 0);
        public Vector2 oldposition = new Vector2(0, 0);
        public Vector2 acceleration = new Vector2(0, 0);
        Vector2 zero = new Vector2(0, 0);
        public int ID = new int();

        public void updatePosition(float sub)
        {
            Vector2 velocity = position - oldposition;
            oldposition = position;
            position = position   (velocity * 0.9f)   acceleration * sub;
            acceleration = zero;
        }
        public void accelerate(Vector2 accel)
        {
            acceleration = acceleration   accel;
        }
    }

    public class Solver
    {
        public List<Partical> Particals = new List<Partical>();
        public List<Vector2> Collision = new List<Vector2>();
        public List<int>[,] Grid = new List<int>[2100,1100];
        public void update()
        {
            int subcount = 8;
            float sub = 1f / (float)subcount;
            for (int i = 0; i < subcount; i  )
            {
                applyGravity(sub);
                updatePositions(sub);
                for (int j = 0; j < Collision.Count; j  )
                {
                    solvecolisions((int)Collision[j].X, (int)Collision[j].Y);
                }
                Collision.Clear();
            }
        }
        public void startupdate()
        {
            applyGravity(0.5f);
            updatePositions(0.5f);
            applyGravity(0.5f);
            updatePositions(0.5f);
        }
        void updatePositions(float sub)
        {
            foreach (Partical partical in Particals)
            {
                partical.updatePosition(sub);
                    int x1 = (int)Math.Round((partical.oldposition.X   5) / 10);
                    int y1 = (int)Math.Round((partical.oldposition.Y   5) / 10);
                    int x2 = (int)Math.Round((partical.oldposition.X - 5) / 10);
                    int y2 = (int)Math.Round((partical.oldposition.Y - 5) / 10);
                    Grid[x1,y1].Remove(partical.ID);
                    Grid[x2,y1].Remove(partical.ID);
                    Grid[x1,y2].Remove(partical.ID);
                    Grid[x2,y2].Remove(partical.ID);                    
                    x1 = (int)Math.Round((partical.position.X   5) / 10);
                    y1 = (int)Math.Round((partical.position.Y   5) / 10);
                    x2 = (int)Math.Round((partical.position.X - 5) / 10);
                    y2 = (int)Math.Round((partical.position.Y - 5) / 10);
                    Grid[x1,y1].Add(partical.ID);
                    Grid[x2,y1].Add(partical.ID);
                    Grid[x1,y2].Add(partical.ID);
                    Grid[x2,y2].Add(partical.ID);
            }
        }
        void applyGravity(float sub)
        {
            float gravitystrangth = -0.1f;
            foreach (Partical partical in Particals)
            {
                float a = partical.position.Y;
                float b = partical.position.X;
                b -= 1000;
                a -= 500;
                double angle = Math.Atan2(a, b);
                float newA = gravitystrangth * (float)(Math.Sin(angle));
                float newB = gravitystrangth * (float)(Math.Sin((Math.PI / 180) * 90 - angle));
                Vector2 gravity = new Vector2(newB, newA);
                partical.accelerate(gravity);
            }
        }
        void solvecolisions(int id1, int id2)
        {
            Partical part = Particals[id1];
            Partical part2 = Particals[id2];
            if (part != part2)
            {
                Vector2 colisionaxis = part.position - part2.position;
                float dist = colisionaxis.Length();
                if (dist < 10)
                {
                    Vector2 n = colisionaxis / dist;
                    float delta = 10 - dist;
                    part.position  = 0.5f * delta * n;
                    part2.position -= 0.5f * delta * n;
                }
            }
        }
        public List<Partical> GetParticals()
        {
            return Particals;
        }
    }
}

`

CodePudding user response:

You ts list depends on solver.Grid[x,y]. I am sure that some of your code that is not visible on the screen makes some changes of solver.Grid, probably deletes some times, or replaces them. This is what causing the error.

  • Related