I have taken your inputs on my original question and formed a new implementation of the Monty Hall Simulation:
Again keep an eye on CleanCode and OOP
The Price to be won:
enum Price {
GOAT, CAR
}
The Door keeping that price in secret
class Door {
private final Price price;
Door(Price price){
this.price = price;
}
Price getPrice() {
return price;
}
}
the Player who participates in an Monty Hall Game
class Player {
private final boolean preferresChange;
private int winCounter;
Player(boolean preferresChange){
this.preferresChange = preferresChange;
}
boolean preferresChange(){
return preferresChange;
}
void increaseWinCounter() {
winCounter = winCounter + 1;
}
int getWinCounter(){
return winCounter;
}
}
the MontyHall in which the player takes action
class MontyHall {
private final List<Door> doors;
private Door selected;
private Door openOne;
private final Random random;
private final int amountOfDoors;
MontyHall(int seed, int amount) {
random = new Random(seed);
amountOfDoors = amount;
doors = IntStream.range(0, amountOfDoors).
mapToObj(e -> new Door(Price.GOAT)).
collect(Collectors.toList());
doors.set(random.nextInt(amountOfDoors), new Door(Price.CAR));
}
void chooseDoor(){
selected = doors.get(random.nextInt(amountOfDoors));
}
void openDoor(){
openOne = doors.stream().
filter(d -> !d.equals(selected) && Price.GOAT == d.getPrice()).
collect(Collectors.toList()).
get(0);
}
void changeDoor(){
selected = doors.stream().
filter(d -> !d.equals(openOne) && !d.equals(selected)).
collect(Collectors.toList()).
get(0);
}
Price getPrice(){
return selected.getPrice();
}
}
and the simulator who hosts the games
class Simulator {
public static void main(String[] args) {
Simulator simulator = new Simulator();
simulator.simulate(10000, 3);
}
private void simulate(int iterations, int amountDoors) {
Player changer = new Player(true);
Player stayer = new Player(false);
Random random = new Random();
for (int i = 0; i < iterations; i ++){
int seed = random.nextInt();
playOneRound(changer, seed, amountDoors);
playOneRound(stayer, seed, amountDoors);
}
System.out.println("changer: "+changer.getWinCounter());
System.out.println("stayer : "+stayer.getWinCounter());
}
private void playOneRound(Player player, int seed, int amountDoors) {
playOneRound(player, new MontyHall(seed, amountDoors));
}
private void playOneRound(Player player, MontyHall montyHall) {
montyHall.chooseDoor();
montyHall.openDoor();
if (player.preferresChange()){
montyHall.changeDoor();
}
if (Price.CAR == montyHall.getPrice()){
player.increaseWinCounter();
}
}
}
3
into a10
, the probabilities don't change much. But they should. The changer should now have a winning probability of 90%. \$\endgroup\$n-2 doors
in my simulation but always1 door
- this leads to a different behaviour... maybe we'll skipt that part and have a closer look at OOP and CleanCode (i'll add a proper implementation soon, where that flaw would be fixed) \$\endgroup\$opendDoors()
- note the plural s ^^ \$\endgroup\$