protected List <BlockType> _blockTypeQueue; // Queue is one way /// <summary> /// Setups the randomizer /// </summary> protected void SetupBlockGenerator(Boolean level_reset = false) { // Create empty Queue if (level_reset) { _blockTypeQueue.Clear(); } else { _blockTypeQueue = new List <BlockType>(); } GenerateNextPermutation(); // First block of first bag is always I J L or T var firstAllowed = new BlockType[] { BlockType.IBlock, BlockType.JBlock, BlockType.LBlock, BlockType.TBlock }; while (!firstAllowed.Contains(_blockTypeQueue.First())) { _blockTypeQueue.Push(_blockTypeQueue.UnShift <BlockType>()); } // Generate as a block if (level_reset) { this.CurrentBlock.Block.SetBlockType(_blockTypeQueue.UnShift <BlockType>()); } else { this.CurrentBlock = new FallingBlock(this.Game, new Block(_blockTypeQueue.UnShift <BlockType>()), this); } this.CurrentBlock.Replace( (this.Width - this.CurrentBlock.Block.Width) / 2 + Block.GetBaseXPosition(this.CurrentBlock.Block.Type), this.CurrentBlock.Field.Height - 1, Block.GetStartRotation(this.CurrentBlock.Block.Type) ); // Set next block if (level_reset) { this.NextBlock.SetBlockType(_blockTypeQueue.UnShift <BlockType>()); } else { this.NextBlock = new Block(_blockTypeQueue.UnShift <BlockType>()); } this.NextBlock.Rotation = Block.GetStartRotation(this.NextBlock.Type); }
/// <summary> /// Generates the next block /// </summary> protected void GenerateNextBlock() { var oldType = this.CurrentBlock.Block.Type; var oldX = this.CurrentBlock.X; var oldY = this.CurrentBlock.Y; var oldR = this.CurrentBlock.Block.Rotation; var oldPoints = this.CurrentBlock.BlockPoints; var newType = this.NextBlock.Type; var newR = Block.GetStartRotation(newType); var nextType = _blockTypeQueue.UnShift <BlockType>(); var newY = this.CurrentBlock.Field.Height - 1; var newX = (this.Width - this.NextBlock.Width) / 2 + Block.GetBaseXPosition(newType); this.Timeline.Add(new Event() { Apply = () => { // Sets currentblock this.CurrentBlock.Block.SetBlockType(newType); this.CurrentBlock.Replace(newX, newY, newR); // Sets the next block this.NextBlock.SetBlockType(nextType); this.NextBlock.Rotation = Block.GetStartRotation(nextType); if (_blockTypeQueue.Count == 0) { GenerateNextPermutation(); } }, Undo = () => { // Restore next type _blockTypeQueue.Shift(nextType); // Retore new block this.NextBlock.SetBlockType(newType); this.NextBlock.Rotation = Block.GetStartRotation(newType); // Restore current block this.CurrentBlock.Block.SetBlockType(oldType); this.CurrentBlock.Replace(oldX, oldY, oldR); this.CurrentBlock.BlockPoints = oldPoints; }, }); }
/// <summary> /// Switches holding block with current /// </summary> public Boolean SwitchHoldingBlock() { if (_holdLocked) { return(false); } _holdLocked = true; // Always drop hold blocks from the top var baseY = this.CurrentBlock.Field.Height - 1; var oldType = this.CurrentBlock.Block.Type; var oldR = this.CurrentBlock.Block.Rotation; var oldPoints = this.CurrentBlock.BlockPoints; var oldX = (this.Width - this.CurrentBlock.Block.Width) / 2 + Block.GetBaseXPosition(oldType); // If this is the first too hold if (this.HoldBlock == null) { // We can't replace the current block, so we generate a new one GenerateNextBlock(); this.Timeline.Add(new Event() { Apply = () => { this.HoldBlock = new Block(oldType); }, Undo = () => { this.HoldBlock = null; this.CurrentBlock.Replace(oldX, baseY, oldR); }, }); return(true); } // Time to switch a block var newType = this.HoldBlock.Type; var newR = Block.GetStartRotation(newType); var newX = (this.Width - Block.BlockTypes[newType].GetLength(0)) / 2 + Block.GetBaseXPosition(newType); // Switch the hold block with the current block this.Timeline.Add(new Event() { Apply = () => { this.HoldBlock.SetBlockType(oldType); this.CurrentBlock.Block.SetBlockType(newType); this.CurrentBlock.Replace(newX, baseY, newR); }, Undo = () => { this.HoldBlock.SetBlockType(newType); this.CurrentBlock.Block.SetBlockType(oldType); this.CurrentBlock.Replace(oldX, baseY, oldR); }, }); return(true); }