Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Kata Monty Hall in Scala, take two
import scala.util.Random
import scala.collection.mutable.ListBuffer
abstract class Door
case class Car() extends Door
case class Goat() extends Door
class Game(val doors:List[Door] = Random.shuffle(List(Goat(), Goat(), Car()))) {
var playerDoor = -1
var montyDoor = -1
var monty = new Monty(this)
def chooseDoor(door: Int) = {
playerDoor = door
montyDoor = monty.pickDoor()
}
def switch() = {
playerDoor = {
val availableDoors = ListBuffer(0, 1, 2)
availableDoors -= playerDoor
availableDoors -= montyDoor
availableDoors.head
}
}
def won() = {
doors(playerDoor) == Car()
}
}
class Player(game: Game) {
def chooseDoor(door: Int) = {
game.chooseDoor(door)
}
def switch() = {
game.switch()
}
}
class Monty(game: Game) {
def pickDoor():Int = {
val availableDoors = ListBuffer(0, 1, 2)
availableDoors -= game.playerDoor
val montyPick = availableDoors(Random.nextInt(2))
if (game.doors(montyPick) != Car())
montyPick
else
pickDoor()
}
}
import org.specs._
import org.specs.mock.Mockito
import org.mockito.Matchers._
import scala.util._
import scala.collection.mutable.{ListBuffer}
class MontySpec extends Specification with Mockito {
val game = new Game(List(Goat(), Goat(), Car()))
val player = new Player(game)
"The Game" should {
"have two Goats and a Car" in {
game.doors.size must_== 3
game.doors.filter{_.isInstanceOf[Car]}.size must_== 1
game.doors.filter{_.isInstanceOf[Goat]}.size must_== 2
}
"make Monty select a door after the player has choosen one" in {
player.chooseDoor(0)
game.montyDoor must_!= -1
}
"make Monty choose another door than the player" in {
player.chooseDoor(0)
game.montyDoor must_!= game.playerDoor
}
"make Monty choose a door that is not a Car" in {
player.chooseDoor(0)
game.doors(game.montyDoor) must_!= Car()
}
"make sure Montys door choosing is not the same all the time" in {
val game = new Game(List(Goat(), Car(), Goat()))
val player = new Player(game)
player.chooseDoor(1)
game.montyDoor must_!= game.playerDoor
}
"know that the player lost if he chooses a Goat" in {
player.chooseDoor(0)
game.won() must_== false
}
"know that the player won if he chooses the Car" in {
player.chooseDoor(2)
game.won must_== true
}
}
"The Player" should {
"be able to select a door" in {
player.chooseDoor(0)
game.playerDoor must_== 0
}
"be able to switch door after Monty has picked a door" in {
player.chooseDoor(0)
player.switch()
game.playerDoor must_!= 0
}
}
"A simulation" should {
"show that switching will win two times out of three" in {
val thousandGames = for(i <- 1 to 1000) yield {
val game = new Game
val player = new Player(game)
player.chooseDoor(0)
player.switch()
game.won()
}
thousandGames.count(_ == true) must be closeTo(667 +/- 67)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.