我想为Monty Hall问题创建一个简单的模拟,作为一个有趣的,快速的辅助项目.我的计划是创建完整的游戏,有可点击的门和所有的形式,但我首先想创建一种方法来模拟尽可能多的游戏,我想证明给自己,切换门有66%的机会获胜.问题是,我每次都有50/50的赔率.
有人能发现我的模拟有什么问题吗?当我增加门的数量时,切换门后获胜的几率就会增加.然而,有3个门,我总是得到大约50/50,所以我知道有一个问题与我的代码.
private void simulateButton_Click(object sender, EventArgs e)
{
int wins = 0;
int losses = 0;
int attempts = 0;
int numberOfDoors = 3;
// Main game loop. Number of simulations can easily be changed from 1000
for (int games = 0; games < 1000; games++)
{
List<Door> doors = new List<Door>();
for (int i = 0; i < numberOfDoors; i++)
{
doors.Add(new Door
{
Contents = "goat",
Opened = false,
PlayerChoice = false,
});
}
// Randomly pick a door for the car to be in
Random random = new Random();
int doorNumWithCar = random.Next(0, numberOfDoors - 1);
doors[doorNumWithCar].Contents = "car";
// I set player choice to always be door #1 to make it simpler
doors[0].PlayerChoice = true;
// Monty randomly removes one of the 2 doors not chosen by the player.
// (obviously, he doesn't remove the door with the car)
int doorMontyOpens;
while (doors.Count != 2)
{
doorMontyOpens = -1;
while (doorMontyOpens == -1)
{
int possibleDoorToBeShown = random.Next(1, doors.Count);
if (doors[possibleDoorToBeShown].Contents != "car")
{
doorMontyOpens = possibleDoorToBeShown;
}
}
// I just remove the door since that is essentially what Monty Hall is doing when
// He reveals one of the goats
doors.RemoveAt(doorMontyOpens);
}
// Since player choice is always door #1 (index 0) and there are only two doors left,
// we only need to check door #2 at index 1. If it has the car, it is a win. If not, a loss.
// This simulation only tests the case in which the player changes doors after Monty reveals
// a door. So it SHOULD usually have about 667 wins and 333 losses. Why do I get 50/50???
if (doors[1].Contents == "car")
{
wins++;
}
else
{
losses++;
}
attempts++;
this.winsTextbox.Text = $"{wins}";
this.lossesTextbox.Text = $"{losses}";
this.attemptsTextbox.Text = $"{attempts}";
}
MessageBox.Show("Done!");
}
public class Door
{
public string Contents { get; set; }
public bool Opened { get; set; }
public bool PlayerChoice { get; set; }
}
别介意代码的蹩脚.这是一个超级快速和肮脏的模拟.代码的每一段注释都在注释中.谢谢!