6 Replies - 1173 Views - Last Post: 02 February 2011 - 08:58 AM Rate Topic: -----

#1 sk8ermeb   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 133
  • Joined: 23-March 10

Lots of random data the same

Posted 01 February 2011 - 04:23 PM

Hello,
I hve this code I am writing for fun to learn about buffered graphics. Basically I have a ball class that when instantiated generates a rondom velocity and color. Each one of these balls runs in its own thread and then the buffered graphics class paints all of them every 5 ms or so. The trick is that in order to make them all random I have to put a Thread.sleep(1) in the loop where I instantiate them all(2000 or so) but with a sleep of 1mS it takes 36 seconds to load and without the sleep it is seemingle instant!! But without the sleep all the balls come out with identicle velocities and colors. Now I know that sleep(10 x2000) ~ 2 seconds so does anyone know of a way I can make psudo random more random without an arbitrary wait? Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Lots of random data the same

#2 Kilorn   User is offline

  • XNArchitect
  • member icon



Reputation: 1361
  • View blog
  • Posts: 3,534
  • Joined: 03-May 10

Re: Lots of random data the same

Posted 01 February 2011 - 04:27 PM

Without seeing the code, I have a guess that you're using 1 randomly generated variable to set the velocities of the balls. Therefore once the random is generated, all of the balls will have the same velocity when set. In order to generate the balls with random velocities, you'll have to create a new instance of the random variable each time you create a new ball with the .Next() method of the Random class.
Was This Post Helpful? 1
  • +
  • -

#3 sk8ermeb   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 133
  • Joined: 23-March 10

Re: Lots of random data the same

Posted 01 February 2011 - 04:31 PM

Unfortunatly no...since there is a ball Class each ball creats its own random number generator then uses that to generate its random data, but I hadn't thought of that !!
Was This Post Helpful? 0
  • +
  • -

#4 Kilorn   User is offline

  • XNArchitect
  • member icon



Reputation: 1361
  • View blog
  • Posts: 3,534
  • Joined: 03-May 10

Re: Lots of random data the same

Posted 01 February 2011 - 04:51 PM

Paste some of your code and let us see what you're working with. That would definitely help diagnose the issue.
Was This Post Helpful? 0
  • +
  • -

#5 sk8ermeb   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 133
  • Joined: 23-March 10

Re: Lots of random data the same

Posted 01 February 2011 - 05:16 PM

My whole program is fairly short so I will just post all three classes
using System;
using System.Windows.Forms;
namespace Bounce
{
    class Program
    {
        static void Main(string[] args)
        {
            Application.Run(new BounceScreen());
        }
    }
}



using System;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;

namespace Bounce
{
    class BounceScreen : Form
    {
        Ball[] myballs;
        Thread[] ballThreads;
        BufferedGraphics BG;
        public BounceScreen()
        {
            this.Size = new Size(800, 500);
            this.Visible = true;
            myballs = new Ball[200];
            ballThreads = new Thread[myballs.Length];
            Thread t1 = new Thread(new ThreadStart(setUpScreen));
            t1.Start();
        }
        public void setUpScreen()
        { 
            int j = 0;
            for (j = 0; j < myballs.Length; j++)
            {
                myballs[j] = new Ball(this.DisplayRectangle);
                ballThreads[j] = new Thread(new ThreadStart(myballs[j].runBall));
                //Thread.Sleep(1);//////////////////////////////////////////This is the magical line
            }
            ballThreads[0].Start();
            Thread t2 = new Thread(new ThreadStart(runBalls));
            t2.Start();
            for (j = 1; j < myballs.Length; j++)
            {
                ballThreads[j].Start();
            }            
        }
        public void runBalls()
        {
            BufferedGraphicsContext context = BufferedGraphicsManager.Current;
            BG = context.Allocate(this.CreateGraphics(), this.DisplayRectangle);            
            bool alive = false;
            int i = 0;
            do
            {
                BG.Graphics.Clear(Color.White);
                Thread.Sleep(2);
                alive = false;
                for (i = 0; i < ballThreads.Length; i++)
                {
                    try
                    {
                        BG.Graphics.FillEllipse(myballs[i].ballBrush, myballs[i].ballSize);
                        if (ballThreads[i].IsAlive)
                        {
                            alive = true;
                        }
                    }
                    catch (NullReferenceException exc){}
                }
                BG.Render();                
            } while (alive);
            Console.WriteLine("No longer Alive");            
        }        
    }
}



