Beispiel #1
0
        private Board GetExamplePuzzle3()
        {
            Board b1 = new Board();

            b1.PlaceBlock(BlockFactory.GetBlockByName("F"), 0, 0, 2);
            b1.PlaceBlock(BlockFactory.GetBlockByName("C"), 2, 0, 2);
            return(b1);
        }
Beispiel #2
0
    private static Board GetExamplePuzzle2()
    {
        Board b1 = new Board();

        b1.PlaceBlock(BlockFactory.GetBlockByName("G"), 0, 0, 2);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("C"), 0, 2, 0);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("J"), 0, 4, 0);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("I"), 0, 5, 2);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("F"), 0, 8, 2);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("K"), 1, 1, 0);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("L"), 1, 5, 0);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("E"), 3, 0, 1);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("H"), 3, 3, 0);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("A"), 4, 0, 1);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("D"), 6, 0, 4);
        //b1.PlaceBlock(BlockFactory.GetBlockByName("B"), 6, 1, 5);
        return(b1);
    }
Beispiel #3
0
    public static Board GetExampleBoard2()
    {
        Board b1 = new Board();

        b1.PlaceBlock(BlockFactory.GetBlockByName("A"), 0, 0, 4);
        b1.PlaceBlock(BlockFactory.GetBlockByName("E"), 0, 1, 6);
        b1.PlaceBlock(BlockFactory.GetBlockByName("J"), 0, 2, 1);
        b1.PlaceBlock(BlockFactory.GetBlockByName("F"), 0, 6, 2);
        b1.PlaceBlock(BlockFactory.GetBlockByName("H"), 0, 7, 2);
        b1.PlaceBlock(BlockFactory.GetBlockByName("G"), 1, 3, 2);
        b1.PlaceBlock(BlockFactory.GetBlockByName("D"), 2, 4, 4);
        b1.PlaceBlock(BlockFactory.GetBlockByName("K"), 2, 5, 0);
        b1.PlaceBlock(BlockFactory.GetBlockByName("C"), 3, 0, 2);
        b1.PlaceBlock(BlockFactory.GetBlockByName("I"), 4, 1, 2);
        b1.PlaceBlock(BlockFactory.GetBlockByName("L"), 5, 1, 0);
        b1.PlaceBlock(BlockFactory.GetBlockByName("B"), 7, 0, 2);
        return(b1);
    }
Beispiel #4
0
        public SubChunk(bool clearBuffers = true)
        {
            _runtimeIds = new List <int> {
                (int)BlockFactory.GetBlockByName("minecraft:air").GetRuntimeId()
            };

            _blocks = ArrayPool <short> .Shared.Rent(4096);

            _loggedBlocks = ArrayPool <byte> .Shared.Rent(4096);

            _blocklight = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048));
            _skylight   = new NibbleArray(ArrayPool <byte> .Shared.Rent(2048));

            if (clearBuffers)
            {
                ClearBuffers();
            }
        }
Beispiel #5
0
    /// <summary>
    /// Place blocks on board so all cells are filled.
    /// </summary>
    /// <returns>a new Board if board is solved, otherwise, return null.</returns>
    public Board Solve()
    {
        List <Block> restBlocks = new List <Block>();

        foreach (string name in BlockFactory.m_blockNames)
        {
            if (!m_blocks.Any(pb => pb.m_block.m_name == name))
            {
                restBlocks.Add(BlockFactory.GetBlockByName(name));
            }
        }
        Board result = DoSolve(this, restBlocks);

        if (m_answersQueue != null)
        {
            m_answersQueue.CompleteAdding();
        }
        return(result);
    }
Beispiel #6
0
        public void TestBlockVarients()
        {
            Block blockA = BlockFactory.GetBlockByName("A");

            Assert.AreEqual(8, blockA.m_varients.Count);
            Block blockG = BlockFactory.GetBlockByName("G");

            Assert.AreEqual(4, blockG.m_varients.Count);
            Block blockI = BlockFactory.GetBlockByName("I");

            Assert.AreEqual(4, blockI.m_varients.Count);
            Block blockJ = BlockFactory.GetBlockByName("J");

            Assert.AreEqual(2, blockJ.m_varients.Count);
            Block blockK = BlockFactory.GetBlockByName("K");

            Assert.AreEqual(1, blockK.m_varients.Count);
            Block blockL = BlockFactory.GetBlockByName("L");

            Assert.AreEqual(1, blockL.m_varients.Count);
        }
