Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package simulations
- import math.random
- class EpidemySimulator extends Simulator {
- def randomBelow(i: Int) = (random * i).toInt
- def randomTo(i: Int) = (random * (i+1)).toInt
- protected[simulations] object SimConfig {
- val population: Int = 300
- val roomRows: Int = 8
- val roomColumns: Int = 8
- // to complete: additional parameters of simulation
- val incubationTime = 6
- val dieTime = 14
- val immuneTime = 16
- val healTime = 18
- val prevalenceRate = 0.01
- val transRate = 0.4
- val dieRate = 0.25
- }
- import SimConfig._
- val persons: List[Person] =
- for {
- i <- (0 until population).toList
- } yield {
- val p = new Person(i)
- if (i < population * prevalenceRate)
- p.setInfected()
- p.mode()
- p
- }
- class Person(val id: Int) {
- var infected = false
- var sick = false
- var immune = false
- var dead = false
- // demonstrates random number generation
- var row: Int = randomBelow(roomRows)
- var col: Int = randomBelow(roomColumns)
- def setInfected() {
- infected = true
- afterDelay(incubationTime)(setSick)
- afterDelay(dieTime)(setDead)
- afterDelay(immuneTime)(setImmune)
- afterDelay(healTime)(setHealthy)
- }
- def setSick() {
- sick = true
- }
- def setDead() {
- if (random < dieRate)
- dead = true
- }
- def setImmune() {
- if (dead) return
- sick = false
- immune = true
- }
- def setHealthy() {
- if (dead) return
- immune = false
- infected = false
- }
- def mode() {
- val moveDelay = randomTo(5)
- afterDelay(moveDelay)(move)
- }
- def move() {
- if (dead) return
- // Move to a neighbor room
- val neighbors = List(((row - 1 + roomRows) % roomRows, col),
- ((row + 1) % roomRows, col),
- (row, (col - 1 + roomColumns) % roomColumns),
- (row, (col + 1) % roomColumns))
- def isHealthy(room: (Int, Int)): Boolean = room match {
- case (r, c) => (persons.find { p => p.row == r && p.col == c && (p.sick || p.dead) }).isEmpty
- }
- val candidates = neighbors filter isHealthy
- if (!candidates.isEmpty) {
- val candidate: (Int, Int) = candidates(randomBelow(candidates.length))
- candidate match {
- case (a, b) => row = a; col = b
- }
- }
- if (!immune && !infected)
- if (random < transRate)
- if (!(persons.find { p => p.row == row && p.col == col && p.infected }).isEmpty)
- setInfected()
- mode()
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement