private int ComputeNewHormoneDensity(WorldCell previousGenWorldCell, ColonyCell cell) { var previousHormoneDensity = previousGenWorldCell.GetMoveHormoneDensity(cell.Colony); // evaporate movement hormone from cell double evaporated = (double)previousHormoneDensity * cell.Colony.HormoneEvaporationRatio; // remove movement hormone that will be dissipated to neighboring cells double dissipated = (double)previousHormoneDensity * cell.Colony.HormoneDissipationRatio; // add movement hormone dissipated from neighboring cells of the same colony double collected = 0.0; foreach (var neighborCell in previousGenWorldCell._neighbors) { double neighborDissipation = neighborCell.GetMoveHormoneDensity(cell.Colony) * cell.Colony.HormoneDissipationRatio; double collectedFromNeighbor = neighborDissipation / neighborCell._neighbors.Count; collected += collectedFromNeighbor; } // add movement hormone deposited by moving cells double depositedByLeaving = previousGenWorldCell.ComputeCreatureDensityMovementLoss(cell.Colony) * cell.Colony.HormoneLeavingCreatureDepositionRatio / cell.Colony.CreatureMoveRate; double depositedByArriving = previousGenWorldCell.ComputeCreatureDensityMovementGain(cell.Colony) * cell.Colony.HormoneArrivingCreatureDepositionRatio / cell.Colony.CreatureMoveRate; var newHormoneDensity = (int)( previousHormoneDensity - evaporated - dissipated + collected + depositedByLeaving + depositedByArriving); return(Math.Max(0, newHormoneDensity)); }
/// <summary> /// Convenience constructor for a hex-rectangle environment. /// More complex, arbitrary patterns/shapes possible, but indexing by row and column still works because it's a (hex) grid. /// When that happens, this becomes RectangularHexWorld, and appropriate methods become part of parent class. /// </summary> public HexWorld(int rows, int cols) { RowCount = rows; ColCount = cols; _currentCells = new WorldCell[rows, cols]; _nextCells = new WorldCell[rows, cols]; // initialize cell containers ForEachPosition((row, col) => { _currentCells[row, col] = new WorldCell(row, col); _nextCells[row, col] = new WorldCell(row, col); }); // add neighbors to each container ForEachCell((current, next, coord) => { IEnumerable <Coord> neighborPositions = ComputeNeighborPositions(coord.Row, coord.Col); current.AddNeighbors(neighborPositions.Select((nbrPos) => GetCurrentCell(nbrPos))); next.AddNeighbors(neighborPositions.Select((nbrPos) => GetNextCell(nbrPos))); }); _colony = new List <Colony>(); }
public void MutateToNextGen(WorldCell previousGenWorldCell) { foreach (ColonyCell cell in _colonyCells.Values) { cell.MoveHormoneDensity = ComputeNewHormoneDensity(previousGenWorldCell, cell); cell.CreatureDensity = ComputeNewCreatureDensity(previousGenWorldCell, cell); } }
private int ComputeNewCreatureDensity(WorldCell previousGenWorldCell, ColonyCell cell) { double previousCreatureDensity = previousGenWorldCell.GetCreatureDensity(cell.Colony); // trans movement double movementCreatureLoss = previousGenWorldCell.ComputeCreatureDensityMovementLoss(cell.Colony); double movementCreatureGain = previousGenWorldCell.ComputeCreatureDensityMovementGain(cell.Colony); // overpressure rebound movement double reboundCreatureLoss = previousGenWorldCell.ComputeCreatureDensityReboundLoss(cell.Colony); double reboundCreatureGain = previousGenWorldCell.ComputeCreatureDensityReboundGain(cell.Colony); double creatureMultiplicationGain = previousGenWorldCell.ComputeCreatureDensityMultiplicationGain(cell.Colony); var newCreatureDensity = (int)( previousCreatureDensity - movementCreatureLoss - reboundCreatureLoss + movementCreatureGain + reboundCreatureGain + creatureMultiplicationGain); return(Math.Max(0, newCreatureDensity)); }
public void AddNeighbor(WorldCell neighbor) { _neighbors.Add(neighbor); }