using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;

namespace Bounce
{
    class Ball
    {
        private Random r;
        private Rectangle bounds;
        private double dX, dY, g;
        public Rectangle ballSize;
        public double x, y;
        private Color ballColor;
        public HatchBrush ballBrush;
        public Ball(Rectangle screenSize)
        {
            bounds = screenSize;

            setUpBall();
        }
        private void setUpBall()
        {
            double speed = 3;
            r = new Random();
            g = .01*speed;
            dX = r.NextDouble()*speed;
            if (dX < .2)
                dX = .2;
            if (dY < .2)
                dY = .2;
            dY = r.NextDouble()*-1*speed;
            ballSize = new Rectangle(0, 0, 20, 20);
            ballColor = Color.FromArgb(r.Next());
            bounds.Height -= ballSize.Height;
            bounds.Width -= ballSize.Width;
            x = 0;
            y = bounds.Height/2;
            ballBrush = new HatchBrush(HatchStyle.Percent90, ballColor);
        }
        public void runBall()
        {
            bool swapped = false;
            do
            {
                x += dX;
                y += dY;
                dY += g;
                if (y >= bounds.Height && !swapped)
                {
                    dY *= -.8;
                    dX *= .8;
                    swapped = true;
                }
                else
                    swapped = false;
                Thread.Sleep(1);
                ballSize.X = (int)Math.Round(x);
                ballSize.Y = (int)Math.Round(y);
            } while (dX > .05 || Math.Abs(dY) > .05);
        }
    }
}


Was This Post Helpful? 1
  • +
  • -

#6 Sergio Tapia   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1258
  • View blog
  • Posts: 4,168
  • Joined: 27-January 10

Re: Lots of random data the same

Posted 01 February 2011 - 06:31 PM

This is a great topic! One I hope someone has the answer to. On one hand MSDN says the following:

Quote

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time.


Then it says:

Quote

This problem can be avoided by creating a single Random object rather than multiple ones.

To improve performance, create one Random object to generate many random numbers over time, instead of repeatedly creating a new Random objects to generate one random number.


Why don't you try creating a static class that returns a random number, that way you use only a single random object, like MSDN suggests.

public static class Randomizer
{
    public static Random random;
    public static int GetRandomNumber()
    {
        return random.Next(0,10);
    }
}


This post has been edited by Sergio Tapia: 01 February 2011 - 06:35 PM

Was This Post Helpful? 2
  • +
  • -

#7 sk8ermeb   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 133
  • Joined: 23-March 10

Re: Lots of random data the same

Posted 02 February 2011 - 08:58 AM

I forgot about seeds! I guess this is why you comp sci majors make the big bucks! So the first thing I tried was just I told each ball what number in the array that was and used that seed and that worked perfectly! So now the code can generate 2000 ball bouncing threads seemingly instantly and it runs smooth(up to 500 or so when my p4 maxes out :) ) then I added one more method so it would actually close out. If anyones interested here is the code it looks pretty cool I think.

Also I wish I was working on a multicore because I have always wanted to try the Task Parallel library. It really interesting because you can visually see when you computer is bogging down the balls stop shooting out as fast. Anyways I think all you want have to do to multicore thread this is use the TPL loop functions in place, I would be curious to know the difference.

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;

