In this document:
aa: Initial "facing" direction:
Fireflies are considered to be facing in one of four directions (up, down, left, right) although visually you can't tell which direction a firefly is currently facing by looking at it. Fireflies always like to turn to their left if possible (going round and round in circles if possible), failing that they will go forward, or finally they will turn to their right if they can't move forward.
In BoulderDash I (on the C64), fireflies always begin "facing left", meaning that they will make their first movement down if possible (because fireflies always try to turn left when possible). The C64 cave format allows you to specify the initial direction of each firefly individually, however all caves in the C64 BoulderDash I have their fireflies facing left to begin with. It is recommended that all fireflies begin life facing left.
The way a firefly works is this:
if (space to the firefly's left is empty) then turn 90 degrees to firefly's left; move one space in this new direction; } else if (space ahead is empty) then move one space forwards; } else { turn 90 degrees to the firefly's right; _do not move_; }The key thing to note is that if a firefly is forced to turn against its "preferred direction", it does not actually move for that frame.
The result is that when a firefly can make a left turn, it will do so "instantly", but if forced to make a right turn, it will pause for one frame before doing so. If forced to turn around (180 degrees), it will pause for two frames before going back the way it came.
Because the check is made before the fly moves, you may momentarily see the fly next to an amoeba/Rockford for one frame before the explosion happens. Note that (unusually), the firefly will also explode if next to a "Rockford, scanned this frame". By "scanned this frame" I mean that Rockford has already moved once during this scan frame, and it is marked as such so that if the same Rockford is come across again in the same scan frame (because Rockford moved down or right) then the player won't have the opportinity to move Rockford again.
procedure ScanFirefly(in positionType positionOfFirefly; in directionType directionOfFirefly) # Local variables positionType NewPosition; directionType NewDirection; # First check whether the firefly will explode by being next to Rockford, # Rockford-scanned-this-frame or amoeba but not amoeba-scanned-this-frame. if (FlyWillExplode(positionOfFirefly)) then Explode(positionOfFirefly, explodeToSpace); else # Failing that, attempt to move turn left and move there if possible NewPosition = GetNextFlyPosition(positionOfFirefly, directionOfFirefly, turnLeft); if (GetObjectAtPosition(NewPosition) == objSpace) then NewDirection = GetNewDirection(directionOfFirefly, turnLeft); PlaceFirefly(NewPosition, NewDirection); PlaceSpace(positionOfFirefly); # ie old position else # Failing that, attempt to move straight ahead NewPosition = GetNextFlyPosition(positionOfFirefly, directionOfFirefly, straightAhead); if (GetObjectAtPosition(NewPosition) == objSpace) then PlaceFirefly(NewPosition, directionOfFirefly); # ie keep same direction PlaceSpace(positionOfFirefly); # ie old position else # Failing that, turn to the right but do not move NewDirection = GetNewDirection(directionOfFirefly, turnRight); PlaceFirefly(positionOfFirefly, NewDirection); # old position, new direction endif endif endif endprocedure #################### function FlyWillExplode(in positionType aPosition):Boolean # Check the four directions around a fly at a given position to see whether # it will explode. Returns true if so, false if not. # Local variables Boolean ExplodedYet; # Check the four directions to see whether the fly will explode ExplodedYet := CheckFlyExplode(GetRelativePosition(aPosition, up1)); if (not ExplodedYet) then ExplodedYet := CheckFlyExplode(GetRelativePosition(aPosition, left1)); endif if (not ExplodedYet) then ExplodedYet := CheckFlyExplode(GetRelativePosition(aPosition, right1)); endif if (not ExplodedYet) then ExplodedYet := CheckFlyExplode(GetRelativePosition(aPosition, down1)); endif # Return function result return ExplodedYet; endfunction #################### function CheckFlyExplode(in positionType aPosition):Boolean # Check the given position to see whether it contains an object which a # fly will explode if it is in contact with (ie Rockford or Amoeba). # Returns true if so, false if not. return (GetObjectAtPosition(aPosition) in {objRockford, objRockfordScanned, objAmoeba}); endfunction