Beispiel #7
0
        /// <summary>
        /// If cells in m_highlightPositions forms one block, add block in m_puzzle, and draw the block. Otherwise, do nothing.
        /// </summary>
        /// <returns>PlacedBlock if block is found, null otherwise</returns>
        private PlacedBlock FindAndHighlightBlockMaybe()
        {
            if (m_highlightPositions.Count == 0)
            {
                return(null);
            }
            int minX = m_highlightPositions.Select(pos => pos.x).Min();
            int minY = m_highlightPositions.Select(pos => pos.y).Min();
            int maxX = m_highlightPositions.Select(pos => pos.x).Max();
            int maxY = m_highlightPositions.Select(pos => pos.y).Max();

            if (maxX - minX > 3 || maxY - minY > 3)
            {
                return(null);
            }
            int[,] hlBlockIndex = new int[4, 4];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (m_highlightPositions.Contains(new Position(minX + i, minY + j)))
                    {
                        hlBlockIndex[i, j] = 1;
                    }
                }
            }
            foreach (string name in BlockFactory.m_blockNames)
            {
                Block b = BlockFactory.GetBlockByName(name);
                for (int i = 0; i < b.m_varients.Count; i++)
                {
                    if (BlockFactory.ArrayEquals(b.m_varients[i], hlBlockIndex))
                    {
                        PlacedBlock pb = new PlacedBlock(b, i, minX, minY);
                        return(pb);
                    }
                }
            }
            return(null);
        }
        public void BlcoksWithBlockstates()
        {
            List <string> blocksWithStates = new List <string>();
            BlockPalette  blockPalette     = BlockFactory.BlockPalette;

            foreach (BlockStateContainer stateContainer in blockPalette)
            {
                if (stateContainer.States.Count > 0)
                {
                    if (stateContainer.States.Count(s => s.Name.Contains("direction")) > 0)
                    {
                        blocksWithStates.Add(stateContainer.Name);
                    }
                    if (stateContainer.States.Count(s => s.Name.Contains("face")) > 0)
                    {
                        blocksWithStates.Add(stateContainer.Name);
                    }
                }
            }

            foreach (string name in blocksWithStates.OrderBy(n => n).Distinct())
            {
                Console.WriteLine($"{name}");
                foreach (var state in BlockFactory.GetBlockByName(name).GetState().States)
                {
                    if (state.Name.Contains("direction"))
                    {
                        Console.WriteLine($"\t{state.Name}");
                    }
                    if (state.Name.Contains("face"))
                    {
                        Console.WriteLine($"\t{state.Name}");
                    }
                }
            }
        }
Beispiel #9
0
        public static List <Block> ParseSeed(string inputSeed)
        {
            if (string.IsNullOrEmpty(inputSeed))
            {
                return(new List <Block>());
            }

            var blocks = new List <Block>();

            var components = inputSeed.Split(';');

            var blockPattern = components[1].Split(',');

            foreach (var pattern in blockPattern)
            {
                var countAndBlock = pattern.Replace("minecraft:", "").Split('*');

                var blockAndMeta = countAndBlock[0].Split(':');
                int count        = 1;
                if (countAndBlock.Length > 1)
                {
                    count        = int.Parse(countAndBlock[0]);
                    blockAndMeta = countAndBlock[1].Split(':');
                }

                if (blockAndMeta.Length == 0)
                {
                    continue;
                }

                Block block;

                if (byte.TryParse(blockAndMeta[0], out byte id))
                {
                    block = BlockFactory.GetBlockById(id);
                }
                else
                {
                    block = BlockFactory.GetBlockByName(blockAndMeta[0]);
                }

                if (blockAndMeta.Length > 1 && byte.TryParse(blockAndMeta[1], out byte meta))
                {
                    block.Metadata = meta;
                }

                if (block != null)
                {
                    for (int i = 0; i < count; i++)
                    {
                        blocks.Add(block);
                    }
                }
                else
                {
                    throw new Exception($"Expected block, but didn't fine one for pattern {pattern}, {string.Join("^", blockAndMeta)} ");
                }
            }

            return(blocks);
        }