namespace Bounce
{
    class BounceScreen : Form
    {
        Ball[] myballs;
        Thread[] ballThreads;
        BufferedGraphics BG;
        Thread t1, t2;
        public BounceScreen()
        {
            this.Size = new Size(800, 500);
            this.Visible = true;

            this.FormClosed += new FormClosedEventHandler(BounceScreen_FormClosed);
            myballs = new Ball[2000];
            ballThreads = new Thread[myballs.Length];
            t1 = new Thread(new ThreadStart(setUpScreen));
            t1.Start();
        }

        void BounceScreen_FormClosed(object sender, FormClosedEventArgs e)
        {
            int i = 0;
            try
            {
                t1.Abort();
            }
            catch (Exception exc) { }
            
            for (i = 0; i < myballs.Length; i++)
            {
                try
                {
                    myballs[i].isRunnable = false;
                }
                catch (Exception exc) { }
            }
            try
            {
                t2.Abort();
            }
            catch (Exception exc) { }
            
        }

       
        public void setUpScreen()
        { 
            int j = 0;
            for (j = 0; j < myballs.Length; j++)
            {
                myballs[j] = new Ball(this.DisplayRectangle, j);
                ballThreads[j] = new Thread(new ThreadStart(myballs[j].runBall));
                //Thread.Sleep(1);
            }
            ballThreads[0].Start();
            t2 = new Thread(new ThreadStart(runBalls));
            t2.Start();
            for (j = 1; j < myballs.Length; j++)
            {
                ballThreads[j].Start();
            }            
        }
        public void runBalls()
        {
            BufferedGraphicsContext context = BufferedGraphicsManager.Current;
            BG = context.Allocate(this.CreateGraphics(), this.DisplayRectangle);            
            bool alive = false;
            int i = 0;
            do
            {
                BG.Graphics.Clear(Color.White);
                Thread.Sleep(2);
                alive = false;
                for (i = 0; i < ballThreads.Length; i++)
                {
                    try
                    {
                        BG.Graphics.FillEllipse(myballs[i].ballBrush, myballs[i].ballSize);
                        if (ballThreads[i].IsAlive)
                        {
                            alive = true;
                        }
                    }
                    catch (NullReferenceException exc){}
                }
                try
                {
                    BG.Render();
                }
                catch (Exception exc) { }
            } while (alive);
            Console.WriteLine("No longer Alive");            
        }
    }
}



using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;

namespace Bounce
{
    class Ball
    {
        private Random r;
        private Rectangle bounds;
        private double dX, dY, g;
        public Rectangle ballSize;
        public double x, y;
        private Color ballColor;
        public HatchBrush ballBrush;
        private int ballNum;
        public bool isRunnable;
        public Ball(Rectangle screenSize, int num)
        {
            bounds = screenSize;
            ballNum = num;
            setUpBall();
        }
        private void setUpBall()
        {
            isRunnable = true;
            double speed = 3;
            r = new Random(ballNum);
            g = .01*speed;
            dX = r.NextDouble()*speed;
            if (dX < .2)
                dX = .2;
            if (dY < .2)
                dY = .2;
            dY = r.NextDouble()*-1*speed;
            ballSize = new Rectangle(0, 0, 20, 20);
            ballColor = Color.FromArgb(r.Next());
            bounds.Height -= ballSize.Height;
            bounds.Width -= ballSize.Width;
            x = 0;
            y = bounds.Height/2;
            ballBrush = new HatchBrush(HatchStyle.Percent90, ballColor);
        }
        public void runBall()
        {
            bool swapped = false;
            do
            {
                x += dX;
                y += dY;
                dY += g;
                if (y >= bounds.Height && !swapped)
                {
                    dY *= -.8;
                    dX *= .8;
                    swapped = true;
                }
                else
                    swapped = false;
                Thread.Sleep(1);
                ballSize.X = (int)Math.Round(x);
                ballSize.Y = (int)Math.Round(y);
            } while ((dX > .05 || Math.Abs(dY) > .05) && isRunnable);
        }
    }
}


Was This Post Helpful? 1
  • +
  • -

Page 1 of 1