-
May 19th, 2010, 10:46 AM
#1
Random choosing - but making sure everything is run at least once?
Hello all,
I am pretty new to C#, learning it myself. Working on a project in the book, about creating a random dog race winner. I got it to work, but I am trying to make it more realistic. The same dog wins almost everytime because he is the first one that is executed everytime.
This is what I would like: Randomly choosing a dog method to run/ or if statement to run. But every dog must run at least once before starting over and randomly choosing who goes first, second, third, and fourth.
I have four if statements like this:
// Dog One
if (dogLocation[0] >= 483)
{
MessageBox.Show("Who won? " + dogs[0].name + " Did!", "We Have a Winner!");
won = true;
break;
}
else
{
dogLocation[0] = dogs[0].Run(dogLocation[0], picDogOne, dogs[0].StartingPosition);
this.Update();
}
// Dog Two
//etc....
This is kind of what I tried:
//Randomize Run Order for this loop
int orderholder;
for (int i = 0; i <= 3; i++)
{
assign = true;
orderholder = DogsRunning[RunOrderRandomizer.Next(4)];
//Check for duplicate entry
looper = i;
while (looper >= 1)
{
if (runorder[i-1] == orderholder)
assign = false;
looper--;
}
if (assign == true)
runorder[i] = orderholder;
else
i=i-1;
But its giving me duplicates.
Thank you!
-
May 19th, 2010, 12:04 PM
#2
Re: Random choosing - but making sure everything is run at least once?
I have not looked into random number generation in C# yet but if your same dog is winning almost everytime it sounds like you are not truly generating a random number. In VB you must seed the random function. If you fail to do so then each time you run the program the random numbers will be the same as the time before.
Typically I use the timer as my seed value as it will be different each time the program is ran and we get numbers that are more random as a result.
Always use [code][/code] tags when posting code.
-
May 19th, 2010, 12:11 PM
#3
Re: Random choosing - but making sure everything is run at least once?
When in doubt, read the docs before giving incorrect information out: http://msdn.microsoft.com/en-us/libr...em.random.aspx
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
May 19th, 2010, 01:35 PM
#4
Re: Random choosing - but making sure everything is run at least once?
Thanks for the reply.
This is what I use to generate a random number of spaces - either 1,2,3,4 spaces at a time.
public class Greyhound
{
public int StartingPosition; // Where PictureBox starts
public int RacetrackLength = 483; // How long the racetrack is
public PictureBox MyPictureBox = null; // My PictureBox object
public int Location; // My location on the racetrack
public Random Randomizer; // An instance of Random
// public bool wonRace = false; // Return true if won
public string name;
public int Run(int runLocation, PictureBox _picbox, int startingPosition)
{
//Move foward either 1,2,3 or 4 spaces at random
//Update the position of my PictureBox on the form
//Return true if I won the race
//MyPictureBox = new PictureBox();
Randomizer = new Random();
int[] randomNumber = { 1, 2, 3, 4 };
Randomizer = new Random();
runLocation += randomNumber[Randomizer.Next(4)];
_picbox.Location = new System.Drawing.Point(runLocation, startingPosition);
return runLocation;
}
It shouldn't generate the same numbers everytime, should it?
I will take a look at that link Mutant, thanks.
-
May 19th, 2010, 01:39 PM
#5
Re: Random choosing - but making sure everything is run at least once?
If I understood the OP well, he needs something like Winamp's shuffle functionality.
I've read about this algorithm that randomly picks each item from a set only once, and never the same one, until all of the items were chosen, but I can't remember it's name.
But, Bobcat, if it's not to computationally expensive, you could precompute a random permutation of the elements and go on that.
You could also use a list and pick and remove a random element, but I'm not sure about how efficient (or not) this approach is.
Anyway, take a look at the MSDN article that Mutant_Fruit provided a link for, and then take a look at this, if you think that it's relevant: Fisher–Yates shuffle - Wikipedia.
P.S. Look what I found
-
May 19th, 2010, 01:43 PM
#6
Re: Random choosing - but making sure everything is run at least once?
Oh. Meanwhile, you posted.
Try moving the
Randomizer = new Random();
out of the method body.
For example:
public Random Randomizer = new Random(); // An instance of Random
**********
EDIT:
P.S. You can use the Next(int, int) overload to get a random integer 1, 2, 3 or 4. ( Randomizer.Next(1, 5) )
************
EDIT 1:
MSDN article:
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. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers.
Last edited by TheGreatCthulhu; May 19th, 2010 at 01:48 PM.
-
May 19th, 2010, 01:56 PM
#7
Re: Random choosing - but making sure everything is run at least once?
Originally Posted by Mutant_Fruit
What incorrect information? According to the doc it appears that my thoughts were correct. Of course using the timer is not fool proof but it typically is the most exceptable way to go as the seed will very likely be different each and everytime you run the program.
I did not look to see if the code was using a single generator [should be] or a new one each time but is clear that the number is not really random if it is the same number most or all of the time.
ETA:
For those who are not aware of what I mean when I say use the timer I am referring to the Timer from VB which basically returns the number of ticks since Midnight. Works very well as a random seed
Last edited by DataMiser; May 19th, 2010 at 01:58 PM.
Always use [code][/code] tags when posting code.
-
May 19th, 2010, 02:19 PM
#8
Re: Random choosing - but making sure everything is run at least once?
Originally Posted by TheGreatCthulhu
P.S. You can use the Next(int, int) overload to get a random integer 1, 2, 3 or 4. ( Randomizer.Next(1, 5) )
Thanks Great,
That seemed to do the trick. Still not sure I understand the overload.
But it is very random on who wins now.
I will check out that other link.
-
May 19th, 2010, 02:38 PM
#9
Re: Random choosing - but making sure everything is run at least once?
Originally Posted by DataMiser
What incorrect information? According to the doc it appears that my thoughts were correct. Of course using the timer is not fool proof but it typically is the most exceptable way to go as the seed will very likely be different each and everytime you run the program.
If you write "Random r = new Random ()" it's already seeded with a random number (see documentation). Nearly anything you do yourself will be less random than that, so just don't try to use a seed. The issue at the start is more than likely because the 'Run' method is being called multiple times in a row, thus instantiating a new Random every time which ends up using the same 'random' seed as the 'random' seed is based on the current time. The fix for that issue is not to try and trick the system with timers (which would fail under this scenario too) but instead to just create the Random once and re-use it.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
May 19th, 2010, 03:08 PM
#10
Re:Old School Answer
Bobcat - I'm almost afraid to jump in here - what with these experts giving you good advice but I would approach it in an old school way. THe random number generator in C# is sufficient - quite good as long as everytime you continue it doesn't try to start over (problems DataMiser addressed). I solve that with a static variable in a small library I build for such problems. I know it is old school but it works. If I understand your intent - a simple dll called "myLib" with the two classes and three methods below should work just fine. Mutant_Fruit and DataMiser feel free to attack my 5 minute effort.
Code:
using System;
namespace MyLib
{
public class Utility
{
static Random rand = null;
public static Random Rand()
{
if(rand == null)
rand = new Random(unchecked((int)DateTime.Now.Ticks));
return rand;
}
}
public class Race
{
public static int [] Dog_Moves(int n)
{
int[] dog_moves = new int [n];
for (int i = 0; i < n; i++)
dog_moves[i] = 1 + (int) Utility.Rand().Next(4);
return dog_moves;
}
public static int [] Random_Indices(int number_indices)
{
int i, j = 0;
int [] indices = new int [number_indices];
int [] randIndex = new int [number_indices];
for (i = 0; i < number_indices; i++)
indices[i] = i;
do
{
i = (int) (Utility.Rand().NextDouble() * (number_indices));
if (i < number_indices && indices[i] >= 0)
{
randIndex[j] = indices[i];
indices[i] = -1;
j++;
}
} while (j < number_indices);
return randIndex;
}
}
}
Last edited by K7SN; May 19th, 2010 at 03:09 PM.
Reason: Forgot to say I used VS-2003 dotnet 1.1
-
May 19th, 2010, 03:10 PM
#11
Re: Random choosing - but making sure everything is run at least once?
Seems like massive overkill for a problem easily solved by declaring a member variable instead of a local one...
If I saw that in production code I would remove it immediately and ask the creator what exactly they were thinking.
EDIT: I would also wonder why a DLL was named "MyLib" seeing as a "lib" is typically a static library
If you liked my post go ahead and give me an upvote so that my epee.... ahem, reputation will grow.
Yes; I have a blog too - http://the-angry-gorilla.com/
-
May 19th, 2010, 03:12 PM
#12
Re: Random choosing - but making sure everything is run at least once?
The System.Random class is not threadsafe so you cannot safely make it a static variable as you've done as multiple threads can potentially access it at the same time and all kinds of problems could arise.
Also this isn't an attack, just a constructive criticism
Last edited by Mutant_Fruit; May 19th, 2010 at 03:14 PM.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
May 19th, 2010, 03:13 PM
#13
Re: Random choosing - but making sure everything is run at least once?
Another good point, I wish I could give you a vote for that one.
If you liked my post go ahead and give me an upvote so that my epee.... ahem, reputation will grow.
Yes; I have a blog too - http://the-angry-gorilla.com/
-
May 19th, 2010, 03:27 PM
#14
Re: Random choosing - but making sure everything is run at least once?
Originally Posted by Mutant_Fruit
The System.Random class is not threadsafe so you cannot safely make it a static variable as you've done as multiple threads can potentially access it at the same time and all kinds of problems could arise.
Also this isn't an attack, just a constructive criticism
I appreciate it - really - don't get to windows program or c# nearly as much as I'd like - still think in the dark ages. Yes - I read Knuth when the books came out - already been programming then for 15 years and so I know I ain't current - I enjoy reading this forum and I'm sure there simpler ways to get random indices nowadays, Thank you also BigEd - I know just a lib and really just a snippet and without comments no less.
-
May 19th, 2010, 03:28 PM
#15
Re: Random choosing - but making sure everything is run at least once?
Originally Posted by K7SN
Thank you also BigEd - I know just a lib and really just a snippet and without comments no less.
I figured as much
If you liked my post go ahead and give me an upvote so that my epee.... ahem, reputation will grow.
Yes; I have a blog too - http://the-angry-gorilla.com/
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|