Beispiel #1
0
        /// <summary>
        /// Grabs a block from the currently selected stack.
        /// </summary>
        /// <param name="stack"></param>
        private void Grab()
        {
            // We only care if we can grab something
            if (currentStack == null || !CanGrab())
            {
                return;
            }

            // Move everything up in the stack.
            Block topBlock = currentStack.TopBlock;

            for (int i = Constants.MaximumGrabCount - 1; i > 0; i--)
            {
                grabStack[i] = grabStack[i - 1];
            }

            // Grab the top block and change its position
            grabStack[0]      = topBlock;
            topBlock.IsMoving = false;
            topBlock.Vector   = 0;
            topBlock.Mass     = 0;

            // Remove the stack for processing
            currentStack.Remove(topBlock);

            // Fire the sound event
            BlockStackEventArgs args = new BlockStackEventArgs();

            args.Stack = currentStack;
            args.Block = topBlock;
            Game.Sound.BlockGrabbed(this, args);

            // Save the last grab stack
            lastGrabStack = currentStack;
        }
Beispiel #2
0
 private void CompileBlockStack(BlockStack b, List <Instruction> instructions, Dictionary <string, int> labels)
 {
     foreach (IBlock s in b)
     {
         CompileExpression(s, DataType.Script, instructions, labels);
     }
 }
