跳至主要內容

🐲龙行大运呱呱乐,最高百万大奖等你来拿

Azil大约 4 分钟

前言

金鳞岂是池中物,一朝飞腾化巨龙, 新的一年展宏图,龙年开启新篇章

首先介绍一下“龙行大运”呱呱乐具体的游戏规则

  1. 彩票结构

    • 彩票刮开区设计为一个4行5列的格子矩阵,总共20个可刮开的格子。
  2. 刮开区内容

    • 每个格子内部上方会显示一个符号或奖项标签,可能是“ ”、“”、“”,或其他任意一个随机生成的两位数数字。
    • 每个格子下方则对应显示一个金额数值,该数值与上方符号或数字相关联。
    • 金额为固定的一组预选值(20,50,100,1000,10000,100000,200000,500000)
  3. 中奖规则

    • 刮刮乐游戏“龙行大运”的最高奖金为100万元人民币。
    • 每张彩票的下方都有一个刮开区,该区域覆盖着一系列的数字和可能的中奖金额。
  4. 中奖判定条件

    • 若刮开区中出现“”标志,获得该标志下方所显示的具体奖金数额。
    • 若刮开区中出现“”标志,获得该标志下方所示奖金数额的两倍。
    • 若刮开区中出现“”标志,一次性获得刮开区域内所有奖金数额之和。
  5. 题外话

    • 实物可前往体育彩票店购买,娱乐即可,切勿上头。

在线体验

可点击“龙行大运”重置刮奖全部刮开后,中奖金额会输出到控制台

点击链接试玩open in new window

开始码砖

经历了2023 AI元年,我们只需要整理游戏规则,剩下的交给AI去实现就行(实际体验极差)。

刮奖

重要知识点:

  1. canvas 宽高不固定,中奖区节点渲染完毕后再设置
  2. 在 canvas 还未设置宽高时,中奖区节点的内容是不可见的,不能使用 display:none; 那样无法确认宽高,这里我们应该使用 visibility: hidden;
  3. 鼠标在页面任意位置按下后,滑过 canvas 都需刮开鼠标指针区域
  4. 计算刮开区域达到多少比例后,自动清除 canvas 色块,使中奖区全部内容可见

搭建基础框架

根据游戏规则,先要生成一个 4*5 的矩阵数组存放奖区数据

/**
 * Start 代码来源于【通义千问】
 */
// 创建刮刮乐矩阵
function createScratchCardMatrix(row = 4, col = 5) {
  let matrix = [];
  for (let i = 0; i < row; i++) {
    matrix[i] = [];
    for (let j = 0; j < col; j++) {
      // 生成奖项
      const prizeInfo = generateRandomPrize();
      matrix[i][j] = {
          ...prizeInfo,
          money: generateRandomMoney(prizeInfo.isSpecial) // 根据奖项调整金额出现的概率
      };
    }
  }
  return matrix;
}

生成奖项

文心一言3.5模型真的很弱,经历了十几次对话,终于生成了一个还算看的过去的写法

// 定义一个用于生成随机奖项的方法
/**
 * Start 代码来源于【文心一言】
 * TODO: 大运奖最多允许出现一次
 * TODO: 龙珠奖最多允许出现二次
 */
 // 定义特殊标志及其对应中奖率
const specialSymbols = {
  '大运': 0.001, // 千分之一
  '龙珠': 0.05, // 百分之五
  '龙': 0.1, // 十分之一
};
function generateRandomPrize() {
  let randomValue = Math.random();
  let accumulatedRate = 0;
  for (let symbol in specialSymbols) {
    accumulatedRate += specialSymbols[symbol];
    if (randomValue <= accumulatedRate) {
      return {prize: symbol, isSpecial: true};
    }
  }
  // 如果没有抽中特殊标志,则随机生成一个数字奖项
  const randomDigitPrize = Math.floor(Math.random() * 99) + 10;
  return {prize: randomDigitPrize, isSpecial: false};
}
/**
 * End 代码来源于【文心一言】
 */

生成金额

AI只提供简易算法,更多的概率事件无法提供(也可能我不会跟它对话),反正还剩挺多待办事项的。

根据奖项,适当的调低中奖率

/**
 * Start 代码来源于【通义千问】
 * TODO: 超过1000的奖最多允许出现一次
 * TODO: 金额总面值不应超过一百万
 */
// 定义奖金
const normalPrizeValues = [500000, 200000, 100000, 1000, 100, 50, 20];
// 未出现特殊标志后奖金的出现概率
const normalPrizeProbabilities = [0.04, 0.06, 0.1, 0.15, 0.25, 0.4, 0];
// 出现特殊标志后奖金的出现概率
const specialPrizeProbabilities = [0.001, 0.002, 0.003, 0.004, 0.01, 0.34, 0.55];
// 定义一个用于生成金额的方法
function generateRandomMoney(isSpecial = false) {
    // 根据isSpecial选择正确的概率和值数组
    const probabilities = isSpecial ? specialPrizeProbabilities : normalPrizeProbabilities;
    // 确保概率之和等于1(或非常接近于1)
    if (Math.abs(probabilities.reduce((acc, prob) => acc + prob, 0) - 1) > Number.EPSILON) {
        return 50
    }
    let sum = 0;
    const cumulativeProbs = [];
    for (let i = 0; i < probabilities.length; i++) {
        sum += probabilities[i];
        cumulativeProbs.push(sum);
    }
    const randomNum = Math.random();
    let selectedIndex = cumulativeProbs.findIndex(prob => prob > randomNum);
    return normalPrizeValues[selectedIndex];
}

/**
 * End 代码来源于【通义千问】
 */

页面操作

后续就是根据自己的布局或者玩法去编码

  1. 根据矩阵数据渲染dom节点到页面
  2. 渲染完成后设置 canvas 宽高与颜色进行覆盖,作为刮奖图层
  3. 鼠标滑动时需考虑滚动条等因素
  4. 可参考上面的在线示例
上次编辑于:
贡献者: Azil