Beispiel #10
0
        private void ParseSection(SubChunk section, ReadOnlySpan <byte> data)
        {
            var reader = new SpanReader();

            var version = reader.ReadByte(data);

            if (version != 8)
            {
                throw new Exception("Wrong chunk version");
            }

            var storageSize = reader.ReadByte(data);

            for (int storage = 0; storage < storageSize; storage++)
            {
                byte paletteAndFlag = reader.ReadByte(data);
                bool isRuntime      = (paletteAndFlag & 1) != 0;
                if (isRuntime)
                {
                    throw new Exception("Can't use runtime for persistent storage.");
                }
                int bitsPerBlock  = paletteAndFlag >> 1;
                int blocksPerWord = (int)Math.Floor(32d / bitsPerBlock);
                int wordCount     = (int)Math.Ceiling(4096d / blocksPerWord);

                int blockIndex = reader.Position;
                reader.Position += wordCount * 4;

                int paletteSize = reader.ReadInt32(data);

                var palette = new Dictionary <int, (short, byte)>();
                for (int j = 0; j < paletteSize; j++)
                {
                    var file = new NbtFile {
                        BigEndian = false, UseVarInt = false
                    };
                    var buffer = data.Slice(reader.Position).ToArray();

                    int numberOfBytesRead = (int)file.LoadFromStream(new MemoryStream(buffer), NbtCompression.None);
                    reader.Position += numberOfBytesRead;
                    var    tag       = file.RootTag;
                    string blockName = tag["name"].StringValue;
                    Block  block     = BlockFactory.GetBlockByName(blockName);
                    short  blockId   = 0;
                    if (block != null)
                    {
                        blockId = (short)block.Id;
                    }
                    else
                    {
                        Log.Warn($"Missing block={blockName}");
                    }
                    short blockMeta = tag["val"].ShortValue;
                    palette.Add(j, (blockId, (byte)blockMeta));
                }

                int nextStore = reader.Position;
                reader.Position = blockIndex;

                int position = 0;
                for (int wordIdx = 0; wordIdx < wordCount; wordIdx++)
                {
                    uint word = reader.ReadUInt32(data);
                    for (int block = 0; block < blocksPerWord; block++)
                    {
                        if (position >= 4096)
                        {
                            continue;                                           // padding bytes
                        }
                        int state = (int)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));
                        int x     = (position >> 8) & 0xF;
                        int y     = position & 0xF;
                        int z     = (position >> 4) & 0xF;
                        if (state > palette.Count)
                        {
                            Log.Error($"Got wrong state={state} from word. bitsPerBlock={bitsPerBlock}, blocksPerWord={blocksPerWord}, Word={word}");
                        }
                        short bid      = palette[state].Item1;
                        byte  metadata = palette[state].Item2;

                        int runtimeId = (int)BlockFactory.GetRuntimeId(bid, metadata);
                        if (storage == 0)
                        {
                            section.SetBlockByRuntimeId(x, y, z, runtimeId);
                        }
                        else
                        {
                            section.SetLoggedBlockByRuntimeId(x, y, z, runtimeId);
                        }
                        position++;
                    }
                }
                reader.Position = nextStore;
            }
        }
