// Selecting other blocks after an initial block is selected, continues the matching chain void OnBlockPointerEnter(BoardBlock boardBlock, PointerEventData.InputButton inputButton) { BoardPosition boardPos = GetBoardPosition(boardBlock); // Only care about going over other tiles if one is selected already // Also needs to match the same color if (blockState == BlockState.Selecting && potentialLinks.Contains(boardPos)) { // If we're entering the previously recorded tile... if (selectedBlocks.Count > 1 && selectedBlocks.IndexOf(boardPos) == selectedBlocks.Count - 2) { // ...remove it, the player has gone back a step in their line drawing selectedBlocks.RemoveAt(selectedBlocks.Count - 1); // Calculate next set of potential block links potentialLinks = NextPotentialPositions(boardPos); } // Otherwise add the tile if it isn't already captured else if (!selectedBlocks.Contains(boardPos)) { selectedBlocks.Add(boardPos); // Calculate next set of potential block links potentialLinks = NextPotentialPositions(boardPos); } } }
/// <summary> /// Places a house at the specified location (top left corner of the house). /// </summary> /// <param name="board">Board for the house to be placed on</param> /// <param name="wallBlock">Block the walls are made of</param> /// <param name="floorBlock">Block the floor is made of</param> /// <param name="x">X coordinate where the top left corner of the house will be placed</param> /// <param name="y">Y coordinate where the top left corner of the house will be placed</param> public void PlaceHouse(Board board, BoardBlock wallBlock, BoardBlock floorBlock, int x, int y) { PlaceRectangle(board, Grass, new Point(x - 1, y - 1), new Point(x + 5, y + 5)); PlaceRectangle(board, Grass, new Point(x - 2, y - 2), new Point(x + 6, y + 6)); PlaceSquare(board, floorBlock, new Point(x + 1, y + 1), 3); PlaceRectangle(board, WoodWall, new Point(x, y), new Point(x + 4, y + 4)); PlaceBlock(board, floorBlock, x + 2, y); }
/// <summary> /// Places a block at the specified location in the map. /// </summary> /// <param name="board"></param> /// <param name="block"></param> /// <param name="point"></param> public void PlaceBlock(Board board, BoardBlock block, Point point) { if (point.X < 0 || point.X >= board.Size.Width || point.Y < 0 || point.Y >= board.Size.Height) { return; } board[point] = block; }
/// <summary> /// Places a square of blocks on the specified board. /// </summary> /// <param name="board">Board for the blocks to be placed on</param> /// <param name="block">Block used for the square</param> /// <param name="startingX">Starting X coordinate of the square (upper left corner)</param> /// <param name="startingY">Starting Y coordinate of the square (upper left corner)</param> /// <param name="sideLength">Length of each side</param> public void PlaceSquare(Board board, BoardBlock block, int startingX, int startingY, int sideLength) { for (int i = 0; i < sideLength; i++) { for (int j = 0; j < sideLength; j++) { PlaceBlock(board, block, new Point(startingX + i, startingY + j)); } } }
// Block input events // Selecting first tile void OnBlockPointerDown(BoardBlock boardBlock, PointerEventData.InputButton inputButton) { blockState = BlockState.Selecting; BoardPosition boardPos = GetBoardPosition(boardBlock); // Add it to the list of tiles chosen selectedBlocks.Add(boardPos); // Find the next tiles of the same color potentialLinks = NextPotentialPositions(boardPos); }
public Move(BoardBlock block, int column, double cost, int board, int[] heights, int lidx, BoardState bs, int placedArea, double density) { Block = new BoardBlock(block.Grid.Clone() as int[, ], new Point(block.Position.X, block.Position.Y)); Board = board; Column = column; Cost = cost; NewHeights = heights.Clone() as int[]; ListIndex = lidx; BoardState = bs; Density = density; PlacedArea = placedArea; }
/// <summary> /// Parse tile block and put information into configuration of the application /// </summary> /// <param name="filename"></param> public void LoadInitial(string filename) { this.Blocks.Clear(); using (StreamReader sr = File.OpenText(filename)) { string line = String.Empty; int state = 0; int numOfBlocks = 0; int blockHeight = 0; int currRowNo = 0; IBlock currentBlock = new BoardBlock(1, 1); while ((line = sr.ReadLine()) != null) { switch (state) { case 0: string[] vals = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); this.Width = uint.Parse(vals[0]); numOfBlocks = int.Parse(vals[1]); state = 1; break; case 1: string[] vals1 = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); currentBlock = new Block(int.Parse(vals1[0]), int.Parse(vals1[1])); blockHeight = int.Parse(vals1[1]); state = 2; currRowNo = 0; break; case 2: string[] vals2 = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < vals2.Length; i++) { currentBlock.Grid[i, currRowNo] = int.Parse(vals2[i]); if (!(int.Parse(vals2[i]) == 0 || int.Parse(vals2[i]) == 1)) { throw new Exception(); } } currRowNo++; if (currRowNo == blockHeight) { state = 1; this.Blocks.Add(currentBlock); } break; } } } }
/// <summary> /// Places a rectangle of blocks around the specified area /// </summary> /// <param name="board">Board for the blocks to be placed on</param> /// <param name="block">Block used for the rectangle</param> /// <param name="startingPoint">Starting point of the rectangle (upper left corner)</param> /// <param name="endingPoint">Ending point of the rectangle (lower right corner)</param> public void PlaceRectangle(Board board, BoardBlock block, Point startingPoint, Point endingPoint) { for (int i = 0; i < endingPoint.X - startingPoint.X; ++i) { PlaceBlock(board, block, startingPoint.X + i, startingPoint.Y); PlaceBlock(board, block, startingPoint.X + i, endingPoint.Y); } for (int i = 0; i < endingPoint.Y - startingPoint.Y + 1; ++i) { PlaceBlock(board, block, startingPoint.X, startingPoint.Y + i); PlaceBlock(board, block, endingPoint.X, startingPoint.Y + i); } }
public BoardPosition GetBoardPosition(BoardBlock boardBlock) { BoardPosition foundBoardPos = null; foreach (BoardPosition boardPos in blockGrid) { if (boardPos.boardBlock == boardBlock) { foundBoardPos = boardPos; break; } } return(foundBoardPos); }
public Board(Size dimension, BoardBlock defaultBlock) { this.Size = dimension; var tempList = new List <BoardBlock>(); for (int i = 0; i < dimension.Width; i++) { for (int j = 0; j < dimension.Height; j++) { tempList.Add(defaultBlock); } } content = tempList; }
/// <summary> /// Instantiates a map container. /// </summary> /// <param name="width">Width of the map</param> /// <param name="height">Height of the map</param> /// <param name="depth">Depth of the map (number of layers)</param> /// <param name="defaultBlock">The block the map is filled with by default</param> public Map(int width, int height, int depth, BoardBlock defaultBlock) { if (depth < 0) { throw new ArgumentOutOfRangeException("depth"); } if (depth == 0) { throw new ArgumentException("depth"); } this.Depth = depth; this.layers = Enumerable.Range(0, depth).Select(x => new Board(width, height, defaultBlock)).ToArray(); }
public List <Move> CalculateTask(BoardBlock block, int idx) //step of the algorithm for one board, calculate cost for every block and every rotation when placed in each column { List <Move> ret = new List <Move>(); for (int j = 0; j < 4; j++) { for (int i = 0; i <= Width - block.Grid.GetLength(0); i++) { var result = CheckMove(i, block); if (result != null) { var newBlock = new BoardBlock(block); newBlock.Position = result.Location; ret.Add(new Move(newBlock, i, result.Cost, K, result.Heights, idx, this, PlacedArea + block.GetArea(), (PlacedArea + block.GetArea()) / (double)(result.Heights.Max() * Width))); } } block = block.RotateClockwise(); } return(ret); }
public Board(int width, int height, BoardBlock defaultBlock) : this(new Size(width, height), defaultBlock) { }
/// <summary> /// Places a square of blocks on the specified board. /// </summary> /// <param name="board">Board for the the blocks to be placed on</param> /// <param name="block">Block used for the square</param> /// <param name="startingPoint">Starting point of the square (upper left corner)</param> /// <param name="sideLength">Length of each side</param> public void PlaceSquare(Board board, BoardBlock block, Point startingPoint, int sideLength) { PlaceSquare(board, block, startingPoint.X, startingPoint.Y, sideLength); }
public Board(Point maxSize, BoardBlock defaultBlock) : this(new Size(maxSize), defaultBlock) { }
/// <summary> /// Places a rectangle of blocks around a specified area /// </summary> /// <param name="board">Board for the blocks to be placed on</param> /// <param name="block">Block used for the rectangle</param> /// <param name="startingX">Starting X coordinate of the rectangle</param> /// <param name="startingY">Starting Y coordinate of the recatangle</param> /// <param name="endingX">Ending X coordinate of the rectangle</param> /// <param name="endingY">Ending Y coordinate of the rectangle</param> public void PlaceRectangle(Board board, BoardBlock block, int startingX, int startingY, int endingX, int endingY) { PlaceRectangle(board, block, new Point(startingX, startingY), new Point(endingX, endingY)); }
public MultipleBlock(MultipleBlock m) { Block = new BoardBlock(m.Block); Count = m.Count; }
/// <summary> /// Places a block at the specified location in the map. /// </summary> /// <param name="block">Block to be placed</param> /// <param name="x">X coordinate of the block</param> /// <param name="y">Y coordinate of the block</param> public void PlaceBlock(Board board, BoardBlock block, int x, int y) { PlaceBlock(board, block, new Point(x, y)); }
void RefillBlockGrid() { blockState = BlockState.Falling; // Three ways a block can fall down into an empty tile BoardDirection[] upwardsDirections = new BoardDirection[] { BoardDirection.Top, BoardDirection.TopLeft, BoardDirection.TopRight }; // Loop checking to keep blocks falling until they can't fall anymore bool areBlocksNeeded = true; while (areBlocksNeeded) { bool isFalling = false; foreach (BoardPosition pos in blockGrid) { if (pos.needsABlock && pos.y > 0) { List <BoardPosition> availableBlocksToFall = GetNeighbours(pos, upwardsDirections); BoardPosition aps = null; if (availableBlocksToFall.Count > 0) { aps = availableBlocksToFall[0]; } if (aps != null && !aps.needsABlock && aps.blockType != Block.BlockType.None) { isFalling = true; aps.go.GetComponent <RectTransform>().DOAnchorPos(pos.position, .5f).SetEase(BlockManager.Instance.blockFallEase); // Block swapping pos.boardBlock = null; pos.boardBlock = aps.boardBlock; pos.needsABlock = false; pos.go = aps.go; pos.blockColor = aps.blockColor; aps.boardBlock = null; aps.needsABlock = true; aps.go = null; } } // Block is in top row, need to bring a new one from above the playfield else if (pos.needsABlock && pos.y == 0) { isFalling = true; // Bring in new block & apply block settings GameObject boardBlockObject = Instantiate(BlockManager.Instance.blockPrefab, pos.position, Quaternion.identity, transform); boardBlockObject.transform.localScale = BlockManager.Instance.blockPrefab.transform.localScale * blockScale; BoardBlock boardBlock = boardBlockObject.GetComponent <BoardBlock>(); RectTransform blockRectTransform = boardBlock.GetComponent <RectTransform>(); blockRectTransform.anchoredPosition = pos.position + new Vector3(0, 64, 0); blockRectTransform.DOAnchorPos(pos.position, 0.5f).SetEase(BlockManager.Instance.blockFallEase); pos.boardBlock = boardBlock; boardBlock.OnBlockPointerDown += OnBlockPointerDown; boardBlock.OnBlockPointerUp += OnBlockPointerUp; boardBlock.OnBlockPointerEnter += OnBlockPointerEnter; pos.go = boardBlockObject; pos.SetupBlock(Block.BlockType.Normal); pos.needsABlock = false; } } // Leave the loop if no more blocks are falling if (!isFalling) { areBlocksNeeded = false; } } blockState = BlockState.Unselected; selectedBlocks.Clear(); // Visual state reset, no block fade ResetBlockSelection(); }
/// <summary> /// Instantiates a map container. /// </summary> /// <param name="size">Size of each board</param> /// <param name="depth">Depth of the map (number of layers)</param> /// <param name="defaultBlock">The block the map is filled with by default</param> public Map(Size size, int depth, BoardBlock defaultBlock) : this(size.Width, size.Height, depth, defaultBlock) { }
public CheckMoveResult CheckMove(int i, BoardBlock block) // i - column of the well in which the block should be placed { int w = block.Grid.GetLength(0); int[] botEmpty = new int[w]; for (int idx = 0; idx < w; idx++) { int h = 0; int hpos = block.Grid.GetLength(1) - 1; while (hpos >= 0 && block.Grid[idx, hpos] == 0) { h++; hpos--; } botEmpty[idx] = h; } //calculate the number of empty cells in each column of the blopck int min = botEmpty.Min(); int[] positions = new int[w]; for (int idx = 0; idx < w; idx++) { //botEmpty[idx] = botEmpty[idx] - min; positions[idx] = this.Heights[i + idx] + block.Grid.GetLength(1) - botEmpty[idx]; } int blockPos = Array.IndexOf(positions, positions.Max()); int blockHeight = this.Heights[i + blockPos] + block.Grid.GetLength(1) - botEmpty[blockPos]; //find the position of the block if placed on top of the stack in given columns bool ok = true; for (int idx = 0; idx < w; idx++) { if (blockHeight - block.Grid.GetLength(1) + botEmpty[idx] - this.Heights[i + idx] < 1) { ok = false; } } ok = true; //check if this placing is valid if (ok) { int[] topEmpty = new int[w]; int[] newHeights = new int[w]; for (int idx = 0; idx < w; idx++) { int h = 0; int hpos = 0; while (hpos < block.Grid.GetLength(1) && block.Grid[idx, hpos] == 0) { h++; hpos++; } topEmpty[idx] = h; newHeights[idx] = blockHeight - topEmpty[idx]; } //find the number of empty cells on top of the block in each column //and the heights of the well after placing the block int[] tempHeights = new int[Heights.Length]; Heights.CopyTo(tempHeights, 0); newHeights.CopyTo(tempHeights, i); int aggHeight = tempHeights.Sum(); int heightIncrease = tempHeights.Max() - Heights.Max(); int bumps = 0; for (int idx = 0; idx < tempHeights.Length - 1; idx++) { bumps = bumps + (Math.Abs(tempHeights[idx] - tempHeights[idx + 1])); } int holes = 0; for (int idx = 0; idx < w; idx++) { holes = holes + (blockHeight - block.Grid.GetLength(1) + botEmpty[idx] - Heights[i + idx]); } //find variables needed to compute the cost return(new CheckMoveResult() { Cost = (A * aggHeight + B * bumps + C * holes + D * heightIncrease), Heights = tempHeights, Location = new System.Drawing.Point(i, blockHeight - block.Grid.GetLength(1)), }); } else { return(null); } }