Skip to content

Instantly share code, notes, and snippets.

@jorgen99
Created December 12, 2010 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorgen99/737804 to your computer and use it in GitHub Desktop.
Save jorgen99/737804 to your computer and use it in GitHub Desktop.
The Monty Hall kata in scala
import scala.util.{Random}
import scala.collection.mutable.{ListBuffer}
class Game(doors: ListBuffer[Symbol] = Random.shuffle(ListBuffer('Car, 'Goat, 'Goat))) {
var playerDoor:Symbol = _
var montyDoor:Symbol = _
if (doors.count(_ == 'Car) != 1 || doors.count(_ == 'Goat) != 2) {
throw new IllegalArgumentException("Should be one Car and two Goats")
}
def numberOfDoors = doors.size
def carDoor = doors.indexOf('Car)
def chooseDoor(doorNo: Int) = {
playerDoor = doors.remove(doorNo)
montyDoor = montyPicksDoor
}
def montyPicksDoor() = {
if (doors(0) == 'Goat)
doors.remove(0)
else
doors.remove(1)
}
def switch = playerDoor = doors.remove(0)
def playerWon = playerDoor == 'Car
override def toString = doors.mkString(", ")
}
import org.specs._
import scala.util._
import scala.collection.mutable.{ListBuffer}
class MontySpec extends Specification {
val game = new Game(ListBuffer('Goat, 'Car, 'Goat))
"The Game" should {
"have three doors" in {
game.numberOfDoors must_== 3
}
"should have one car and two doors" in {
new Game(ListBuffer('Goat, 'Goat, 'Goat)) must throwA[IllegalArgumentException]
new Game(ListBuffer('Car, 'Car, 'Car)) must throwA[IllegalArgumentException]
new Game(ListBuffer('Goat, 'Car, 'Car)) must throwA[IllegalArgumentException]
new Game(ListBuffer('Car, 'Car, 'Goat)) must throwA[IllegalArgumentException]
new Game(ListBuffer('Car, 'Goat, 'Car)) must throwA[IllegalArgumentException]
}
"know where the car is" in {
game.carDoor must_== 1
}
"be able to tell if the player was a winner" in {
game.chooseDoor(1)
game.playerWon must be(true)
}
}
"A Player" should {
"be able to choose a door" in {
game.chooseDoor(0)
game.playerDoor must be('Goat)
}
"be able to switch doors" in {
game.chooseDoor(0)
game.switch
game.playerDoor must beOneOf('Car, 'Goat)
game.numberOfDoors must_== 0
}
}
"Monty" should {
"pick a door after the player has chosen one" in {
game.chooseDoor(0)
game.montyDoor must be('Goat)
game.numberOfDoors must_== 1
}
}
"Running a thousand games" should {
"show that switching wins 2 times out of 3" in {
(for(i <- 1 to 1000) yield {
val game = new Game
game.chooseDoor(Random.nextInt(3))
game.switch
game.playerWon
}).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