Sign in to follow this  
Khaiy

Simple Simulation Code Fails-- Sometimes

Recommended Posts

I've been fiddling with this for a few days, and I've run out of ideas. I'm practicing some basic C# programming, and I decided to make a simulation to test the Monty Hall problem (from a thread in the lounge a while back). I've been testing it with each feature I've added, and now I'm stuck.

The code works as intended sometimes, but other times it hangs in the middle. The program is intended to create three boxes, randomly assign a prize to one, and randomly select one in phase one. This part works 100% of the time so far. In phase 2, a box that is neither chosen nor contains the prize is supposed to be eliminated. This code works, but only some of the time. When it works, it seems to do so perfectly-- eliminating an appropriate box every time. When it doesn't work, the program hangs after completing phase one.

I've tried lots of different arrangements of my Eliminator function, but I always have the same, occasionally-works issue. I've looked it over over and over again, and I'm out of ideas of what might be causing it to fail sometimes. I'm confident that it's a round to issue

Here's the code:

[code]


namespace MontyHall
{
class Program
{

static void Main(string[] args)
{
char b1 = 'A';
char b2 = 'B';
char b3 = 'C';


Box a = new Box(b1);
Box b = new Box(b2);
Box c = new Box(b3);


Box[] stage1 = new Box[3] {a, b, c};

Initialize.prizeStuffer(ref stage1);

Game.chooseBox(ref stage1);

Tester.showInfo(stage1);

Game.Eliminator(ref stage1);

Tester.showRound2(stage1);

}
}
}
[/code]

[code]

namespace MontyHall
{
// Defines the box object type
public class Box
{
public bool prize;
public bool chosen;
public bool eliminated;
public char name;

// Constructor
public Box(char name)
{
// Set the box to empty
this.prize = false;

// Mark all boxes as unchosen
this.chosen = false;

// Set elimination flag to false
this.eliminated = false;

// Name the box
this.name = name;
}
}
}
[/code]

[code]

namespace MontyHall
{
public static class Game
{

// Randomly chooses one of the three boxes
public static void chooseBox(ref Box[] stage1)
{
// Get seed value from Seeder

int c = Seeder.Randomizer();

stage1[c].chosen = true;
}

// Eliminate a non-chosen, empty box
public static void Eliminator(ref Box[] stage1)
{
int i = 0;

bool keepon = true;

do
{
i = Seeder.Randomizer();

if (stage1[i].chosen == false && stage1[i].prize == false)
{
stage1[i].eliminated = true;
keepon = false;
}
}
while (keepon == true);
}
}
}
[/code]

[code]
// Randomly generates a number for box selection

namespace MontyHall
{
static class Seeder
{
static int seedGenerator()
{
Thread.Sleep(27);

Random seeder = new Random();
int seed = seeder.Next();

return seed;
}

public static int Randomizer()
{
Random random = new Random(seedGenerator());
int choice = random.Next(0, 2);

return choice;
}
}
}
[/code]

[code]
// Places the prize in a random box

namespace MontyHall
{
public static class Initialize
{
public static void prizeStuffer(ref Box[] stage1)
{
int i = 0;

i = Seeder.Randomizer();

stage1[i].prize = true;
}
}
}

[/code]

[code]

// Shows the results of each round, for testing purposes

namespace MontyHall
{
public static class Tester
{

// Display the results of round 1
public static void showInfo(Box[] stage1)
{
for (int i = 0; i < stage1.Length; i++)
{
Console.WriteLine("Box {0}:", stage1[i].name);
Console.WriteLine("Prize: {0}", stage1[i].prize);
Console.WriteLine("Chosen: {0}", stage1[i].chosen);
Console.WriteLine("\n");
}
}

// Display the results of round 2
public static void showRound2(Box[] stage1)
{
for (int i = 0; i < stage1.Length; i++)
{
if (stage1[i].eliminated == false)
{
Console.WriteLine("Box {0}:", stage1[i].name);
Console.WriteLine("Prize: {0}:", stage1[i].prize);
Console.WriteLine("Chosen: {0}", stage1[i].chosen);
}

else
{
Console.WriteLine("Box {0} was eliminated.", stage1[i].name);
}
}
}
}
}

[/code]

What am I missing? Clearly there's some problem above. Any help is appreciated. Any more general comments about my code are also welcome, as I'm sure I'm not using best practices.

Share this post


Link to post
Share on other sites
Well what I've noticed so far is that you're using the random number generator wrong. You're creating an seeding a new generator each time, and hence have discovered a need to sleep so that the seeds aren't so similar or repeated. What you should do is have a member of type Random and only create this variable once, then Randomiser should just return random[color="#666600"].[/color][color="#660066"]Next[/color][color="#666600"]([/color][color="#006666"]0[/color][color="#666600"],[/color] [color="#006666"]2[/color][color="#666600"]);
[/color][color="#000000"]You can then remove the Thread.Sleep();

Secondly, a quick look at the documentation for Random.Next indicates that the upper bound is "exclusive" meaning that it does not include that value. Hence you actually need to return random[color="#666600"].[/color][color="#660066"]Next[/color][color="#666600"]([/color][color="#006666"]0[/color][color="#666600"],[/color] [color="#006666"]3[/color][color="#666600"]);
[/color][color="#000000"]This would explain the lockup if you picked item 0 or 1 and item 1-choice was actually the prize, because it would be unable to eliminate any box.[/color][/color] It would presumably work every time it you picked 2.

Share this post


Link to post
Share on other sites
Thanks for the reply! The parameters in my use of Random.Next() were what was causing the program to hang.

As for my poor use of the random number generator, would this be better?

[code]


namespace MontyHall
{
static class Seeder
{

Random random = new Random();

public static int Randomizer()
{
int choice = random.Next(0, 3);

return choice;
}
}
}
[/code]

The reason I did it as I did was because I'm planning on running the program for a large number of trials, and wanted to make sure that each trial was truly random so that the results aren't statistically unsound.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this