/// <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; }
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 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++; } }
/// <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)); } } } } }
/// <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); }
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; }
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); }
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; }
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 { } }
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); } }
/// <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); }
/// <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>(); }
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; }
/// <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); }
/// <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; }
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); }
/// <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); } }
/// <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; } } }
/// <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); } } } }
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; }
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; }
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; }
/// <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; } }
/// <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); }
public TopLevelScript SplitBlockStack(BlockStack block, int nKeep, Point newStacklocation) { IBlock newStack = block.Split(nKeep); return AddTopLevel(newStack, newStacklocation); }
/// <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; }
bool IsEmptyBlockStack(BlockStack blockStack) { return(blockStack == null || (blockStack.Block == BlockValue.Air && blockStack.count == 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); } }
/// <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 } } } }
public void removeStack(BlockStack bs) { blockStacks.Remove(bs); }
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; }
internal SyntaxTreeNode AddNodeToCurrentBlock(SyntaxTreeNode node) { BlockStack.Peek().Block.Add(node); return(node); }
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; }
/// <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); }
// 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; } } }
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; }
/// <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; }
/// <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; }
/// <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); }
/// <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--; } }
/// <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; } } }