コード例 #1
0
        public void IterationTest()
        {
            const int bitSetSize = 1000;
            const int sampleSize = bitSetSize / 10;

            var set = new SparseBitSet(bitSetSize);

            // Generate random but unique bit numbers:
            var bitnums = Enumerable.Range(0, set.Length).ReservoirSample(sampleSize);

            foreach (int i in bitnums)
            {
                set.Set(i);
            }

            Assert.Equal(100, set.Cardinality);

            // Retrieve ids in ascending order:
            var actual = new List <int>();
            int id     = -1;

            while ((id = set.NextSetBit(id + 1)) >= 0)
            {
                actual.Add(id);
            }

            var expected = bitnums.ToList();

            expected.Sort((a, b) => a.CompareTo(b));
            Assert.Equal(expected, actual);
        }
コード例 #2
0
        void FloodFill(Player p, ushort x, ushort y, ushort z, byte oldType, byte oldExtType, DrawMode fillType,
                       SparseBitSet bits, List <int> buffer, List <int> origins, int depth)
        {
            if (bits.Get(x, y, z) || buffer.Count > p.group.maxBlocks)
            {
                return;
            }
            int index = p.level.PosToInt(x, y, z);

            if (depth > 2000)
            {
                origins.Add(index); return;
            }
            bits.Set(x, y, z, true);
            buffer.Add(index);

            if (fillType != DrawMode.verticalX)   // x
            {
                if (CheckTile(p, (ushort)(x + 1), y, z, oldType, oldExtType))
                {
                    FloodFill(p, (ushort)(x + 1), y, z, oldType, oldExtType, fillType, bits, buffer, origins, depth + 1);
                }
                if (CheckTile(p, (ushort)(x - 1), y, z, oldType, oldExtType))
                {
                    FloodFill(p, (ushort)(x - 1), y, z, oldType, oldExtType, fillType, bits, buffer, origins, depth + 1);
                }
            }

            if (fillType != DrawMode.verticalZ)   // z
            {
                if (CheckTile(p, x, y, (ushort)(z + 1), oldType, oldExtType))
                {
                    FloodFill(p, x, y, (ushort)(z + 1), oldType, oldExtType, fillType, bits, buffer, origins, depth + 1);
                }
                if (CheckTile(p, x, y, (ushort)(z - 1), oldType, oldExtType))
                {
                    FloodFill(p, x, y, (ushort)(z - 1), oldType, oldExtType, fillType, bits, buffer, origins, depth + 1);
                }
            }

            if (!(fillType == DrawMode.down || fillType == DrawMode.layer))   // y up
            {
                if (CheckTile(p, x, (ushort)(y + 1), z, oldType, oldExtType))
                {
                    FloodFill(p, x, (ushort)(y + 1), z, oldType, oldExtType, fillType, bits, buffer, origins, depth + 1);
                }
            }

            if (!(fillType == DrawMode.up || fillType == DrawMode.layer))   // y down
            {
                if (CheckTile(p, x, (ushort)(y - 1), z, oldType, oldExtType))
                {
                    FloodFill(p, x, (ushort)(y - 1), z, oldType, oldExtType, fillType, bits, buffer, origins, depth + 1);
                }
            }
        }
コード例 #3
0
        public void SingletonTest()
        {
            var singletonSet = new SparseBitSet(1);

            Assert.False(singletonSet.Get(0));
            Assert.Equal(0, singletonSet.Cardinality);
            singletonSet.Set(0).Clear(0).Set(0);
            Assert.True(singletonSet.Get(0));
            Assert.Equal(1, singletonSet.Cardinality);
            Assert.Equal(1, singletonSet.Length);
            Assert.Equal(0, singletonSet.NextSetBit(0));
            Assert.Equal(-1, singletonSet.NextSetBit(1));
        }
