全妹爱看的乌龟对对碰背后的逻辑

253 阅读3分钟

前段时间全妹在直播间玩乌龟对对碰的事让大家津津乐道,其实玩法本质就是一个九宫格棋盘类游戏。

玩法

实际是一种盲盒销售手段,玩家花费一定金额购买对应数量的乌龟摆件,主播会根据顺序将其拆开,将其放在桌面对应位置上,按照规则清除,直到桌面上没有符合以上规则的乌龟位置,拆出来的所有小乌龟,均归玩家所有。

名词解释

  1. 许愿

    又叫幸运色,拆到玩家选择的“幸运色”

  2. 对碰

    当桌面上同时出现两个颜色乌龟

  3. 三连

    当桌面上有是哪个同样颜色的乌龟位列一排

  4. 清台

    当桌面上所有乌龟都被清除

  5. 全家福

    乌龟有10个颜色,桌面有九个格子,当九个格子中的颜色均不一致

代码实现

import { Node } from 'cc';
import { HallTurtle } from '../hall/HallTurtle';
export class GridHandler {
    private static _instance: GridHandler = null;
    private constructor() { }
    // 获取单例实例
    public static get instance(): GridHandler {
        if (this._instance == null) {
            this._instance = new GridHandler();
        }
        return this._instance;
    }

    //九宫格
    public grid: Node[][] = [
        [null, null, null],
        [null, null, null],
        [null, null, null],
    ];


    // 派发指定数量的物品到空的格子
    public dispatchItemToEmptyCells(item: Node) {
        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                if (this.grid[i][j] === null) {
                    this.grid[i][j] = item;
                    // console.log(`格子 (${i}, ${j}) 是空的,派发物品: ${item.name}`);
                    return [i, j];
                }
            }
        }
        return null
    }

    //清空制定格子
    public clearCells(i: number, j: number) {
        this.grid[i][j] = null;
    }

    // 清空所有格子
    public clearAllCells() {
        this.grid = Array(3).fill(null).map(() => Array(3).fill(null));
    }

    // 检查网格中是否有两个相同的物品(对碰)
    public hasTwoSameItems(): Node[] {
        let grid = this.grid
        // 用一个Map来存储每个物品
        const itemMap = new Map<number, Node>();
        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                const item = grid[i][j];
                if (item !== null) {
                    let turtleColorID = item.getComponent(HallTurtle).turtleColorID
                    // 如果这个物品已经存在于Map中
                    if (itemMap.has(turtleColorID)) {
                        return [itemMap.get(turtleColorID), item]
                    } else {
                        itemMap.set(turtleColorID, item);
                    }
                }
            }
        }
        return []; // 没有找到两个相同的物品
    }

    // 检查网格中是否有指定颜色的物品(幸运色)
    public hasSpecifiedItem(luckyColorID: number): Node {
        let grid = this.grid
        // 遍历整个九宫格
        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                const item = grid[i][j]
                if (item && item.getComponent(HallTurtle).turtleColorID === luckyColorID) {
                    return item; // 找到指定的物品
                }
            }
        }
        return null; // 没有找到指定的物品
    }

    // 检查是否有三连
    public checkThreeInARow(): Node[] {
        let grid = this.grid;

        // 定义一个检查三连的辅助函数
        const isThreeInARow = (nodes: Node[]): boolean => {
            return nodes.every(node => node && node.getComponent(HallTurtle).turtleColorID === nodes[0].getComponent(HallTurtle).turtleColorID);
        };

        // 检查每一行
        for (let i = 0; i < 3; i++) {
            let row = [grid[i][0], grid[i][1], grid[i][2]];
            if (isThreeInARow(row)) {
                return row;
            }
        }

        // 检查每一列
        for (let i = 0; i < 3; i++) {
            let col = [grid[0][i], grid[1][i], grid[2][i]];
            if (isThreeInARow(col)) {
                return col;
            }
        }

        // 检查对角线 (从左上到右下)
        let leftDiagonal = [grid[0][0], grid[1][1], grid[2][2]];
        if (isThreeInARow(leftDiagonal)) {
            return leftDiagonal;
        }

        // 检查对角线 (从右上到左下)
        let rightDiagonal = [grid[0][2], grid[1][1], grid[2][0]];
        if (isThreeInARow(rightDiagonal)) {
            return rightDiagonal;
        }

        // 如果没有三连,返回空数组
        return [];
    }


    //检查是否有清台
    public areAllCellsEmpty(): boolean {
        let grid = this.grid
        // 遍历整个九宫格
        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                // 如果有任意一个格子不是空的,返回 false
                if (grid[i][j] !== null) {
                    return false;
                }
            }
        }
        // 如果所有格子都为空,返回 true
        return true;
    }

    // 检查是否所有物品都不同(全家福)
    public hasFamily(): Node[] {
        let grid = this.grid;
        const itemMap = new Map<number, Node>();

        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                const item = grid[i][j];
                if (!item) {
                    return [];
                }

                let turtleColorID = item.getComponent(HallTurtle).turtleColorID;

                // 如果这个颜色ID已经存在于Map中,返回空数组
                if (itemMap.has(turtleColorID)) {
                    return [];
                }

                itemMap.set(turtleColorID, item);
            }
        }

        return Array.from(itemMap.values());
    }


    //计算网格中空格的数量
    public countEmptyCells(): number {
        let emptyCount = 0;
        // 遍历整个网格
        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                if (this.grid[i][j] === null) {
                    emptyCount++;
                }
            }
        }
        return emptyCount;
    }

}