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); }
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); }
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); }
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(); } }
/// <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); }
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); }
/// <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}"); } } } }
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); }
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; } }
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; } }
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); } } }