Beispiel #11
0
        private void ParseSection(SubChunk section, ReadOnlyMemory <byte> data)
        {
            var reader = new MemoryStreamReader(data);

            var version = reader.ReadByte();

            if (version != 8)
            {
                throw new Exception("Wrong chunk version");
            }

            var storageSize = reader.ReadByte();

            for (int storage = 0; storage < storageSize; storage++)
            {
                byte paletteAndFlag = (byte)reader.ReadByte();
                bool isRuntime      = (paletteAndFlag & 1) != 0;
                if (isRuntime)
                {
                    throw new Exception("Can't use runtime for persistent storage.");
                }
                int bitsPerBlock  = paletteAndFlag >> 1;
                int blocksPerWord = (int)Math.Floor(32d / bitsPerBlock);
                int wordCount     = (int)Math.Ceiling(4096d / blocksPerWord);

                long blockIndex = reader.Position;
                reader.Position += wordCount * 4;

                int paletteSize = reader.ReadInt32();

                var palette = new Dictionary <int, int>();
                for (int j = 0; j < paletteSize; j++)
                {
                    var file = new NbtFile
                    {
                        BigEndian = false,
                        UseVarInt = false
                    };
                    file.LoadFromStream(reader, NbtCompression.None);
                    var tag = (NbtCompound)file.RootTag;

                    Block block = BlockFactory.GetBlockByName(tag["name"].StringValue);
                    if (block != null && block.GetType() != typeof(Block) && !(block is Air))
                    {
                        List <IBlockState> blockState = ReadBlockState(tag);
                        block.SetState(blockState);
                    }
                    else
                    {
                        block = new Air();
                    }

                    palette.Add(j, block.GetRuntimeId());
                }

                long nextStore = reader.Position;
                reader.Position = blockIndex;

                int position = 0;
                for (int wordIdx = 0; wordIdx < wordCount; wordIdx++)
                {
                    uint word = reader.ReadUInt32();
                    for (int block = 0; block < blocksPerWord; block++)
                    {
                        if (position >= 4096)
                        {
                            continue;                                           // padding bytes
                        }
                        int state = (int)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));
                        int x     = (position >> 8) & 0xF;
                        int y     = position & 0xF;
                        int z     = (position >> 4) & 0xF;
                        if (state > palette.Count)
                        {
                            Log.Error($"Got wrong state={state} from word. bitsPerBlock={bitsPerBlock}, blocksPerWord={blocksPerWord}, Word={word}");
                        }

                        if (storage == 0)
                        {
                            section.SetBlockByRuntimeId(x, y, z, palette[state]);
                        }
                        else
                        {
                            section.SetLoggedBlockByRuntimeId(x, y, z, palette[state]);
                        }
                        position++;
                    }
                }
                reader.Position = nextStore;
            }
        }
