02.消消乐斜向填充算法

  //分步填充
    public bool Fill()
    {
        bool filledNotFinished = false;//判断本次填充是否完成

        for (int y = yRow-2; y >=0; y--)
        {
            for (int x = 0; x < xColumn; x++)
            {
                GameSweet sweet = sweets[x, y];//得到当前元素位置的甜品对象
                if (sweet.CanMove())//如果无法移动,则无法往下填充 
                {
                    GameSweet sweetBelow = sweets[x, y + 1];

                    if (sweetBelow.Type==SweetsType.EMPTY)//垂直填充 正下方的情况
                    {
                        Destroy(sweetBelow.gameObject);
                        sweet.MovedComponent.Move(x, y + 1,fillTime);
                        sweets[x, y + 1] = sweet;
                        CreateNewSweet(x, y, SweetsType.EMPTY); //移走了就为空了
                        filledNotFinished = true;
                    }
                    else //斜向填充 遍历左右下方的情况
                    {
                        //down -1左下 0 正下 1右下 三次遍历
                        for (int down = -1; down <=1; down++)
                        {
                            if (down!=0) //排除正下方的情况
                            {
                                int downX = x + down;
                                //排除没有左下和右下的情况
                                if (downX>=0&&downX<xColumn)
                                {
                                    //获取左下方的对象
                                    GameSweet downSweet = sweets[downX, y + 1];
                                    //左下位置是不是空甜品
                                    if (downSweet.Type==SweetsType.EMPTY)
                                    {
                                        //是否可以垂直填充
                                        bool canFill = true;
                                        //左下头顶的是不是可以垂直填充
                                        for (int aboveY = y; aboveY>=0; aboveY--)
                                        {
                                            // 左下头顶的对象
                                            GameSweet sweetAbove = sweets[downX, aboveY];
                                            if (sweetAbove.CanMove()) //可以垂直填充不用斜填充
                                            {
                                                break;
                                            }
                                            else if (sweetAbove.Type!=SweetsType.EMPTY&&!sweetAbove.CanMove()) //是空甜品而且不能移动的时候
                                            {
                                                canFill = false;
                                                break;
                                            }
                                           
                                        }

                                        if (!canFill)
                                        {
                                            Destroy(downSweet.gameManager); //把要填充的原来的空甜品移除
                                            //斜向填充
                                            sweet.MovedComponent.Move(downX,y+1,fillTime);
                                            sweets[downX, y + 1] = sweet;
                                            CreateNewSweet(x, y, SweetsType.EMPTY); //移走了就为空了
                                            filledNotFinished = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
               
                
            }
        }



        //最上排的特殊情况
        for (int x = 0; x < xColumn; x++)
        {
            GameSweet sweet = sweets[x, 0];

            if (sweet.Type==SweetsType.EMPTY)
            {
                GameObject newSweet= Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPositon(x, -1), Quaternion.identity);
                newSweet.transform.parent = transform;
                sweets[x, 0] = newSweet.GetComponent<GameSweet>();//赋值给数组
                sweets[x, 0].Init(x, -1, this, SweetsType.NORMAL);
                sweets[x, 0].MovedComponent.Move(x, 0,fillTime);
                sweets[x, 0].ColoredComponent.SetColor((ColorSweet.ColorType)Random.Range(0, sweets[x, 0].ColoredComponent.NumColors));
                filledNotFinished = true;
            }
        }

        return filledNotFinished;
    }

   
   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
消消乐填充算法是一种经典的游戏算法,其主要目的是在一个矩阵中,将相同的方块进行消除,以获得更高的分数。下面我会提供一个简单的Vue实现消消乐游戏的例子,并讲解其中的算法原理。 首先,我们需要创建一个包含所有游戏方块的矩阵。我们可以用一个二维数组来表示矩阵,其中每个元素代表一个方块。例如: ```javascript data: { matrix: [ [1, 1, 2, 3, 2], [3, 2, 1, 2, 3], [1, 2, 1, 3, 2], [3, 1, 2, 1, 3], [2, 3, 1, 2, 1] ] } ``` 在上述代码中,我们创建了一个5x5的矩阵,其中每个方块的值为1、2或3。 接下来,我们需要实现一个算法来检查矩阵中是否存在相同的方块。我们可以使用深度优先搜索算法来遍历整个矩阵,以找到相邻的相同方块。具体实现代码如下: ```javascript function check(matrix, visited, row, col, value) { if ( row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length || visited[row][col] || matrix[row][col] !== value ) { return; } visited[row][col] = true; check(matrix, visited, row - 1, col, value); // 上 check(matrix, visited, row + 1, col, value); // 下 check(matrix, visited, row, col - 1, value); // 左 check(matrix, visited, row, col + 1, value); // 右 } ``` 在上述代码中,我们使用了一个visited数组来记录已经遍历过的方块,避免重复遍历。然后,我们对当前方块的上下左右进行递归遍历,直到找到所有相邻的相同方块。 接下来,我们需要实现一个算法来消除所有相邻的相同方块。我们可以使用一个队列来记录所有需要消除的方块。具体实现代码如下: ```javascript function remove(matrix, visited, row, col, value, queue) { if ( row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length || visited[row][col] || matrix[row][col] !== value ) { return; } visited[row][col] = true; queue.push({ row, col }); remove(matrix, visited, row - 1, col, value, queue); // 上 remove(matrix, visited, row + 1, col, value, queue); // 下 remove(matrix, visited, row, col - 1, value, queue); // 左 remove(matrix, visited, row, col + 1, value, queue); // 右 } ``` 在上述代码中,我们使用了一个queue数组来记录需要消除的方块。然后,我们对当前方块的上下左右进行递归遍历,将所有相邻的相同方块加入到队列中。 最后,我们可以实现一个方法来执行整个游戏的主逻辑。具体实现代码如下: ```javascript methods: { play() { const { matrix } = this; const visited = matrix.map(row => row.map(() => false)); for (let row = 0; row < matrix.length; row++) { for (let col = 0; col < matrix[0].length; col++) { if (!visited[row][col]) { const queue = []; const value = matrix[row][col]; remove(matrix, visited, row, col, value, queue); if (queue.length > 1) { for (const { row, col } of queue) { matrix[row][col] = null; } } } } } for (let col = 0; col < matrix[0].length; col++) { const stack = []; for (let row = matrix.length - 1; row >= 0; row--) { if (matrix[row][col] !== null) { stack.push(matrix[row][col]); } } for (let row = matrix.length - 1; row >= 0; row--) { if (stack.length > 0) { matrix[row][col] = stack.pop(); } else { matrix[row][col] = null; } } } } } ``` 在上述代码中,我们首先遍历整个矩阵,对每个未遍历过的方块进行消除操作。如果当前方块的相邻方块数量大于1,则将所有相邻方块的值设置为null,标记需要消除。然后,我们通过一个栈来将每列中的非null方块向下移动,以填补消除方块留下的空位。 最后,我们只需要在页面上渲染出所有方块,并绑定上点击事件即可。点击方块时,我们执行play方法来更新矩阵,并重新渲染页面。 完整代码如下: ```html <template> <div> <div v-for="(row, i) in matrix" :key="i" class="row"> <div v-for="(value, j) in row" :key="j" class="block" :class="{ selected: selected === `${i}-${j}` }" :style="{ backgroundColor: colors[value] }" @click="onSelect(`${i}-${j}`)" ></div> </div> </div> </template> <script> export default { data: { matrix: [ [1, 1, 2, 3, 2], [3, 2, 1, 2, 3], [1, 2, 1, 3, 2], [3, 1, 2, 1, 3], [2, 3, 1, 2, 1] ], selected: null, colors: { 1: '#f00', 2: '#0f0', 3: '#00f' } }, methods: { onSelect(key) { if (this.selected === key) { this.selected = null; } else if ( this.selected && this.canSwap(this.selected, key) ) { this.swap(this.selected, key); this.play(); this.selected = null; } else { this.selected = key; } }, canSwap(key1, key2) { const [i1, j1] = key1.split('-'); const [i2, j2] = key2.split('-'); const di = Math.abs(i1 - i2); const dj = Math.abs(j1 - j2); return (di === 0 && dj === 1) || (di === 1 && dj === 0); }, swap(key1, key2) { const [i1, j1] = key1.split('-'); const [i2, j2] = key2.split('-'); const temp = this.matrix[i1][j1]; this.matrix[i1][j1] = this.matrix[i2][j2]; this.matrix[i2][j2] = temp; }, play() { const { matrix } = this; const visited = matrix.map(row => row.map(() => false)); for (let row = 0; row < matrix.length; row++) { for (let col = 0; col < matrix[0].length; col++) { if (!visited[row][col]) { const queue = []; const value = matrix[row][col]; remove(matrix, visited, row, col, value, queue); if (queue.length > 1) { for (const { row, col } of queue) { matrix[row][col] = null; } } } } } for (let col = 0; col < matrix[0].length; col++) { const stack = []; for (let row = matrix.length - 1; row >= 0; row--) { if (matrix[row][col] !== null) { stack.push(matrix[row][col]); } } for (let row = matrix.length - 1; row >= 0; row--) { if (stack.length > 0) { matrix[row][col] = stack.pop(); } else { matrix[row][col] = null; } } } } } }; function remove(matrix, visited, row, col, value, queue) { if ( row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length || visited[row][col] || matrix[row][col] !== value ) { return; } visited[row][col] = true; queue.push({ row, col }); remove(matrix, visited, row - 1, col, value, queue); // 上 remove(matrix, visited, row + 1, col, value, queue); // 下 remove(matrix, visited, row, col - 1, value, queue); // 左 remove(matrix, visited, row, col + 1, value, queue); // 右 } </script> <style> .row { display: flex; } .block { width: 50px; height: 50px; margin: 5px; cursor: pointer; } .selected { border: 2px solid #000; } </style> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值