コード例 #4
0
        public void SingleChunkTest()
        {
            var singleChunkSet = new SparseBitSet(4096);

            Assert.Equal(0, singleChunkSet.Cardinality);
            singleChunkSet.Set(2345).Set(64);
            Assert.Equal(2, singleChunkSet.Cardinality);
            Assert.True(singleChunkSet.Get(64));
            Assert.False(singleChunkSet.Get(65));
            Assert.True(singleChunkSet.Get(2345));
            Assert.False(singleChunkSet.Get(2346));
            Assert.Equal(64, singleChunkSet.NextSetBit(0));
            Assert.Equal(2345, singleChunkSet.NextSetBit(64 + 1));
            Assert.Equal(-1, singleChunkSet.NextSetBit(2345 + 1));
        }
コード例 #5
0
        public void NextSetBitTest()
        {
            var set = new SparseBitSet(10000);             // 3 chunks, bits 0..9999

            set.Set(0).Set(1).Set(2).Set(10).Set(100);     // all in 1st chunk
            set.Set(5000).Set(5001).Set(5100);             // all in 2nd chunk
            Assert.Equal(8, set.Cardinality);
            Assert.Equal(0, set.NextSetBit(0));
            Assert.Equal(1, set.NextSetBit(1));
            Assert.Equal(2, set.NextSetBit(2));
            Assert.Equal(10, set.NextSetBit(3));
            Assert.Equal(10, set.NextSetBit(10));
            Assert.Equal(100, set.NextSetBit(11));
            Assert.Equal(100, set.NextSetBit(100));
            Assert.Equal(5000, set.NextSetBit(101));
            Assert.Equal(5000, set.NextSetBit(5000));
            Assert.Equal(5001, set.NextSetBit(5001));
            Assert.Equal(5100, set.NextSetBit(5002));
            Assert.Equal(5100, set.NextSetBit(5100));
            Assert.Equal(-1, set.NextSetBit(5101));             // no next set bit
        }
コード例 #6
0
        public void PerformanceTest(int length, double maxAllowedSecs)
        {
            const int seed      = 1234;
            var       startTime = DateTime.Now;
            int       count     = length / 100;
            var       largeSet  = new SparseBitSet(length);

            var random = new Random(seed);

            for (int k = 0; k < count; k++)
            {
                int i = random.Next(length);
                largeSet.Set(i);
            }

            random = new Random(seed);
            for (int k = 0; k < count; k++)
            {
                int i = random.Next(length);
                Assert.True(largeSet.Get(i));
            }

            random = new Random(seed);
            for (int k = 0; k < count; k++)
            {
                int i = random.Next(length);
                largeSet.Clear(i);
            }

            var elapsed = DateTime.Now - startTime;

            _output.WriteLine(@"size={0:N0} count={1:N0} set/get/clear elapsed={2}",
                              length, count, elapsed);

            Assert.Equal(0, largeSet.Cardinality);
            Assert.True(elapsed < TimeSpan.FromSeconds(maxAllowedSecs), "Too slow");
        }