Beispiel #12
0
        public static ChunkColumn DecodeChunkColumn(int subChunkCount, byte[] buffer, BlockPalette bedrockPalette = null, HashSet <BlockStateContainer> internalBlockPallet = null)
        {
            //lock (_chunkRead)
            {
                var stream = new MemoryStream(buffer);
                {
                    var defStream = new BinaryReader(stream);

                    if (subChunkCount < 1)
                    {
                        Log.Warn("Nothing to read");
                        return(null);
                    }

                    //if (Log.IsTraceEnabled()) Log.Trace($"Reading {subChunkCount} sections");

                    var chunkColumn = new ChunkColumn(false);

                    for (int chunkIndex = 0; chunkIndex < subChunkCount; chunkIndex++)
                    {
                        int version     = stream.ReadByte();
                        int storageSize = stream.ReadByte();

                        var subChunk = chunkColumn[chunkIndex];

                        for (int storageIndex = 0; storageIndex < storageSize; storageIndex++)
                        {
                            int  flags         = stream.ReadByte();
                            bool isRuntime     = (flags & 1) != 0;
                            int  bitsPerBlock  = flags >> 1;
                            int  blocksPerWord = (int)Math.Floor(32f / bitsPerBlock);
                            int  wordsPerChunk = (int)Math.Ceiling(4096f / blocksPerWord);
                            if (Log.IsTraceEnabled())
                            {
                                Log.Trace($"New section {chunkIndex}, " +
                                          $"version={version}, " +
                                          $"storageSize={storageSize}, " +
                                          $"storageIndex={storageIndex}, " +
                                          $"bitsPerBlock={bitsPerBlock}, " +
                                          $"isRuntime={isRuntime}, " +
                                          $"noBlocksPerWord={blocksPerWord}, " +
                                          $"wordCount={wordsPerChunk}, " +
                                          $"");
                            }

                            long jumpPos = stream.Position;
                            stream.Seek(wordsPerChunk * 4, SeekOrigin.Current);

                            int paletteCount = VarInt.ReadSInt32(stream);
                            var palette      = new int[paletteCount];
                            for (int j = 0; j < paletteCount; j++)
                            {
                                if (!isRuntime)
                                {
                                    var file = new NbtFile
                                    {
                                        BigEndian = false,
                                        UseVarInt = true
                                    };
                                    file.LoadFromStream(stream, NbtCompression.None);
                                    var tag = (NbtCompound)file.RootTag;

                                    Block block = BlockFactory.GetBlockByName(tag["name"].StringValue);
                                    if (block != null && block.GetType() != typeof(Block) && !(block is Air))
                                    {
                                        List <IBlockState> blockState = ReadBlockState(tag);
                                        block.SetState(blockState);
                                    }
                                    else
                                    {
                                        block = new Air();
                                    }

                                    palette[j] = block.GetRuntimeId();
                                }
                                else
                                {
                                    int runtimeId = VarInt.ReadSInt32(stream);
                                    if (bedrockPalette == null || internalBlockPallet == null)
                                    {
                                        continue;
                                    }

                                    palette[j] = GetServerRuntimeId(bedrockPalette, internalBlockPallet, runtimeId);
                                }
                            }

                            long afterPos = stream.Position;
                            stream.Position = jumpPos;
                            int position = 0;
                            for (int w = 0; w < wordsPerChunk; w++)
                            {
                                uint word = defStream.ReadUInt32();
                                for (int block = 0; block < blocksPerWord; block++)
                                {
                                    if (position >= 4096)
                                    {
                                        continue;
                                    }

                                    uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));

                                    int x = (position >> 8) & 0xF;
                                    int y = position & 0xF;
                                    int z = (position >> 4) & 0xF;

                                    int runtimeId = palette[state];

                                    if (storageIndex == 0)
                                    {
                                        subChunk.SetBlockByRuntimeId(x, y, z, (int)runtimeId);
                                    }
                                    else
                                    {
                                        subChunk.SetLoggedBlockByRuntimeId(x, y, z, (int)runtimeId);
                                    }

                                    position++;
                                }
                            }
                            stream.Position = afterPos;
                        }
                    }

                    if (stream.Read(chunkColumn.biomeId, 0, 256) != 256)
                    {
                        return(chunkColumn);
                    }
                    //Log.Debug($"biomeId:\n{Package.HexDump(chunk.biomeId)}");

                    if (stream.Position >= stream.Length - 1)
                    {
                        return(chunkColumn);
                    }

                    int borderBlock = VarInt.ReadSInt32(stream);
                    if (borderBlock != 0)
                    {
                        Log.Warn($"??? Got borderblock with value {borderBlock}.");

                        int len   = (int)(stream.Length - stream.Position);
                        var bytes = new byte[len];
                        stream.Read(bytes, 0, len);
                        Log.Warn($"Data to read for border blocks\n{Packet.HexDump(new ReadOnlyMemory<byte>(bytes))}");

                        //byte[] buf = new byte[borderBlock];
                        //int len = stream.Read(buf, 0, borderBlock);
                        //Log.Warn($"??? Got borderblock {borderBlock}. Read {len} bytes");
                        //Log.Debug($"{Packet.HexDump(buf)}");
                        //for (int i = 0; i < borderBlock; i++)
                        //{
                        //	int x = (buf[i] & 0xf0) >> 4;
                        //	int z = buf[i] & 0x0f;
                        //	Log.Debug($"x={x}, z={z}");
                        //}
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        while (stream.Position < stream.Length)
                        {
                            NbtFile file = new NbtFile()
                            {
                                BigEndian = false,
                                UseVarInt = true
                            };

                            file.LoadFromStream(stream, NbtCompression.None);
                            var blockEntityTag = file.RootTag;
                            if (blockEntityTag.Name != "alex")
                            {
                                int x = blockEntityTag["x"].IntValue;
                                int y = blockEntityTag["y"].IntValue;
                                int z = blockEntityTag["z"].IntValue;

                                chunkColumn.SetBlockEntity(new BlockCoordinates(x, y, z), (NbtCompound)file.RootTag);

                                if (Log.IsTraceEnabled())
                                {
                                    Log.Trace($"Blockentity:\n{file.RootTag}");
                                }
                            }
                        }
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        int len   = (int)(stream.Length - stream.Position);
                        var bytes = new byte[len];
                        stream.Read(bytes, 0, len);
                        Log.Warn($"Still have data to read\n{Packet.HexDump(new ReadOnlyMemory<byte>(bytes))}");
                    }

                    return(chunkColumn);
                }
            }
        }