🐲龙行大运呱呱乐,最高百万大奖等你来拿
大约 4 分钟
前言
金鳞岂是池中物,一朝飞腾化巨龙, 新的一年展宏图,龙年开启新篇章
首先介绍一下“龙行大运”呱呱乐具体的游戏规则
彩票结构
- 彩票刮开区设计为一个4行5列的格子矩阵,总共20个可刮开的格子。
刮开区内容
- 每个格子内部上方会显示一个符号或奖项标签,可能是“ ”、“”、“”,或其他任意一个随机生成的两位数数字。
- 每个格子下方则对应显示一个金额数值,该数值与上方符号或数字相关联。
- 金额为固定的一组预选值(20,50,100,1000,10000,100000,200000,500000)
中奖规则
- 刮刮乐游戏“龙行大运”的最高奖金为100万元人民币。
- 每张彩票的下方都有一个刮开区,该区域覆盖着一系列的数字和可能的中奖金额。
中奖判定条件
- 若刮开区中出现“”标志,获得该标志下方所显示的具体奖金数额。
- 若刮开区中出现“”标志,获得该标志下方所示奖金数额的两倍。
- 若刮开区中出现“”标志,一次性获得刮开区域内所有奖金数额之和。
题外话
- 实物可前往体育彩票店购买,娱乐即可,切勿上头。
在线体验
可点击“龙行大运”重置刮奖全部刮开后,中奖金额会输出到控制台
点击链接试玩
开始码砖
经历了2023 AI元年,我们只需要整理游戏规则,剩下的交给AI去实现就行(实际体验极差)。
刮奖
重要知识点:
canvas 宽高不固定,中奖区节点渲染完毕后再设置
在 canvas 还未设置宽高时,中奖区节点的内容是不可见的,不能使用 display:none; 那样无法确认宽高,这里我们应该使用 visibility: hidden;
鼠标在页面任意位置按下后,滑过 canvas 都需刮开鼠标指针区域
计算刮开区域达到多少比例后,自动清除 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 代码来源于【通义千问】
*/
页面操作
后续就是根据自己的布局或者玩法去编码
- 根据矩阵数据渲染dom节点到页面
- 渲染完成后设置 canvas 宽高与颜色进行覆盖,作为刮奖图层
- 鼠标滑动时需考虑滚动条等因素
- 可参考上面的在线示例