Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ inThisBuild(Seq(
))

lazy val xinuk = project.in(file("."))
.aggregate(`xinuk-core`, formin, fortwist, torch)
.aggregate(`xinuk-core`, formin, fortwist, torch, school)
.disablePlugins(AssemblyPlugin)

lazy val `xinuk-core` = project
Expand Down Expand Up @@ -83,4 +83,5 @@ def modelProject(projectName: String)(mainClassName: String): Project = {
lazy val formin = modelProject("formin")("pl.edu.agh.formin.ForminMain")
lazy val fortwist = modelProject("fortwist")("pl.edu.agh.fortwist.FortwistMain")
lazy val torch = modelProject("torch")("pl.edu.agh.torch.TorchMain")
lazy val mock = modelProject("mock")("pl.edu.agh.mock.MockMain")
lazy val mock = modelProject("mock")("pl.edu.agh.mock.MockMain")
lazy val school = modelProject("school")("pl.edu.agh.school.SchoolMain")
16 changes: 9 additions & 7 deletions formin/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ clustering {

xinuk {
classes = [
"pl.edu.agh.formin.model.AlgaeCell",
"pl.edu.agh.formin.model.ForaminiferaCell",
"pl.edu.agh.formin.simulation.ForminMetrics",
"pl.edu.agh.school.model.AlgaeCell",
"pl.edu.agh.school.model.ForaminiferaCell",
"pl.edu.agh.school.simulation.ForminMetrics",
]
}

Expand All @@ -31,16 +31,18 @@ formin {
signalSpeedRatio = 2
signalSuppressionFactor = 0.5
signalAttenuationFactor = 1
gridSize = 100
gridSize = 50
spawnChance = 0.1
foraminiferaSpawnChance = 0.3
foraminiferaInitialSignal = -1
algaeInitialSignal = 1
foraminiferaInitialSignal = [-1, 0]
foraminiferaPursuedSignalIndex = 0
algaeInitialSignal = [1, 0]
algaePursuedSignalIndex = 0
guiType = basic
guiCellSize = 4
workersRoot = 2
iterationsNumber = 10000
isSupervisor = true
shardingMod = 144
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package pl.edu.agh.formin
package pl.edu.agh.school

import java.awt.Color

import com.typesafe.scalalogging.LazyLogging
import pl.edu.agh.formin.algorithm.ForminMovesController
import pl.edu.agh.formin.config.ForminConfig
import pl.edu.agh.formin.model.parallel.ForminConflictResolver
import pl.edu.agh.formin.model.{AlgaeCell, ForaminiferaCell}
import pl.edu.agh.school.algorithm.ForminMovesController
import pl.edu.agh.school.config.ForminConfig
import pl.edu.agh.school.model.parallel.ForminConflictResolver
import pl.edu.agh.school.model.{AlgaeCell, ForaminiferaCell}
import pl.edu.agh.xinuk.Simulation
import pl.edu.agh.xinuk.model.{DefaultSmellPropagation, SmellingCell}

Expand All @@ -26,7 +26,7 @@ object ForminMain extends LazyLogging {
private def cellToColor(cell: SmellingCell): Color = {
cell match {
case AlgaeCell(_, _) => new Color(0, 128, 0)
case ForaminiferaCell(_, _, _) => new Color(139, 69, 19)
case ForaminiferaCell(_, _, _, _) => new Color(139, 69, 19)
case _ => Color.WHITE
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package pl.edu.agh.formin.algorithm
package pl.edu.agh.school.algorithm

import com.avsystem.commons
import com.avsystem.commons.SharedExtensions._
import com.avsystem.commons.misc.Opt
import pl.edu.agh.formin.config.ForminConfig
import pl.edu.agh.formin.model._
import pl.edu.agh.formin.simulation.ForminMetrics
import pl.edu.agh.school.config.ForminConfig
import pl.edu.agh.school.model._
import pl.edu.agh.school.simulation.ForminMetrics
import pl.edu.agh.xinuk.algorithm.MovesController
import pl.edu.agh.xinuk.model._

Expand Down Expand Up @@ -49,6 +49,9 @@ final class ForminMovesController(bufferZone: TreeSet[(Int, Int)])(implicit conf
Grid.SubcellCoordinates
.map { case (i, j) => cell.smell(i)(j) }
.zipWithIndex
.map {
case (signalVector, index) => (signalVector(cell.pursuedSignalIndex), index)
}
.sorted(implicitly[Ordering[(Signal, Int)]].reverse)
.iterator
.map { case (_, idx) =>
Expand Down Expand Up @@ -172,10 +175,10 @@ final class ForminMovesController(bufferZone: TreeSet[(Int, Int)])(implicit conf
y <- 0 until config.gridSize
} {
this.grid.cells(x)(y) match {
case ForaminiferaCell(energy, _, _) =>
case ForaminiferaCell(energy, _, _, _) =>
foraminiferaTotalEnergy += energy.value
foraminiferaCount += 1
case BufferCell(ForaminiferaCell(energy, _, _)) =>
case BufferCell(ForaminiferaCell(energy, _, _, _)) =>
foraminiferaTotalEnergy += energy.value
foraminiferaCount += 1
case AlgaeCell(_, _) | BufferCell(AlgaeCell(_, _)) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package pl.edu.agh.formin.config
package pl.edu.agh.school.config

import pl.edu.agh.xinuk.config.{GuiType, XinukConfig}
import pl.edu.agh.xinuk.model.{Energy, Signal}
import pl.edu.agh.xinuk.model.{Energy, Signal, SignalVector}

/*
FSE - foraminifera start energy; FSE ∈ [0,1] && FSE ∈ R.
Expand Down Expand Up @@ -32,8 +32,10 @@ final case class ForminConfig(
gridSize: Int,
spawnChance: Double,
foraminiferaSpawnChance: Double,
foraminiferaInitialSignal: Signal,
algaeInitialSignal: Signal,
foraminiferaInitialSignal: List[Signal],
foraminiferaPursuedSignalIndex: Int,
algaeInitialSignal: List[Signal],
algaePursuedSignalIndex: Int,
guiType: GuiType,
guiCellSize: Int,
workersRoot: Int,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package pl.edu.agh.formin.model
package pl.edu.agh.school.model

import pl.edu.agh.formin.config.ForminConfig
import pl.edu.agh.school.config.ForminConfig
import pl.edu.agh.xinuk.model.Cell.SmellArray
import pl.edu.agh.xinuk.model.{BufferCell, EmptyCell, GridPart, SmellingCell}
import pl.edu.agh.xinuk.model.SignalVector.SignalVectorOps

final case class AlgaeCell(smell: SmellArray, lifespan: Long) extends SmellingCell {
override type Self = AlgaeCell
Expand All @@ -18,12 +19,12 @@ object AlgaeAccessible {

def unapply(arg: EmptyCell)(implicit config: ForminConfig): AlgaeAccessible[AlgaeCell] =
new AlgaeAccessible[AlgaeCell] {
override def withAlgae(lifespan: Long): AlgaeCell = AlgaeCell(arg.smellWith(config.algaeInitialSignal), lifespan)
override def withAlgae(lifespan: Long): AlgaeCell = AlgaeCell(arg.smellWith(config.algaeInitialSignal.toSignalVector), lifespan)
}

def unapply(arg: BufferCell)(implicit config: ForminConfig): AlgaeAccessible[BufferCell] =
new AlgaeAccessible[BufferCell] {
override def withAlgae(lifespan: Long): BufferCell = BufferCell(AlgaeCell(arg.smellWith(config.algaeInitialSignal), lifespan))
override def withAlgae(lifespan: Long): BufferCell = BufferCell(AlgaeCell(arg.smellWith(config.algaeInitialSignal.toSignalVector), lifespan))
}

def unapply(arg: GridPart)(implicit config: ForminConfig): Option[AlgaeAccessible[GridPart]] = arg match {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package pl.edu.agh.formin.model
package pl.edu.agh.school.model

import pl.edu.agh.formin.config.ForminConfig
import pl.edu.agh.school.config.ForminConfig
import pl.edu.agh.xinuk.model.Cell.SmellArray
import pl.edu.agh.xinuk.model._
import pl.edu.agh.xinuk.model.SignalVector.SignalVectorOps

final case class ForaminiferaCell(energy: Energy, smell: SmellArray, lifespan: Long) extends SmellingCell {
final case class ForaminiferaCell(energy: Energy, smell: SmellArray, lifespan: Long, pursuedSignalIndex: Int) extends SmellingCell {
override type Self = ForaminiferaCell

override def withSmell(smell: SmellArray): ForaminiferaCell = copy(smell = smell)
Expand All @@ -18,17 +19,17 @@ object ForaminiferaAccessible {

def unapply(arg: AlgaeCell)(implicit config: ForminConfig): ForaminiferaAccessible[ForaminiferaCell] =
new ForaminiferaAccessible[ForaminiferaCell] {
override def withForaminifera(energy: Energy, lifespan: Long): ForaminiferaCell = ForaminiferaCell(energy + config.algaeEnergeticCapacity, arg.smellWith(config.foraminiferaInitialSignal), lifespan)
override def withForaminifera(energy: Energy, lifespan: Long): ForaminiferaCell = ForaminiferaCell(energy + config.algaeEnergeticCapacity, arg.smellWith(config.foraminiferaInitialSignal.toSignalVector), lifespan, config.foraminiferaPursuedSignalIndex)
}

def unapply(arg: EmptyCell)(implicit config: ForminConfig): ForaminiferaAccessible[ForaminiferaCell] =
new ForaminiferaAccessible[ForaminiferaCell] {
override def withForaminifera(energy: Energy, lifespan: Long): ForaminiferaCell = ForaminiferaCell(energy, arg.smellWith(config.foraminiferaInitialSignal), lifespan)
override def withForaminifera(energy: Energy, lifespan: Long): ForaminiferaCell = ForaminiferaCell(energy, arg.smellWith(config.foraminiferaInitialSignal.toSignalVector), lifespan, config.foraminiferaPursuedSignalIndex)
}

def unapply(arg: BufferCell)(implicit config: ForminConfig): ForaminiferaAccessible[BufferCell] =
new ForaminiferaAccessible[BufferCell] {
override def withForaminifera(energy: Energy, lifespan: Long): BufferCell = BufferCell(ForaminiferaCell(energy, arg.smellWith(config.foraminiferaInitialSignal), lifespan))
override def withForaminifera(energy: Energy, lifespan: Long): BufferCell = BufferCell(ForaminiferaCell(energy, arg.smellWith(config.foraminiferaInitialSignal.toSignalVector), lifespan, config.foraminiferaPursuedSignalIndex))
}

def unapply(arg: GridPart)(implicit config: ForminConfig): Option[ForaminiferaAccessible[GridPart]] = arg match {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package pl.edu.agh.formin.model.parallel
package pl.edu.agh.school.model.parallel

import pl.edu.agh.formin.config.ForminConfig
import pl.edu.agh.formin.model._
import pl.edu.agh.formin.simulation.ForminMetrics
import pl.edu.agh.school.config.ForminConfig
import pl.edu.agh.school.model._
import pl.edu.agh.school.simulation.ForminMetrics
import pl.edu.agh.xinuk.model._
import pl.edu.agh.xinuk.model.parallel.ConflictResolver

Expand All @@ -16,14 +16,14 @@ object ForminConflictResolver extends ConflictResolver[ForminConfig] {
(incomingCell.withSmell(incomingCell.smell + currentSmell), ForminMetrics.empty())
case (currentCell: SmellingCell, EmptyCell(incomingSmell)) =>
(currentCell.withSmell(currentCell.smell + incomingSmell), ForminMetrics.empty())
case (AlgaeCell(currentSmell, currentLifespan), ForaminiferaCell(energy, incomingSmell, incomingLifespan)) =>
(ForaminiferaCell(energy + config.algaeEnergeticCapacity, incomingSmell + currentSmell, incomingLifespan), ForminMetrics(0, 0, 0, 0, 0, 1, 0, currentLifespan))
case (ForaminiferaCell(energy, currentSmell, currentLifespan), AlgaeCell(incomingSmell, incomingLifespan)) =>
(ForaminiferaCell(energy + config.algaeEnergeticCapacity, incomingSmell + currentSmell, currentLifespan), ForminMetrics(0, 0, 0, 0, 0, 1, 0, incomingLifespan))
case (AlgaeCell(currentSmell, currentLifespan), ForaminiferaCell(energy, incomingSmell, incomingLifespan, pursuedSignalIndex)) =>
(ForaminiferaCell(energy + config.algaeEnergeticCapacity, incomingSmell + currentSmell, incomingLifespan, pursuedSignalIndex), ForminMetrics(0, 0, 0, 0, 0, 1, 0, currentLifespan))
case (ForaminiferaCell(energy, currentSmell, currentLifespan, pursuedSignalIndex), AlgaeCell(incomingSmell, incomingLifespan)) =>
(ForaminiferaCell(energy + config.algaeEnergeticCapacity, incomingSmell + currentSmell, currentLifespan, pursuedSignalIndex), ForminMetrics(0, 0, 0, 0, 0, 1, 0, incomingLifespan))
case (AlgaeCell(currentSmell, lifespan), AlgaeCell(incomingSmell, incomingLifespan)) =>
(AlgaeCell(currentSmell + incomingSmell, math.max(lifespan, incomingLifespan)), ForminMetrics.empty())
case (ForaminiferaCell(currentEnergy, currentSmell, lifespan), ForaminiferaCell(incomingEnergy, incomingSmell, incomingLifespan)) =>
(ForaminiferaCell(currentEnergy + incomingEnergy, currentSmell + incomingSmell, math.max(lifespan, incomingLifespan)), ForminMetrics.empty())
case (ForaminiferaCell(currentEnergy, currentSmell, lifespan, _), ForaminiferaCell(incomingEnergy, incomingSmell, incomingLifespan, pursuedSignalIndex)) => // TODO: here are place where two smells can intersect
(ForaminiferaCell(currentEnergy + incomingEnergy, currentSmell + incomingSmell, math.max(lifespan, incomingLifespan), pursuedSignalIndex), ForminMetrics.empty())
case (Obstacle, _) => (Obstacle, ForminMetrics.empty())
case (x, y) => throw new UnsupportedOperationException(s"Unresolved conflict: $x with $y")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pl.edu.agh.formin.simulation
package pl.edu.agh.school.simulation

import pl.edu.agh.xinuk.simulation.Metrics

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package pl.edu.agh.formin
package pl.edu.agh.school

import org.scalatest.{BeforeAndAfter, FlatSpecLike, Matchers}
import pl.edu.agh.formin.config.ForminConfig
import pl.edu.agh.formin.model._
import pl.edu.agh.school.config.ForminConfig
import pl.edu.agh.school.model._
import pl.edu.agh.xinuk.config.GuiType
import pl.edu.agh.xinuk.model._

Expand All @@ -21,8 +21,10 @@ class GridTest extends FlatSpecLike with Matchers with BeforeAndAfter {
gridSize = 5,
spawnChance = 0.1,
foraminiferaSpawnChance = 0.5,
foraminiferaInitialSignal = Signal(-1),
algaeInitialSignal = Signal(1),
foraminiferaInitialSignal = List(Signal(-1), Signal(0)),
foraminiferaPursuedSignalIndex = 0,
algaeInitialSignal = List(Signal(1), Signal(0)),
algaePursuedSignalIndex = 0,
guiType = GuiType.None,
guiCellSize = 4,
workersRoot = 1,
Expand Down Expand Up @@ -62,27 +64,27 @@ class GridTest extends FlatSpecLike with Matchers with BeforeAndAfter {
grid.cells(3)(2) = grid.propagatedSignal(DefaultSmellPropagation.calculateSmellAddendsStandard, 3, 2)
grid.cells(3)(1) = grid.propagatedSignal(DefaultSmellPropagation.calculateSmellAddendsStandard, 3, 1)

grid.cells(2)(2).smell(0)(0).value shouldBe -1
grid.cells(2)(2).smell(0)(1).value shouldBe -1
grid.cells(2)(2).smell(0)(2).value shouldBe -1
grid.cells(2)(2).smell(0)(0).value(0).value shouldBe -1
grid.cells(2)(2).smell(0)(1).value(0).value shouldBe -1
grid.cells(2)(2).smell(0)(2).value(0).value shouldBe -1

grid.cells(3)(2).smell(0)(1).value shouldBe -1.5
grid.cells(3)(2).smell(0)(1).value(0).value shouldBe -1.5

grid.cells(3)(1).smell(0)(2).value shouldBe -0.5
grid.cells(3)(1).smell(0)(2).value(0).value shouldBe -0.5
}

it should "propagate signal correctly for one algae cell" in {
grid.cells(2)(2) = AlgaeAccessible.unapply(EmptyCell.Instance).withAlgae(0)
grid.cells(3)(2) = grid.propagatedSignal(DefaultSmellPropagation.calculateSmellAddendsStandard, 3, 2)
grid.cells(3)(1) = grid.propagatedSignal(DefaultSmellPropagation.calculateSmellAddendsStandard, 3, 1)

grid.cells(2)(2).smell(0)(0).value shouldBe 1
grid.cells(2)(2).smell(0)(1).value shouldBe 1
grid.cells(2)(2).smell(0)(2).value shouldBe 1
grid.cells(2)(2).smell(0)(0).value(0).value shouldBe 1
grid.cells(2)(2).smell(0)(1).value(0).value shouldBe 1
grid.cells(2)(2).smell(0)(2).value(0).value shouldBe 1

grid.cells(3)(2).smell(0)(1).value shouldBe 1.5
grid.cells(3)(2).smell(0)(1).value(0).value shouldBe 1.5

grid.cells(3)(1).smell(0)(2).value shouldBe 0.5
grid.cells(3)(1).smell(0)(2).value(0).value shouldBe 0.5
}

it should "propagate signal correctly between algae and foraminifera cells" in {
Expand All @@ -93,26 +95,26 @@ class GridTest extends FlatSpecLike with Matchers with BeforeAndAfter {
grid.cells(2)(2) = gridCellWithAlgaeAfterSignalPropagation
grid.cells(3)(2) = gridCellWithForaminiferaAfterSignalPropagation

grid.cells(2)(2).smell(2)(1).value shouldBe -0.5
grid.cells(2)(2).smell(2)(0).value shouldBe 1
grid.cells(2)(2).smell(2)(2).value shouldBe 1
grid.cells(2)(2).smell(0)(0).value shouldBe 1
grid.cells(2)(2).smell(0)(1).value shouldBe 1
grid.cells(2)(2).smell(0)(2).value shouldBe 1

grid.cells(3)(2).smell(0)(0).value shouldBe -1
grid.cells(3)(2).smell(0)(1).value shouldBe 0.5
grid.cells(3)(2).smell(0)(2).value shouldBe -1
grid.cells(3)(2).smell(2)(0).value shouldBe -1
grid.cells(3)(2).smell(2)(1).value shouldBe -1
grid.cells(3)(2).smell(2)(2).value shouldBe -1
grid.cells(2)(2).smell(2)(1).value(0).value shouldBe -0.5
grid.cells(2)(2).smell(2)(0).value(0).value shouldBe 1
grid.cells(2)(2).smell(2)(2).value(0).value shouldBe 1
grid.cells(2)(2).smell(0)(0).value(0).value shouldBe 1
grid.cells(2)(2).smell(0)(1).value(0).value shouldBe 1
grid.cells(2)(2).smell(0)(2).value(0).value shouldBe 1

grid.cells(3)(2).smell(0)(0).value(0).value shouldBe -1
grid.cells(3)(2).smell(0)(1).value(0).value shouldBe 0.5
grid.cells(3)(2).smell(0)(2).value(0).value shouldBe -1
grid.cells(3)(2).smell(2)(0).value(0).value shouldBe -1
grid.cells(3)(2).smell(2)(1).value(0).value shouldBe -1
grid.cells(3)(2).smell(2)(2).value(0).value shouldBe -1
}

it should "not propagate signal on obstacle cell" in {
grid.cells(3)(2) = ForaminiferaAccessible.unapply(EmptyCell.Instance).withForaminifera(config.foraminiferaStartEnergy, 0)
grid.cells(4)(2) = grid.propagatedSignal(DefaultSmellPropagation.calculateSmellAddendsStandard, 4, 2)
grid.cells(3)(2).smell(1)(1).value shouldBe -1
grid.cells(4)(2).smell(0)(1).value shouldBe 0
grid.cells(3)(2).smell(1)(1).value(0).value shouldBe -1
grid.cells(4)(2).smell(0)(1).value(0).value shouldBe 0
}

it should "calculate neighbour cells correctly for middle one" in {
Expand Down
Loading