Beispiel #3
0
 private void CompileBlockStack(BlockStack b, List<Instruction> instructions, Dictionary<string, int> labels)
 {
     foreach (IBlock s in b)
     {
         CompileExpression(s, DataType.Script, instructions, labels);
     }
 }
        private void OnBlockMovingChanged(
            object sender, BlockStackEventArgs args)
        {
            // Figure out the point
            Block      b  = args.Block;
            BlockStack bs = args.Stack;
            PointF     p1 =
                blockViewport.ToPoint(bs.X, bs.Y, b.Height);
            PointF p = new PointF(
                p1.X + blockViewport.Point.X + 31 + Viewport.Point.X,
                p1.Y + blockViewport.Point.Y + 90 + Viewport.Point.Y);

            // Swarm the stars and hearts
            Game.PlayMode
            .SwarmStars(Constants.StarsPerPrayerBlock, p);
            Game.PlayMode
            .SwarmHearts(Constants.HeartsPerPrayerBlock, p);

            // Mark the block as unmovable
            b.Data = false;

            // Add the chance of a chest
            int random = Entropy.Next(Constants.ChestChance);

            chestChance++;

            if (random <= chestChance)
            {
                chestChance = 0;
                ChestCounter++;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Migrates the current board to the other one, dropping
        /// everything on top.
        /// </summary>
        /// <param name="board"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void MigrateBoard(Board board, int x, int y)
        {
            // Go through the columns
            for (int i = 0; i < Columns; i++)
            {
                // Get the data for speed
                IList <BlockStack> stacks  = Game.State.Board[x + i];
                IList <BlockStack> stacks0 = this[i];

                // Go through the rows
                for (int j = 0; j < Rows; j++)
                {
                    // Get the stacks
                    BlockStack stack  = stacks[y + j];
                    BlockStack stack0 = stacks0[j];

                    // Get the position
                    Block bBlock   = stack.TopBlock;
                    float position = stack.TopPosition;

                    // Move everything but the bottom-most one
                    foreach (Block block in stack0)
                    {
                        // Seal it to change how it looks on the
                        // mini map
                        switch (block.Sprite.ID)
                        {
                        case "Water Block":
                            bBlock.Sprite = AssetLoader.Instance
                                            .CreateSprite("Sealed Water Block");
                            bBlock.Data = false;
                            break;

                        case "Grass Block":
                            bBlock.Sprite = AssetLoader.Instance
                                            .CreateSprite("Sealed Grass Block");
                            bBlock.Data = false;
                            break;

                        case "Dirt Block":
                            bBlock.Sprite = AssetLoader.Instance
                                            .CreateSprite("Sealed Dirt Block");
                            bBlock.Data = false;
                            break;
                        }

                        // Positions 0's are sealed
                        if (block.BottomPosition != 0)
                        {
                            // Move it over to the new one and add the position
                            // to the bottom, minus one because we ignore the
                            // bottom row
                            block.BottomPosition += position - 1f;
                            stack.Add(new Block(block));
                        }
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// This creates a new stage for the game, using the
        /// properties of the state to determine how the board is
        /// generated.
        /// </summary>
        public void GenerateStage()
        {
            // See if we already have a gate column (i.e. if we have
            // any columns, then we do).
            int newColumns = Constants.StageWidth;

            // Extend the board by the number of columns
            int oldColumns = Columns;

            Columns = Columns + newColumns;

            // Populate the base level board
            for (int i = 0; i < newColumns; i++)
            {
                // Get the column
                IList <BlockStack> stacks = this[oldColumns + i];

                // Go through the rows
                for (int j = 0; j < Constants.BoardRows; j++)
                {
                    // Get the stack
                    BlockStack stack = stacks[j];
                    stack.IsInInitialPlacement = true;

                    // Set a new immobile block into place
                    Block block = AssetLoader.Instance
                                  .CreateBlock(Constants.ImmobileBlockName);
                    block.BottomPosition = 0;
                    block.Height         = 1;

                    // Add it to the stack
                    stack.Add(block);
                }
            }

            // Populate the additional immobile boards
            AddBlocks(Game.State.ImmobileCount, Constants.ImmobileBlockName);

            // Add the grass, dirt, and water blocks
            AddBlocks();

            // Add the character prayer, but not on the far-right side
            Prayer prayer = new Prayer();
            int    px     = Entropy.Next(0, Constants.StageWidth - 1);
            int    py     = Entropy.Next(0, Constants.BoardRows);

            prayer.X = px + oldColumns;
            prayer.Y = py;
            Game.State.Prayers.Add(prayer);

            BlockStack ps = Game.State.Board[oldColumns + px, py];

            prayer.BottomPosition = ps.TopPosition;
            prayer.Vector         = Constants.DroppedVector;
            ps.Add(prayer);
        }
Beispiel #7
0
 public void init()
 {
     state = action.start;
     if (currentBlock == null)
     {
         currentBlock = IceHopping.S.getStart();
     }
     transform.position = new Vector3(currentBlock.transform.localPosition.x, currentBlock.transform.position.y + currentBlock.blocks.Count - (1 - Block.heightOffset), currentBlock.transform.localPosition.z);
     GetComponent <Rigidbody>().isKinematic = true;
 }
Beispiel #8
0
    public void drawSelectedBlock()
    {
        int blockSelectKey = getBlockSelectButton();

        if (blockSelectKey > 0 && blockSelectMenu.selectedBlockStacks[blockSelectKey-1] != null)
            selectedBlockStack = (BlockStack)blockSelectMenu.selectedBlockStacks[blockSelectKey - 1];

        if (selectedBlockStack != null)
            GuiFunctions.drawSlotTexture(selectedBlockStack.blockTexture, selectedBlockPosition.x,
                selectedBlockPosition.y, selectedBlockScale);
    }
Beispiel #9
0
    public void loadLevel(int n)
    {
        blockAnchor          = new GameObject("BlockAnchor").transform;
        blockAnchor.position = new Vector3(0, -15, 0);

        Level level = LevelInfo.S.getLevel(n);

        blockGrid = new BlockStack[level.size, level.size];
        for (int i = 0; i < level.size; i++)
        {
            for (int j = 0; j < level.size; j++)
            {
                if (level.field[i, j] > 0)
                {
                    //create stack object and set parent
                    GameObject go = Instantiate <GameObject>(blockStackPrefab);
                    go.transform.parent = blockAnchor;
                    BlockStack bs = go.GetComponent <BlockStack>();
                    bs.transform.localPosition = new Vector3(i * 1.25f, 0, j * 1.25f);

                    //check if start or end before adding blocks
                    if (i == level.start.x && Mathf.Sqrt(level.field.Length) - 1 - j == level.start.y)
                    {
                        bs.isStart = true;
                    }
                    if (i == level.end.x && Mathf.Sqrt(level.field.Length) - 1 - j == level.end.y)
                    {
                        bs.isEnd = true;
                    }
                    //create ice blocks
                    bs.createBlocks(level.field[i, j]);

                    //save
                    blockStacks.Add(bs);
                    blockGrid[i, j] = bs;
                }
            }
        }

        //printGrid();

        SetNeighbors();

        Camera.main.transform.position = new Vector3(level.start.x + 2, 8, -6);

        GameObject pGO = Instantiate <GameObject>(playerPrefab);

        player = pGO.GetComponent <Player>();
        player.transform.parent = blockAnchor;
        player.init();

        load     = true;
        loadLife = Time.time;
    }
Beispiel #10
0
        public BlockStackView(BlockStack model, IEnumerable<IBlockView> elements)
        {
            this.model = model;
            this.model.OnSplit += new BlockStackSplitEvent(model_OnSplit);
            this.elements.AddRange(elements);

            Changed += delegate(object sender) { };
            foreach (IBlockView v in this.elements)
            {
                Attach(v);
            }
            Reassemble();
        }
 // Use this for initialization
 void Start()
 {
     if (BodyStack == null)
     {
         BodyStack = new BlockStack();
     }
     try
     {
         animator = GetComponentsInChildren <Animator>()[0];
     }
     catch {
     }
 }
Beispiel #12
0
    public void drawSelectedBlock()
    {
        int blockSelectKey = getBlockSelectButton();

        if (blockSelectKey > 0 && blockSelectMenu.selectedBlockStacks[blockSelectKey - 1] != null)
        {
            selectedBlockStack = (BlockStack)blockSelectMenu.selectedBlockStacks[blockSelectKey - 1];
        }

        if (selectedBlockStack != null)
        {
            GuiFunctions.drawSlotTexture(selectedBlockStack.blockTexture, selectedBlockPosition.x,
                                         selectedBlockPosition.y, selectedBlockScale);
        }
    }
Beispiel #13
0
        /// <summary>
        /// Triggered when the mouse enters a specific stack
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnStackMouseEnter(object sender, BlockStackEventArgs args)
        {
            // Ignore if we have a minor mode
            if (minorMode != null)
            {
                return;
            }

            // Add the selector to the current position and set it on top
            currentStack = args.Stack;

            // Remove the stack, just in case
            bool isValidTarget = IsValidTarget();

            // See if we have a valid target
            if (!isValidTarget)
            {
                // Change the selector so it shows an incorrect selection
                selector.Sprite = AssetLoader.Instance
                                  .CreateSprite(Constants.InvalidSelectorName);
                vertViewport.Visible = false;

                // We are done
                return;
            }

            // Change the selector to show a valid selector.
            selector.Sprite = AssetLoader.Instance
                              .CreateSprite(Constants.SelectorName);

            // Move the vertical stack display to the currently
            // selected stack and make it visible
            PointF vertPoint = blockViewport.ToPoint(
                currentStack.X, currentStack.Y,
                currentStack.TopPosition);

            vertViewport.Visible     = true;
            vertViewport.BlockStackX = currentStack.X;
            vertViewport.BlockStackY = currentStack.Y;
            vertViewport.Point       = new PointF(
                vertPoint.X
                + blockViewport.BlockWidth / 2
                - vertViewport.Size.Width / 2,
                vertPoint.Y);

            // We are going to be grabbing or dropping
            Game.GuiManager.MouseUpListeners.Add(this);
        }
Beispiel #14
0
        /// <summary>
        /// Would be the same as BlockStack.Peek() but only returns the topmost block of given type
        /// </summary>
        /// <returns></returns>
        public T GetTopMostBlock <T>() where T : ParsedScope
        {
            T   output = BlockStack.Peek() as T;
            var i      = 0;

            while (output == null)
            {
                i++;
                if (i >= BlockStack.Count)
                {
                    break;
                }
                output = BlockStack.ElementAt(i) as T;
            }
            return(output);
        }
        // Start is called before the first frame update
        private void OnEnable()
        {
            //Find our properities.
            blocks = serializedObject.FindProperty("Name");
            // dataRef = serializedObject.FindProperty("data");

            ////Cast the target object into my instance?
            myInstance = (BlockStack)target;

            blockdata = myInstance.data;

            ////Go through the instance and grab the childrne?
            allTheBoxes = myInstance.GetComponentsInChildren <Rigidbody>();

            allTheBlocks = myInstance.GetComponentsInChildren <Block>();
        }
Beispiel #16
0
        public Method DefineMethod(ProcDefBlock b, BlockStack stack)
        {
            // 'stack' is a BlockStack whose first element (#0) is a ProcDefBlock, the same as 'b'

            Method ret = new Method();
            List<Instruction> instructions = new List<Instruction>();
            string[] argNames = b.GetArgNames();
            for (int i = 0; i < argNames.Length; ++i)
            {
                instructions.Add(new PopLocal(vm, argNames[i]));
            }
            for(int i=1; i<stack.Count; ++i)
                instructions.AddRange(CompileBlockToInstructions(stack[i], false));
            instructions.Add(new Push(vm, null));
            instructions.Add(new Ret(vm));
            ret.Instructions = instructions.ToArray();
            ret.Arity = argNames.Length;
            ret.PrepareLabels();
            return ret;
        }
Beispiel #17
0
        /// <summary>
        /// Triggered when a mouse leaves a stack.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnStackMouseExit(object sender, BlockStackEventArgs args)
        {
            // Ignore if we have a minor mode
            if (minorMode != null)
            {
                return;
            }

            // If we don't have a current stack, don't bother
            if (currentStack == null)
            {
                return;
            }

            // Remove the selectors
            // We use RemoveAll() because of a duplication bug
            currentStack         = null;
            vertViewport.Visible = false;

            // Since we won't be listening to down, remove it
            Game.GuiManager.MouseUpListeners.Remove(this);
        }
Beispiel #18
0
        /// <summary>
        /// Drops the bottom-most grab stack (index 0) from the stack
        /// onto the currently selected stack.
        /// </summary>
        /// <param name="stack"></param>
        private void Drop()
        {
            // Don't bother if we can't drop
            if (currentStack == null || !CanDrop())
            {
                return;
            }

            // Grab the block we are dropping
            Block block = grabStack[0];

            // Move the rest of the stack down
            for (int i = 0; i < Constants.MaximumGrabCount - 1; i++)
            {
                grabStack[i] = grabStack[i + 1];
            }

            grabStack[Constants.MaximumGrabCount - 1] = null;

            // Set down the vector
            block.BottomPosition -= 1f;
            block.Vector          = Constants.DroppedVector;

            // Put that block back into the stack
            droppingBlocks.Add(block);
            currentStack.Add(block);

            // Mark this as the end of the turn
            if (currentStack != lastGrabStack)
            {
                // Subtract a heart and score it
                Game.State.Hearts -= Game.State.GrabCost;
                Game.State.EndTurn();
            }

            // Reset the grab stack for "undo"
            lastGrabStack = null;
        }
Beispiel #19
0
        public Method DefineMethod(ProcDefBlock b, BlockStack stack)
        {
            // 'stack' is a BlockStack whose first element (#0) is a ProcDefBlock, the same as 'b'

            Method             ret          = new Method();
            List <Instruction> instructions = new List <Instruction>();

            string[] argNames = b.GetArgNames();
            for (int i = 0; i < argNames.Length; ++i)
            {
                instructions.Add(new PopLocal(vm, argNames[i]));
            }
            for (int i = 1; i < stack.Count; ++i)
            {
                instructions.AddRange(CompileBlockToInstructions(stack[i], false));
            }
            instructions.Add(new Push(vm, null));
            instructions.Add(new Ret(vm));
            ret.Instructions = instructions.ToArray();
            ret.Arity        = argNames.Length;
            ret.PrepareLabels();
            return(ret);
        }
Beispiel #20
0
        /// <summary>
        /// Internal function to determine if the target is valid or
        /// not.
        /// </summary>
        private bool IsInvalidTarget(BlockStack srcStack, BlockStack destStack)
        {
            // Remove ourselves to take ourselves out of the calculation
            srcStack.Remove(this);

            try
            {
                // Make sure the destination is a ground block or an
                // immobile one, but nothing else
                Block dest = destStack.TopBlock;

                if (!Board.IsGroundBlock(dest) &&
                    !Board.IsImmobileBlock(dest))
                {
                    // Neither ground or immobile
                    return(true);
                }

                // We need the distance to be 1 or less
                float dist =
                    Math.Abs(srcStack.TopPosition - destStack.TopPosition);

                if (dist > 1)
                {
                    // Too much to jump
                    return(true);
                }

                // It is good
                return(false);
            }
            finally
            {
                // Put ourselves back
                srcStack.Add(this);
            }
        }
Beispiel #21
0
        /// <summary>
        /// Adds a number of blocks of the give name to the board. This
        /// only places blocks in the last Constants.StateWidth rows.
        /// </summary>
        /// <param name="count"></param>
        /// <param name="name"></param>
        private void AddBlocks(int count, string name)
        {
            // Loop through the blocks
            for (int i = 0; i < count; i++)
            {
                // Create a new block
                Block block = CreateBlock(name);

                // Since we have a maximum count here, we loop until we
                // find a valid stack to drop it on
                while (true)
                {
                    // Figure out a random position
                    int col = Entropy.Next(0, Constants.StageWidth)
                              + Columns - Constants.StageWidth;
                    int        row   = Entropy.Next(0, Constants.BoardRows);
                    BlockStack stack = this[col, row];

                    // Make sure the stack doesn't have too many items
                    if (stack.Count >= Constants.MaximumPlacementCount)
                    {
                        continue;
                    }

                    // Set the position based on the count
                    block.BottomPosition =
                        2f + (float)stack.Count * Constants.PlacementSpacing;
                    block.Vector   = Constants.DroppedVector;
                    block.IsMoving = true;
                    stack.Add(block);

                    // Break out of the loop
                    break;
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Internal function to populate the board with random
        /// blocks.
        /// </summary>
        private void PopulateBoard()
        {
            for (int x = 0; x < BoardColumns; x++)
            {
                for (int y = 0; y < BoardRows; y++)
                {
                    // Get the stack
                    BlockStack stack = board[x, y];

                    // Add 1-4 blocks
                    int total = Entropy.Next(4) + 1;

                    for (int i = 0; i < total; i++)
                    {
                        Block block = new Block(RandomBlock());
                        block.BottomPosition = i;
                        block.CastsShadows   = true;
                        block.Height         = 1;
                        block.Mass           = Constants.BlockMass;
                        stack.Add(block);
                    }
                }
            }
        }
Beispiel #23
0
 public IBlockView ViewFromBlockStack(BlockStack blocks)
 {
     IEnumerable<IBlockView> stack = blocks.Select(b => ViewFromBlock(b));
     BlockStackView ret = new BlockStackView(blocks, stack);
     blocks.OnInsert += new BlockStackInsertEvent(blockstack_OnInsert);
     return ret;
 }
Beispiel #24
0
 BlockStack MergeStacks(IBlock b1, IBlock b2)
 {
     BlockStack ret = new BlockStack();
     if ((b1 is BlockStack))
     {
         BlockStack bs1 = b1 as BlockStack;
         ret.AddRange(bs1);
     }
     else
     {
         // We need to remove b1 from its parent before adding it to the newly merged stack
         // otherwise consider such a scenario:
         // 1- We drag a stack block into an existing stackBlock in a C block
         // 2- 'b1' is the existing stackBlock, it is not added to ret, but is still an arg of the C block
         // 3- after merge is called, we'll try to set ret as the arg of the C block; the C will try
         // to remove the old arg (b1)...but it doesn't have C as a parent! exception thrown
         b1.ParentRelationship.Detach(this);
         ret.Add(b1);
     }
     if ((b2 is BlockStack))
     {
         BlockStack bs2 = b2 as BlockStack;
         ret.AddRange(bs2);
     }
     else
     {
         b2.ParentRelationship.Detach(this);
         ret.Add(b2);
     }
     return ret;
 }
Beispiel #25
0
    public MenuActions draw()
    {
        MenuActions menuAction = MenuActions.none;
        GUI.DrawTexture(backgroundRect, background, ScaleMode.ScaleAndCrop, false, 0);

        GUILayout.BeginArea(backgroundRect);
        GUILayout.BeginVertical();
        GUILayout.Label("Assign blocks to keys 1-9", normalStyle);

        float slotScale = slotWidth / 16;
        ArrayList blockStacks = getBlockStacksForSlots();
        {
            GUILayout.BeginHorizontal();
            if (GUILayout.Button(ResourceLookup.getSideButtonTexture(0), slotGuiOptions))
                scrollLeft();

            if (blockStacks.Count == slotPositions)
                GUILayout.FlexibleSpace();

            BlockStack blockStack;
            for (int i = 0; i < blockStacks.Count; i++)
            {
                GUILayout.Box("", slotGuiOptions);
                if (blockStacks[i] == null)
                    break;
                blockStack = (BlockStack)blockStacks[i];
                Rect rect = GUILayoutUtility.GetLastRect();
                GuiFunctions.drawSlotTexture(blockStack.blockTexture, rect.xMin, rect.yMin, slotScale);

                if (Input.GetMouseButtonDown(0) && GuiFunctions.isMouseInGuiRect(rect))
                    mouseDownBlockStack = blockStack;

            }

            GUILayout.FlexibleSpace();

            if (GUILayout.Button(ResourceLookup.getSideButtonTexture(1), slotGuiOptions))
                scrollRight();
            GUILayout.EndHorizontal();
        }

        {
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            for (int i = 0; i < slotPositions; i++)
            {
                GUILayout.Box((i + 1).ToString(), slotGuiOptions);
                Rect rect = GUILayoutUtility.GetLastRect();
                if (selectedBlockStacks[i] != null)
                {
                    BlockStack blockStack = (BlockStack)selectedBlockStacks[i];
                    GuiFunctions.drawSlotTexture(blockStack.blockTexture, rect.xMin, rect.yMin, slotScale);
                }
                if (Input.GetMouseButtonUp(0) && mouseDownBlockStack != null && GuiFunctions.isMouseInGuiRect(rect))
                {
                    selectedBlockStacks[i] = mouseDownBlockStack;
                    mouseDownBlockStack = null;
                }
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
        }

        GUILayout.FlexibleSpace();
        GUILayout.EndVertical();
        GUILayout.EndArea();

        if (mouseDownBlockStack != null)
        {
            GuiFunctions.drawSlotTexture(mouseDownBlockStack.blockTexture, Input.mousePosition.x - slotWidth / 2, Screen.height - Input.mousePosition.y - slotHeight / 2, slotScale);
            if (!Input.GetMouseButton(0) && Event.current.type == EventType.repaint)
                mouseDownBlockStack = null;
        }

        return menuAction;
    }
Beispiel #26
0
        /// <summary>
        /// Random grabs or drops a block on the board.
        /// </summary>
        private void ChangeBoard(UpdateArgs args)
        {
            // Loop through the blocks to see if they are too high. If
            // they are, remove them.
            LinkedList <Block> tmpBlocks = new LinkedList <Block>();

            tmpBlocks.AddAll(blocks);

            foreach (Block b in tmpBlocks)
            {
                if (b.BottomPosition > 10)
                {
                    stacks[b].Remove(b);
                    blocks.Remove(b);
                    stacks.Remove(b);
                }
            }

            // Decrement the counter for the timeout
            secondsUntilChange -= args.SecondsSinceLastUpdate;

            if (secondsUntilChange > 0)
            {
                // We aren't changing anything
                return;
            }

            // Reset it
            secondsUntilChange = Entropy.NextDouble() * 2;

            // Pick a random coordinate
            int        x     = Entropy.Next(0, BoardColumns);
            int        y     = Entropy.Next(0, BoardRows);
            BlockStack stack = board[x, y];

            // Make sure we aren't already doing something here
            foreach (Block b in blocks)
            {
                if (stacks[b] == stack)
                {
                    // Don't bother this time
                    return;
                }
            }

            // We have a stack, decide if we are going to drop or grab
            // something from the stack.
            bool drop = Entropy.Next(0, 2) == 0;

            if (stack.Count > 5)
            {
                // Don't go over 5 high
                drop = false;
            }

            if (stack.Count == 1)
            {
                // Don't go below 1 high
                drop = true;
            }

            // Figure out what to do
            if (drop)
            {
                // Create a new block
                Block nb = new Block(RandomBlock());
                nb.BottomPosition = 10;
                nb.Vector         = Constants.DroppedVector;
                nb.Mass           = Constants.BlockMass;
                nb.IsMoving       = true;
                nb.CastsShadows   = true;
                nb.Height         = 1;
                stack.Add(nb);
            }
            else
            {
                // Grab the top block
                Block tb = stack.TopBlock;
                tb.Vector   = -Constants.DroppedVector;
                tb.Mass     = 0;
                tb.IsMoving = true;
            }
        }
Beispiel #27
0
        /// <summary>
        /// Triggered when a mouse leaves a stack.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnStackMouseExit(object sender, BlockStackEventArgs args)
        {
            // Ignore if we have a minor mode
            if (minorMode != null)
                return;

            // If we don't have a current stack, don't bother
            if (currentStack == null)
                return;

            // Remove the selectors
            // We use RemoveAll() because of a duplication bug
            currentStack = null;
            vertViewport.Visible = false;

            // Since we won't be listening to down, remove it
            Game.GuiManager.MouseUpListeners.Remove(this);
        }
Beispiel #28
0
 public TopLevelScript SplitBlockStack(BlockStack block, int nKeep, Point newStacklocation)
 {
     IBlock newStack = block.Split(nKeep);
     return AddTopLevel(newStack, newStacklocation);
 }
Beispiel #29
0
        /// <summary>
        /// This function causes the prayer to jump and potentially
        /// move around the board.
        /// </summary>
        public void Jump()
        {
            // Reset the time
            timeUntilBounce = Entropy.NextDouble(
                Constants.MinimumCharacterBounce,
                Constants.MaximumCharacterBounce);

            // We want the characters to bounce around a bit, so
            // we randomly pick a direction to jump into. We get a
            // random number between 0 and 4:
            //   0 no change
            //   1 north
            //   2 east
            //   3 south
            //   4 west
            // Actually, 0 happens because of fallback
            direction = Entropy.Next(4) + 1;

            // East/West only
            // TODO Fix
            if (direction == 1 || direction == 3)
            {
                direction++;
            }

            // If we haven't been accepted, we don't move around
            if (!IsAccepted)
            {
                direction = 0;
            }

            // Do sanity checking on the bounds of the stage. If
            // we are on the end and we would have jumped off, set
            // the direction to "none"
            Board board = Game.State.Board;

            if (direction == 1 && Y == 0)
            {
                direction = 0;
            }
            else if (direction == 2 && X == board.Columns - 1)
            {
                direction = 0;
            }
            else if (direction == 3 && Y == board.Rows - 1)
            {
                direction = 0;
            }
            else if (direction == 4 && X == 0)
            {
                direction = 0;
            }

            // If we still non-zero, then get the appropriate
            // stacks
            BlockStack myStack   = board[X, Y];
            BlockStack destStack = myStack;

            if (direction > 0)
            {
                // Get the proper stack and make sure it is a
                // valid target
                if (direction == 1)
                {
                    destStack = board[X, Y - 1];
                }
                else if (direction == 2)
                {
                    destStack = board[X + 1, Y];
                }
                else if (direction == 3)
                {
                    destStack = board[X, Y + 1];
                }
                else if (direction == 4)
                {
                    destStack = board[X - 1, Y];
                }

                // We don't jump if the destination block isn't a
                // ground or immobile block. We also don't jump if
                // the difference in height is more than one.
                if (IsInvalidTarget(myStack, destStack))
                {
                    direction = 0;
                    destStack = myStack;
                }
            }

            // Figure out the vector, we need a higher one if we
            // are jumping north and/or if the destination block
            // is higher.
            myStack.Remove(this);
            float myTop   = myStack.TopPosition;
            float destTop = destStack.TopPosition;
            float vector  = Constants.PrayerBounceVector;

            myStack.Add(this);

            if (direction == 1)
            {
                vector += Constants.PrayerBounceNorthVector;
            }

            if (destTop > myTop)
            {
                vector += Constants.PrayerBounceUpVector;
            }

            // Add a positive vector
            Vector += vector;
        }
Beispiel #30
0
 bool IsEmptyBlockStack(BlockStack blockStack)
 {
     return(blockStack == null || (blockStack.Block == BlockValue.Air && blockStack.count == 0));
 }
Beispiel #31
0
        /// <summary>
        /// Internal function to determine if the target is valid or
        /// not.
        /// </summary>
        private bool IsInvalidTarget(BlockStack srcStack, BlockStack destStack)
        {
            // Remove ourselves to take ourselves out of the calculation
            srcStack.Remove(this);

            try
            {
                // Make sure the destination is a ground block or an
                // immobile one, but nothing else
                Block dest = destStack.TopBlock;

                if (!Board.IsGroundBlock(dest) &&
                    !Board.IsImmobileBlock(dest))
                {
                    // Neither ground or immobile
                    return true;
                }

                // We need the distance to be 1 or less
                float dist =
                    Math.Abs(srcStack.TopPosition - destStack.TopPosition);

                if (dist > 1)
                {
                    // Too much to jump
                    return true;
                }

                // It is good
                return false;
            }
            finally
            {

                // Put ourselves back
                srcStack.Add(this);
            }
        }
Beispiel #32
0
        /// <summary>
        /// Based on algorithm MinSFA from POPL14.
        /// </summary>
        void ComputeSplitHistory()
        {
            var fa = autom;

            if (!fa.isDeterministic)
            {
                throw new AutomataException(AutomataExceptionKind.AutomatonIsNondeterministic);
            }

            this.initialFinalBlock             = new Block(fa.GetFinalStates());
            this.initialNonfinalBlock          = new Block(fa.GetNonFinalStates());
            this.initialFinalNode              = new SplitNode();
            this.initialNonfinalNode           = new SplitNode();
            splithistory[initialFinalBlock]    = this.initialFinalNode;
            splithistory[initialNonfinalBlock] = this.initialNonfinalNode;

            foreach (var q in fa.GetFinalStates())
            {
                Blocks[q] = initialFinalBlock;
            }
            foreach (var q in fa.GetNonFinalStates())
            {
                Blocks[q] = initialNonfinalBlock;
            }

            var W  = new BlockStack();
            var W1 = new BlockStack();

            if (initialNonfinalBlock.Count < initialFinalBlock.Count)
            {
                W1.Push(initialNonfinalBlock);
            }
            else
            {
                W1.Push(initialFinalBlock);
            }

            Func <T, T, T> MkDiff = (x, y) => solver.MkAnd(x, solver.MkNot(y));

            //use breath first search wrt new elements

            while (!W1.IsEmpty)
            {
                var tmp = W;
                W  = W1;
                W1 = tmp;

                while (!W.IsEmpty)
                {
                    var B = W.Pop();

                    var Bcopy = new List <int>(B);             //make a copy of B for iterating over its elemenents
                    var Gamma = new Dictionary <int, T>();     //joined conditions leading to B from states leading to B
                    foreach (var q in Bcopy)
                    {
                        foreach (var move in fa.GetMovesTo(q))      //moves leading to q
                        {
                            if (Blocks[move.SourceState].Count > 1) //singleton blocks cannot be further split
                            {
                                if (Gamma.ContainsKey(move.SourceState))
                                {
                                    Gamma[move.SourceState] = solver.MkOr(Gamma[move.SourceState], move.Label);
                                }
                                else
                                {
                                    Gamma[move.SourceState] = move.Label;
                                }
                            }
                        }
                    }

                    //if x is not in Gamma.Keys then return False else return Gamma[q]
                    //this way initial (_,B)-splitting is not required
                    Func <int, T> GAMMA = (x) =>
                    {
                        T pred;
                        if (Gamma.TryGetValue(x, out pred))
                        {
                            return(pred);
                        }
                        else
                        {
                            return(solver.False);
                        }
                    };

                    var relevant2 = new HashSet <Block>();
                    foreach (var q in Gamma.Keys)
                    {
                        if (Blocks[q].Count > 1)
                        {
                            relevant2.Add(Blocks[q]); //collect the relevant blocks
                        }
                    }
                    var relevantList = new List <Block>(relevant2);

                    //only relevant blocks are potentially split
                    while (relevantList.Count > 0)
                    {
                        var P = relevantList[0];
                        relevantList.RemoveAt(0);

                        var PE = P.GetEnumerator();
                        PE.MoveNext();

                        var  P1         = new Block();
                        bool splitFound = false;

                        //psi may be false here
                        T psi = GAMMA(PE.Current);
                        P1.Add(PE.Current); //note that PE has at least 2 elements

                        #region compute P1 as the new sub-block of P
                        while (PE.MoveNext())
                        {
                            var q   = PE.Current;
                            var phi = GAMMA(q);

                            if (splitFound)
                            {
                                var psi_and_phi = solver.MkAnd(psi, phi);
                                if (solver.IsSatisfiable(psi_and_phi))
                                {
                                    psi = psi_and_phi;
                                    P1.Add(q);
                                }
                            }
                            else
                            {
                                var psi_min_phi = MkDiff(psi, phi);
                                if (solver.IsSatisfiable(psi_min_phi))
                                {
                                    psi        = psi_min_phi;
                                    splitFound = true;
                                }
                                else // [[psi]] is subset of [[phi]]
                                {
                                    var phi_min_psi = MkDiff(phi, psi);
                                    if (!solver.IsSatisfiable(phi_min_psi))
                                    {
                                        // [[phi]] is subset of [[psi]]
                                        P1.Add(q); //psi and phi are equivalent
                                    }
                                    else
                                    {
                                        //there is some a: q --a--> B and p --a--> compl(B)
                                        P1.Clear();
                                        P1.Add(q);
                                        psi        = phi_min_psi;
                                        splitFound = true;
                                    }
                                }
                            }
                        }
                        #endregion

                        #region split P
                        //if P1.Count == P.Count then nothing was split
                        if (P1.Count < P.Count)
                        {
                            var node = splithistory[P];
                            node.Split(psi);
                            //which one is left or right does not matter
                            splithistory[P]  = node.left;
                            splithistory[P1] = node.right;

                            foreach (var p in P1)
                            {
                                P.Remove(p);
                                Blocks[p] = P1;
                            }

                            if (W.Contains(P) || W1.Contains(P))
                            {
                                W1.Push(P1);
                            }
                            else if (P.Count <= P1.Count)
                            {
                                W1.Push(P);
                            }
                            else
                            {
                                W1.Push(P1);
                            }

                            if (P.Count > 1)
                            {
                                relevantList.Add(P);
                            }
                            if (P1.Count > 1)
                            {
                                relevantList.Add(P1);
                            }
                        }
                        #endregion
                    }
                }
            }
        }
Beispiel #33
0
 public void removeStack(BlockStack bs)
 {
     blockStacks.Remove(bs);
 }
Beispiel #34
0
        BlockStack makeSampleBlockStack()
        {
            InvokationBlock b1 = makeInvokationBlock("move % steps",
             new DataType[] { DataType.Number },
             DataType.Script,
             new IBlock[] { new TextBlock("") });

            InvokationBlock b2 = makeInvokationBlock("turn % degrees right",
                new DataType[] { DataType.Number },
                DataType.Script,
                new IBlock[] { new TextBlock("") });

            BlockStack stack = new BlockStack();
            stack.AddRange(new IBlock[] { b1, b2 });
            return stack;
        }
Beispiel #35
0
 internal SyntaxTreeNode AddNodeToCurrentBlock(SyntaxTreeNode node)
 {
     BlockStack.Peek().Block.Add(node);
     return(node);
 }
Beispiel #36
0
        private IBlock ToBlockStack(JToken json)
        {
            BlockStack b = new BlockStack();

            for (int i = 1; i < json.Count(); ++i)
            {
                IBlock subBlock = ToBlock(json[i]);
                if (i == 1 && subBlock is ProcDefBlock)
                    currentProcDef = subBlock as ProcDefBlock;
                b.Add(subBlock);
            }
            currentProcDef = null;
            return b;
        }
Beispiel #37
0
        /// <summary>
        /// Checks a specific prayer against a specific location,
        /// returning true if the layout is found and false if it
        /// is invalid.
        /// </summary>
        private bool CheckLayout(int x, int y, Prayer prayer)
        {
            // Figure out the extents for searching on this point
            int   pRows = prayer.Board.Rows;
            int   pCols = prayer.Board.Columns;
            int   bRows = Game.State.Board.Rows;
            int   bCols = Game.State.Board.Columns;
            Block first = null;

            // Sanity checking
            if (x < 0 || y < 0 ||
                x + pCols > bCols ||
                y + pRows > bRows)
            {
                return(false);
            }

            // Noise
            Debug("Checking for prayer at {0},{1}", x, y);

            // Loop through the columns
            for (int i = 0; i < pCols; i++)
            {
                // Get the game column
                IList <BlockStack> boardColumn = Game.State.Board[x + i];

                // Loop through each of the rows
                for (int j = 0; j < pRows; j++)
                {
                    // Grab the top block
                    BlockStack stack = prayer.Board[i, j];

                    // If this stack is empty, just skip it as valid
                    if (stack.Count == 0)
                    {
                        continue;
                    }

                    // Grab the stack
                    Block pBottom = stack.BottomBlock;

                    // Grab the board block
                    BlockStack bStack = boardColumn[y + j];
                    Block      bTop   = bStack.TopBlock;

                    // Compare the drawable names
                    if (pBottom.Sprite.ID == "Invisible")
                    {
                        // Invisible always matches
                        continue;
                    }

                    if (bTop.Sprite.ID != pBottom.Sprite.ID)
                    {
                        Debug("  Name rejected prayer: {0} v. {1}",
                              bTop.Sprite.ID, pBottom.Sprite.ID);
                        return(false);
                    }

                    // Copy first or verify that the position is valid
                    if (first == null)
                    {
                        first = bTop;
                    }
                    else
                    {
                        if (first.BottomPosition != bTop.BottomPosition)
                        {
                            Debug("  Position rejected prayer: {0} v {1}",
                                  first.BottomPosition, bTop.BottomPosition);
                            return(false);
                        }
                    }
                }
            }

            // We didn't have any errors
            Debug("  Found prayer!");
            return(true);
        }
Beispiel #38
0
    // Update is called once per frame
    void Update()
    {
        if (currentBlock.isEnd && IceHopping.S.stacksLeft() == 1 && state == action.idle)
        {
            Debug.Log("End reached");
            state = action.end;
            Invoke("nextLevel", 0.7f);
        }

        //check movement keys
        if (state == action.idle)
        {
            GetComponent <Rigidbody>().isKinematic = false;

            if (Input.GetKeyDown(KeyCode.LeftArrow))
            {
                if (currentBlock.left != null)
                {
                    moveTo = currentBlock.left;
                    movementStart();
                }
                else
                {
                    midPoint      = new Vector3(transform.position.x - .75f, transform.position.y + 0.5f, transform.position.z);
                    endPoint      = new Vector3(transform.position.x - 1.25f, -.13f, transform.position.z);
                    state         = action.moving;
                    moveStartTime = Time.time;
                }
            }
            else if (Input.GetKeyDown(KeyCode.RightArrow))
            {
                //if moving right is valid...
                if (currentBlock.right != null)
                {
                    moveTo = currentBlock.right;
                    movementStart();
                }
                //if its not valid, set the point yourself and start the timer
                else
                {
                    midPoint      = new Vector3(transform.position.x + .75f, transform.position.y + 0.5f, transform.position.z);
                    endPoint      = new Vector3(transform.position.x + 1.25f, -.13f, transform.position.z);
                    state         = action.moving;
                    moveStartTime = Time.time;
                }
            }
            else if (Input.GetKeyDown(KeyCode.DownArrow))
            {
                if (currentBlock.down != null)
                {
                    moveTo = currentBlock.down;
                    movementStart();
                }
                else
                {
                    midPoint      = new Vector3(transform.position.x, transform.position.y + 0.5f, transform.position.z - .75f);
                    endPoint      = new Vector3(transform.position.x, -.13f, transform.position.z - 1.25f);
                    state         = action.moving;
                    moveStartTime = Time.time;
                }
            }
            else if (Input.GetKeyDown(KeyCode.UpArrow))
            {
                if (currentBlock.up != null)
                {
                    moveTo = currentBlock.up;
                    movementStart();
                }
                else
                {
                    midPoint      = new Vector3(transform.position.x, transform.position.y + 0.5f, transform.position.z + .75f);
                    endPoint      = new Vector3(transform.position.x, -.13f, transform.position.z + 1.25f);
                    state         = action.moving;
                    moveStartTime = Time.time;
                }
            }
        }

        if (state == action.moving)
        {
            float u = (Time.time - moveStartTime) / movementTime;
            if (u > 1)
            {
                //state = action.idle;
                currentBlock = moveTo;
                callOnce     = false;
                moveTo       = null;
                if (state == action.waiting)
                {
                    state = action.idle;
                }
                else
                {
                    state = action.waiting;
                }
                return;
            }
            else if (u < 0)
            {
                return;
            }
            else
            {
                if (u > .25 && !callOnce)
                {
                    //dont lower more if there are none left to lower
                    if (currentBlock.blocks.Count > 0)
                    {
                        currentBlock.lower();
                        callOnce = true;
                    }
                }
                Vector3 p1, p2;
                p1 = (1 - u) * transform.position + u * midPoint;
                p2 = (1 - u) * midPoint + u * endPoint;

                transform.position = (1 - u) * p1 + u * p2;
            }
        }
    }
Beispiel #39
0
 internal SyntaxTreeNode LastNode()
 {
     return(BlockStack.GetCurrentBlockNode().LastNode());
 }
        /// <summary>
        /// Constructs the basic minor mode and sets up the internal
        /// structures.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="prayer"></param>
        public PrayerCompletedMinorMode(int x, int y, Prayer prayer)
            : base()
        {
            // Save the values
            X = x;
            Y = y;

            // Set up the prayer board
            Prayer = prayer;
            Prayer.Board.MaximumPosition = 5;
            Prayer.Board.MinimumPosition = -2;

            // Create the block viewport
            blockViewport =
                new BlockViewport(Prayer.Board, AssetLoader.Instance);
            blockViewport.Size         = blockViewport.Extents.Size;
            blockViewport.ClipContents = false;
            Viewport.Add(blockViewport);

            // We modify the prayer to simulate a drop by raising
            // everything but the bottommost one.
            for (int i = 0; i < prayer.Board.Columns; i++)
            {
                // Get the stack
                IList <BlockStack> stacks = prayer.Board[i];

                // Go through the stack
                for (int j = 0; j < stacks.Count; j++)
                {
                    // Get the stack
                    BlockStack stack = stacks[j];
                    stack.IsInInitialPlacement = false;

                    // Go through the blocks
                    foreach (Block block in stack)
                    {
                        // Mark this as unusable
                        block.Data = false;

                        // Figure out the position
                        if (block.BottomPosition != 0)
                        {
                            // For the top blocks
                            block.BottomPosition *=
                                Constants.PrayerDroppingMultiplier;
                            block.BottomPosition +=
                                Entropy.NextFloat(-0.5f, 0.5f);
                            block.IsMoving = true;
                            block.Mass     = Constants.PrayerBlockMass;
                            block.Vector   = Constants.PrayerDroppedVector;
                        }
                        else
                        {
                            // For the bottom blocks
                            block.IsMoving = false;
                            block.Vector   = 0;
                            block.Mass     = 0;
                        }
                    }
                }
            }

            // Attack some new events
            prayer.Board.BlockMovingChanged += OnBlockMovingChanged;
            prayer.Board.MovingChanged      += OnMovingChanged;
        }
Beispiel #41
0
        /// <summary>
        /// Drops the bottom-most grab stack (index 0) from the stack
        /// onto the currently selected stack.
        /// </summary>
        /// <param name="stack"></param>
        private void Drop()
        {
            // Don't bother if we can't drop
            if (currentStack == null || !CanDrop())
                return;

            // Grab the block we are dropping
            Block block = grabStack[0];

            // Move the rest of the stack down
            for (int i = 0; i < Constants.MaximumGrabCount - 1; i++)
                grabStack[i] = grabStack[i + 1];

            grabStack[Constants.MaximumGrabCount - 1] = null;

            // Set down the vector
            block.BottomPosition -= 1f;
            block.Vector = Constants.DroppedVector;

            // Put that block back into the stack
            droppingBlocks.Add(block);
            currentStack.Add(block);

            // Mark this as the end of the turn
            if (currentStack != lastGrabStack)
            {
                // Subtract a heart and score it
                Game.State.Hearts -= Game.State.GrabCost;
                Game.State.EndTurn();
            }

            // Reset the grab stack for "undo"
            lastGrabStack = null;
        }
Beispiel #42
0
        /// <summary>
        /// Grabs a block from the currently selected stack.
        /// </summary>
        /// <param name="stack"></param>
        private void Grab()
        {
            // We only care if we can grab something
            if (currentStack == null || !CanGrab())
                return;

            // Move everything up in the stack.
            Block topBlock = currentStack.TopBlock;

            for (int i = Constants.MaximumGrabCount - 1; i > 0; i--)
                grabStack[i] = grabStack[i - 1];

            // Grab the top block and change its position
            grabStack[0] = topBlock;
            topBlock.IsMoving = false;
            topBlock.Vector = 0;
            topBlock.Mass = 0;

            // Remove the stack for processing
            currentStack.Remove(topBlock);

            // Fire the sound event
            BlockStackEventArgs args = new BlockStackEventArgs();
            args.Stack = currentStack;
            args.Block = topBlock;
            Game.Sound.BlockGrabbed(this, args);

            // Save the last grab stack
            lastGrabStack = currentStack;
        }
Beispiel #43
0
        /// <summary>
        /// Triggered when the mouse enters a specific stack
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnStackMouseEnter(object sender, BlockStackEventArgs args)
        {
            // Ignore if we have a minor mode
            if (minorMode != null)
                return;

            // Add the selector to the current position and set it on top
            currentStack = args.Stack;

            // Remove the stack, just in case
            bool isValidTarget = IsValidTarget();

            // See if we have a valid target
            if (!isValidTarget)
            {
                // Change the selector so it shows an incorrect selection
                selector.Sprite = AssetLoader.Instance
                    .CreateSprite(Constants.InvalidSelectorName);
                vertViewport.Visible = false;

                // We are done
                return;
            }

            // Change the selector to show a valid selector.
            selector.Sprite = AssetLoader.Instance
                .CreateSprite(Constants.SelectorName);

            // Move the vertical stack display to the currently
            // selected stack and make it visible
            PointF vertPoint = blockViewport.ToPoint(
                currentStack.X, currentStack.Y,
                currentStack.TopPosition);
            vertViewport.Visible = true;
            vertViewport.BlockStackX = currentStack.X;
            vertViewport.BlockStackY = currentStack.Y;
            vertViewport.Point = new PointF(
                vertPoint.X
                + blockViewport.BlockWidth / 2
                - vertViewport.Size.Width / 2,
                vertPoint.Y);

            // We are going to be grabbing or dropping
            Game.GuiManager.MouseUpListeners.Add(this);
        }
Beispiel #44
0
        /// <summary>
        /// This event is used to handle jumping from one block to
        /// another.
        /// </summary>
        private void OnDirectionChanged(
            object sender,
            BlockStackEventArgs args)
        {
            // At the apex, we change our direction by moving to the
            // next stack as appropriate. Start by ignoring direction
            // 0 since that is an inplace jumping.
            if (direction == 0)
            {
                return;
            }

            // Get the destination stack
            Board      board     = Game.State.Board;
            BlockStack srcStack  = board[X, Y];
            BlockStack destStack = null;

            if (direction == 1)
            {
                destStack = board[X, Y - 1];
            }
            else if (direction == 2)
            {
                destStack = board[X + 1, Y];
            }
            else if (direction == 3)
            {
                destStack = board[X, Y + 1];
            }
            else if (direction == 4)
            {
                destStack = board[X - 1, Y];
            }

            // Make sure we are still a valid destination
            if (IsInvalidTarget(srcStack, destStack))
            {
                // We want to reverse the direction, but stay in the
                // same stack because our destination became
                // invalid. This works because the code will show them
                // "bouncing" back.
                if (direction == 1)
                {
                    direction = 3;
                }
                else if (direction == 2)
                {
                    direction = 4;
                }
                else if (direction == 3)
                {
                    direction = 1;
                }
                else if (direction == 4)
                {
                    direction = 2;
                }

                // We are done
                srcStack.Add(this);
                return;
            }

            // Move this block to the next one
            srcStack.Remove(this);
            destStack.Add(this);

            // Change our coordinates
            if (direction == 1)
            {
                BottomPosition -= 4;
                Y--;
            }
            else if (direction == 2)
            {
                OffsetX -= 101;
                X++;
            }
            else if (direction == 3)
            {
                BottomPosition += 1;
                Y++;
            }
            else if (direction == 4)
            {
                OffsetX += 101;
                X--;
            }
        }
Beispiel #45
0
        /// <summary>
        /// Adds some bugs into the stage.
        /// </summary>
        public void AddBugs(int howMany)
        {
            // Loop through the bugs
            for (int i = 0; i < howMany; i++)
            {
                // Create a bug
                Bug bug = new Bug();

                // Place the bug
                while (true)
                {
                    // Find a random location
                    int        col   = Entropy.Next(0, Columns);
                    int        row   = Entropy.Next(0, Constants.BoardRows);
                    BlockStack stack = this[col, row];

                    // Go through the stack, looking for bugs
                    float immobilePosition = 0;
                    bool  foundGround      = false;
                    bool  validStack       = false;

                    foreach (Block block in stack)
                    {
                        // Don't bother if we already have a bug here
                        if (block.Sprite.ID == Constants.BugBlockName)
                        {
                        }

                        // Make sure we have at least one land block
                        else if (IsGroundBlock(block))
                        {
                            foundGround = true;
                        }

                        // If we have an immobile, keep it
                        else if (block.Sprite.ID ==
                                 Constants.ImmobileBlockName)
                        {
                            immobilePosition =
                                Math.Max(block.TopPosition, immobilePosition);
                            validStack = true;
                        }

                        // Not valid, a character or someting
                        else
                        {
                            validStack = false;
                            break;
                        }
                    }

                    // See if we have a valid one
                    if (!validStack || !foundGround)
                    {
                        continue;
                    }

                    // Put the bug in
                    bug.BottomPosition = immobilePosition;
                    bug.X          = col;
                    bug.Y          = row;
                    bug.BlockStack = stack;
                    stack.Add(bug);
                    stack.Sort();
                    Game.State.Bugs.Add(bug);
                    break;
                }
            }
        }