Esempio n. 1
0
 public static VoxelInfo GetStrongerVoxel(ref VoxelInfo a, ref VoxelInfo b)
 {
     return a;
 }
Esempio n. 2
0
        /// <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;
        }