import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
class MontyHallProblem
{
static final int DOORS_SIZE = 3;
static final int REPETITIONS_NUMBER = 1000;
static
{
}
static class Door
{
boolean car;
boolean firstChoiced;
boolean opened;
Door(boolean car)
{
this.car = car;
firstChoiced = false;
opened = false;
}
}
static abstract class Player
{
int firstWonsNumber;
int secondWonsNumber;
Player()
{
firstWonsNumber = 0;
secondWonsNumber = 0;
}
Door firstChoice(List<Door> doors)
{
final Door door = randomChoice(doors);
door.firstChoiced = true;
return door;
}
abstract Door secondChoice(List<Door> doors);
}
static class ImmutablePlayer extends Player
{
Door secondChoice(List<Door> doors)
{
return doors.stream()
.filter(door -> door.firstChoiced)
.findFirst()
.get();
}
}
static class MutablePlayer extends Player
{
Door secondChoice(List<Door> doors)
{
return randomChoice(doors.stream()
.filter(door -> !door.opened)
.collect(Collectors.toList()));
}
}
static class Game
{
List<Door> doors;
Game()
{
doors.add(new Door(true));
while (doors.size() < DOORS_SIZE) doors.add(new Door(false));
}
void openAnother()
{
randomChoice(doors.stream()
.filter(door -> !door.car && !door.firstChoiced)
.collect(Collectors.toList())).opened = true;
}
void play(Player player)
{
if (player.firstChoice(doors).car) ++player.firstWonsNumber;
openAnother();
if (player.secondChoice(doors).car) ++player.secondWonsNumber;
}
}
public static void main
(String[] args
) {
final Player immutablePlayer = new ImmutablePlayer();
repeat(immutablePlayer);
(
"Immutable first=%d second=%d\n",
immutablePlayer.firstWonsNumber,
immutablePlayer.secondWonsNumber
);
final Player mutablePlayer = new MutablePlayer();
repeat(mutablePlayer);
(
"Mutable first=%d second=%d\n",
mutablePlayer.firstWonsNumber,
mutablePlayer.secondWonsNumber
);
}
static <T> T randomChoice(List<T> list)
{
return list.get(random.nextInt(list.size()));
}
static void repeat(Player player)
{
for (int i = 0; i < REPETITIONS_NUMBER; ++i) new Game().play(player);
}
}