Пример #1
0
    // 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);
            }
        }
    }
Пример #2
0
 /// <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);
 }
Пример #3
0
        /// <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;
        }
Пример #4
0
 /// <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));
         }
     }
 }
Пример #5
0
    // 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);
    }
Пример #6
0
 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;
 }
Пример #7
0
        /// <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;
                    }
                }
            }
        }
Пример #8
0
        /// <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);
            }
        }
Пример #9
0
    public BoardPosition GetBoardPosition(BoardBlock boardBlock)
    {
        BoardPosition foundBoardPos = null;

        foreach (BoardPosition boardPos in blockGrid)
        {
            if (boardPos.boardBlock == boardBlock)
            {
                foundBoardPos = boardPos;
                break;
            }
        }

        return(foundBoardPos);
    }
Пример #10
0
        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;
        }
Пример #11
0
        /// <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();
        }
Пример #12
0
        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);
        }
Пример #13
0
 public Board(int width, int height, BoardBlock defaultBlock) : this(new Size(width, height), defaultBlock)
 {
 }
Пример #14
0
 /// <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);
 }
Пример #15
0
 public Board(Point maxSize, BoardBlock defaultBlock) : this(new Size(maxSize), defaultBlock)
 {
 }
Пример #16
0
 /// <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));
 }
Пример #17
0
 public MultipleBlock(MultipleBlock m)
 {
     Block = new BoardBlock(m.Block);
     Count = m.Count;
 }
Пример #18
0
 /// <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));
 }
Пример #19
0
    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();
    }
Пример #20
0
 /// <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)
 {
 }
Пример #21
0
        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);
            }
        }