コード例 #7
0
        public unsafe static List <int> FloodFill(Player p, int index, ExtBlock block, DrawMode mode)
        {
            Level        lvl    = p.level;
            SparseBitSet bits   = new SparseBitSet(lvl.Width, lvl.Height, lvl.Length);
            List <int>   buffer = new List <int>();
            Queue <int>  temp   = new Queue <int>();

            const int max = 65536;
            int       count = 0, oneY = lvl.Width * lvl.Length;
            int *     pos = stackalloc int[max];

            pos[0] = index; count++;

            while (count > 0 && buffer.Count <= p.group.DrawLimit)
            {
                index = pos[count - 1]; count--;
                ushort x = (ushort)(index % lvl.Width);
                ushort y = (ushort)((index / lvl.Width) / lvl.Length);
                ushort z = (ushort)((index / lvl.Width) % lvl.Length);

                if (temp.Count > 0)
                {
                    pos[count] = temp.Dequeue(); count++;
                }
                if (bits.Get(x, y, z))
                {
                    continue;
                }

                bits.Set(x, y, z, true);
                buffer.Add(index);

                if (mode != DrawMode.verticalX)   // x
                {
                    if (lvl.GetBlock((ushort)(x + 1), y, z) == block)
                    {
                        if (count == max)
                        {
                            temp.Enqueue(index + 1);
                        }
                        else
                        {
                            pos[count] = index + 1; count++;
                        }
                    }
                    if (lvl.GetBlock((ushort)(x - 1), y, z) == block)
                    {
                        if (count == max)
                        {
                            temp.Enqueue(index - 1);
                        }
                        else
                        {
                            pos[count] = index - 1; count++;
                        }
                    }
                }

                if (mode != DrawMode.verticalZ)   // z
                {
                    if (lvl.GetBlock(x, y, (ushort)(z + 1)) == block)
                    {
                        if (count == max)
                        {
                            temp.Enqueue(index + lvl.Width);
                        }
                        else
                        {
                            pos[count] = index + lvl.Width; count++;
                        }
                    }
                    if (lvl.GetBlock(x, y, (ushort)(z - 1)) == block)
                    {
                        if (count == max)
                        {
                            temp.Enqueue(index - lvl.Width);
                        }
                        else
                        {
                            pos[count] = index - lvl.Width; count++;
                        }
                    }
                }

                if (!(mode == DrawMode.down || mode == DrawMode.layer))   // y up
                {
                    if (lvl.GetBlock(x, (ushort)(y + 1), z) == block)
                    {
                        if (count == max)
                        {
                            temp.Enqueue(index + oneY);
                        }
                        else
                        {
                            pos[count] = index + oneY; count++;
                        }
                    }
                }

                if (!(mode == DrawMode.up || mode == DrawMode.layer))   // y down
                {
                    if (lvl.GetBlock(x, (ushort)(y - 1), z) == block)
                    {
                        if (count == max)
                        {
                            temp.Enqueue(index - oneY);
                        }
                        else
                        {
                            pos[count] = index - oneY; count++;
                        }
                    }
                }
            }
            bits.Clear();
            return(buffer);
        }
コード例 #8
0
        protected override void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
        {
            p.ClearBlockchange();
            CatchPos cpos = (CatchPos)p.blockchangeObject;
            byte     oldType = p.level.GetTile(x, y, z), oldExtType = 0;

            if (oldType == Block.custom_block)
            {
                oldExtType = p.level.GetExtTile(x, y, z);
            }
            p.RevertBlock(x, y, z);
            GetRealBlock(type, extType, p, ref cpos);

            if (cpos.type == oldType)
            {
                if (cpos.type != Block.custom_block)
                {
                    Player.SendMessage(p, "Cannot fill with the same type."); return;
                }
                if (cpos.extType == oldExtType)
                {
                    Player.SendMessage(p, "Cannot fill with the same type."); return;
                }
            }
            if (!Block.canPlace(p, oldType) && !Block.BuildIn(oldType))
            {
                Player.SendMessage(p, "Cannot fill with that."); return;
            }

            SparseBitSet bits = new SparseBitSet(p.level.Width, p.level.Height, p.level.Length);
            List <int>   buffer = new List <int>(), origins = new List <int>();

            FloodFill(p, x, y, z, oldType, oldExtType, cpos.mode, bits, buffer, origins, 0);

            int totalFill = origins.Count;

            for (int i = 0; i < totalFill; i++)
            {
                int pos = origins[i];
                p.level.IntToPos(pos, out x, out y, out z);
                FloodFill(p, x, y, z, oldType, oldExtType, cpos.mode, bits, buffer, origins, 0);
                totalFill = origins.Count;
            }

            FillDrawOp op = new FillDrawOp();

            op.Positions = buffer;
            int   brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
            Brush brush       = GetBrush(p, cpos, brushOffset);

            if (brush == null)
            {
                return;
            }
            if (!DrawOp.DoDrawOp(op, brush, p, cpos.x, cpos.y, cpos.z, cpos.x, cpos.y, cpos.z))
            {
                return;
            }
            bits.Clear();
            op.Positions = null;

            if (p.staticCommands)
            {
                p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
            }
        }