swarm-0.5.0.0: 2D resource gathering game with programmable robots
LicenseBSD-3-Clause
Safe HaskellSafe-Inferred
LanguageHaskell2010

Swarm.Game.Step.Combustion

Description

Some entities are "combustible". A command, Ignite, will initiate combustion on such an entity. Furthermore, combustion can spread to (4-)adjacent entities, depending on the ignition property of that entity.

Short-lived robots are used to illustrate the combusting entity as well as to initiate the delayed combustion of its neighbors.

Synopsis

Documentation

igniteCommand :: (HasRobotStepState sig m, Has (Lift IO) sig m) => Const -> Direction -> m () Source #

addCombustionBot :: Has (State GameState) sig m => Entity -> Combustibility -> TimeSpec -> Cosmic Location -> m Integer Source #

Construct a "combustion robot" from entity and position and add it to the world. It has low priority and will be covered by placed entities. The "combustion bot" represents the burning of a single entity; propagating the fire to neighbors is handled upstream, within the Ignite command.

combustionProgram :: Integer -> Combustibility -> ProcessedTerm Source #

A system program for a "combustion robot", to burn an entity after it is ignited.

For efficiency, we determine a priori (i.e. the instant the combustion robot is spawned) whether any neighbors will eventually be burned, based on probabilities.

Note that it is possible that new neighbors may be introduced while combustion is in progress. Although it may be more realistic to subject these to possible combustion as well, we do not bother.

Though if we did actually want to do that, some options are:

  1. Create sub-partitions (of say, 10-tick duration) of the combustion duration to re-evaluate opportunities to light adjacent entities on fire.
  2. Use the Watch command to observe for changes to adjacent entities. Note that if we "wake" from our Wait due to the Watch being triggered, we would need to maintain bookkeeping of how much time is left.
  3. Spawn more robots whose sole purpose is to observe for changes to neighbor cells. This would avoid polluting the logic of the currently burning cell with logic to manage probabilities of combustion propagation.

igniteNeighbor :: Has (State GameState) sig m => TimeSpec -> Integer -> Cosmic Location -> m () Source #

We treat the ignition field in the Combustibility record as a rate in a Poisson distribution. Ignition of neighbors depends on that particular neighbor entity's combustion rate, but also on the duration that the current entity will burn.

addIgnitionBot :: Has (State GameState) sig m => Integer -> Entity -> TimeSpec -> Cosmic Location -> m () Source #

Construct an invisible "ignition robot" and add it to the world. Its sole purpose is to delay the Ignite command for a neighbor that has been a priori determined that it shall be ignited.