Updated ants sample

This commit is contained in:
Peter Vlugter 2010-06-20 09:25:26 +12:00
parent 3f7402ceff
commit 18ed80b160
2 changed files with 31 additions and 16 deletions

View file

@ -7,13 +7,13 @@ package sample.ants
import java.util.concurrent.TimeUnit
import scala.util.Random.{nextInt => randomInt}
import se.scalablesolutions.akka
import akka.actor.{ActorRef, Transactor, Scheduler}
import akka.actor.{Actor, ActorRef, Scheduler}
import akka.actor.Actor.actorOf
import akka.stm.local._
object Config {
val Dim = 80 // dimensions of square world
val AntsSqrt = 7 // number of ants = AntsSqrt^2
val AntsSqrt = 20 // number of ants = AntsSqrt^2
val FoodPlaces = 35 // number of places with food
val FoodRange = 100 // range of amount of food at a place
val PherScale = 10 // scale factor for pheromone drawing
@ -41,7 +41,7 @@ case class Cell(food: Int = 0, pher: Float = 0, ant: Option[Ant] = None, home: B
object EmptyCell extends Cell
class Place(initCell: Cell = EmptyCell) extends Ref(Some(initCell)) {
def cell: Cell = get.get
def cell: Cell = getOrElse(EmptyCell)
def food: Int = cell.food
def food(i: Int) = alter(_.addFood(i))
def hasFood = food > 0
@ -58,6 +58,8 @@ class Place(initCell: Cell = EmptyCell) extends Ref(Some(initCell)) {
def home: Boolean = cell.home
}
case object Ping
object World {
import Config._
@ -66,6 +68,10 @@ object World {
lazy val ants = setup
lazy val evaporator = actorOf[Evaporator].start
private val snapshotFactory = TransactionFactory(readonly = true, familyName = "snapshot")
def snapshot = atomic(snapshotFactory) { Array.tabulate(Dim, Dim)(place(_, _).get) }
def place(loc: (Int, Int)) = places(loc._1)(loc._2)
private def setup = atomic {
@ -81,12 +87,12 @@ object World {
}
def start = {
ants foreach (pingEvery(_, AntMillis))
pingEvery(evaporator, EvapMillis)
ants foreach pingEvery(AntMillis)
pingEvery(EvapMillis)(evaporator)
}
private def pingEvery(actor: ActorRef, millis: Long) =
Scheduler.schedule(actor, "ping", Config.StartDelay, millis, TimeUnit.MILLISECONDS)
private def pingEvery(millis: Long)(actor: ActorRef) =
Scheduler.schedule(actor, Ping, Config.StartDelay, millis, TimeUnit.MILLISECONDS)
}
object Util {
@ -121,9 +127,9 @@ object Util {
}
}
trait WorldActor extends Transactor {
trait WorldActor extends Actor {
def act
def receive = { case "ping" => act }
def receive = { case Ping => act }
}
class AntActor(initLoc: (Int, Int)) extends WorldActor {
@ -131,13 +137,17 @@ class AntActor(initLoc: (Int, Int)) extends WorldActor {
import Util._
val locRef = Ref(initLoc)
val name = "ant-from-" + initLoc._1 + "-" + initLoc._2
implicit val txFactory = TransactionFactory(familyName = name)
val homing = (p: Place) => p.pher + (100 * (if (p.home) 0 else 1))
val foraging = (p: Place) => p.pher + p.food
def loc = locRef.get.getOrElse(initLoc)
def loc = locRef.getOrElse(initLoc)
def newLoc(l: (Int, Int)) = locRef swap l
def act = {
def act = atomic {
val (x, y) = loc
val current = place(x, y)
for (ant <- current.ant) {
@ -200,6 +210,11 @@ class AntActor(initLoc: (Int, Int)) extends WorldActor {
class Evaporator extends WorldActor {
import Config._
import World._
implicit val txFactory = TransactionFactory(familyName = "evaporator")
val evaporate = (pher: Float) => pher * EvapRate
def act = for (x <- 0 until Dim; y <- 0 until Dim) place(x, y) pher evaporate
def act = for (x <- 0 until Dim; y <- 0 until Dim) {
atomic { place(x, y) pher evaporate }
}
}

View file

@ -8,13 +8,13 @@ size(Dim * scale, Dim * scale)
smooth()
override def setup() {
background(255)
background(255)
World.start
}
def draw() {
for (x <- 0 until Dim; y <- 0 until Dim) {
val cell = atomic { World.place(x, y).cell }
val world = World.snapshot
for (x <- 0 until Dim; y <- 0 until Dim; cell <- world(x)(y)) {
val (rx, ry, rw, rh) = (x * scale, y * scale, scale, scale)
noStroke()
fill(255)
@ -39,7 +39,7 @@ val s = scale - 1
val m = s / 2
def antLine(dir: Int) = dir match {
case 0|4 => (m, 0, m, s)
case 0|4 => (m, 0, m, s)
case 1|5 => (s, 0, 0, s)
case 2|6 => (s, m, 0, m)
case _ => (s, s, 0, 0)