public static VoxelInfo GetStrongerVoxel(ref VoxelInfo a, ref VoxelInfo b) { return a; }
/// <summary> /// The core of the simulation. This function applies all rules to all /// living voxels. /// </summary> /// <returns>Every change which have to be made to apply the latest changes.</returns> private ConcurrentDictionary<Int32, VoxelInfo> SimulateAsync() { // There is just one map but nobody should write before all have // seen the current state -> collect all results first. ConcurrentDictionary<Int32, VoxelInfo> results = new ConcurrentDictionary<Int32, VoxelInfo>(); Parallel.ForEach(_livingVoxels, currentVoxel => //foreach( KeyValuePair<Int32, LivingVoxel> currentVoxel in _livingVoxels ) { ++currentVoxel.Value.Ticks; // Create a local window for the rule algorithms VoxelInfo[, ,] localFrame = new VoxelInfo[3, 3, 3]; IterateNeighbours((x, y, z) => { Int32 pos = _map.EncodePosition(currentVoxel.Value.X + x - 1, currentVoxel.Value.Y + y - 1, currentVoxel.Value.Z + z - 1); VoxelType voxel = _map.Get(pos); // Living? if (_map.IsLiving(pos)) { // Yes: query more information from the dictinary LivingVoxel voxelInfo = _livingVoxels[pos]; localFrame[z, y, x] = new VoxelInfo(voxel, true, voxelInfo.Generation, voxelInfo.Resources, voxelInfo.Ticks, voxelInfo.From); } else { // No uses directly localFrame[z, y, x] = new VoxelInfo((VoxelType)voxel); } }); // Apply the rule for currentVoxel VoxelInfo[, ,] ruleResult = TypeInformation.GetRule(localFrame[1, 1, 1].Type).ApplyRule(localFrame); if (ruleResult != null) { currentVoxel.Value.Ticks = 0; // Add changes to the change collection IterateNeighbours((x, y, z) => { if (ruleResult[z, y, x] != null && _map.IsInside(currentVoxel.Value.X + x - 1, currentVoxel.Value.Y + y - 1, currentVoxel.Value.Z + z - 1)) { Int32 positionCode = _map.EncodePosition(currentVoxel.Value.X + x - 1, currentVoxel.Value.Y + y - 1, currentVoxel.Value.Z + z - 1); // Two rules tried to grow at the same location. Use decision function results.AddOrUpdate(positionCode, ruleResult[z, y, x], (key, old) => GamePlayUtils.GetStrongerVoxel(ref old, ref ruleResult[z, y, x])); } }); } }); return results; }