You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中实现符合规则的刮刮卡生成算法?

问题修复:生成符合规则的刮刮卡矩阵

现有代码的核心问题

  1. findNumberCount函数存在拼写错误:matris应为matrix,导致数字计数完全失效
  2. create3x3Matrix的选号逻辑错误:当前条件仅在「已有中奖数字且目标数字计数≥3」时才重新选号,会出现数字超过3次、多个中奖数字的违规情况
  3. findWinningNumber遍历列时逻辑错误:使用matrix.length而非matrix[i].length,非方阵场景会漏统计/越界,且未校验是否存在多个中奖数字

修复后的完整代码

exports.scratchCard = async (req, res) => {
  let numArray = [5, 10, 20, 40, 100, 5, 5, 10, 5, 20, 5, 40];
  let matrix = create3x3Matrix(numArray);

  console.log("Matrix:", matrix);
  let winningNumber = findWinningNumber(matrix);
  console.log("Winning Number:", winningNumber);
  
  return res.json({ matrix, winningNumber });
};

function create3x3Matrix(numArray) {
  let matrix = [];
  let numberCounts = {}; // 实时维护数字出现次数,避免重复遍历矩阵

  for (let i = 0; i < 3; i++) {
    let row = [];
    for (let j = 0; j < 3; j++) {
      let randomNumber;
      let isValid = false;

      while (!isValid) {
        let randomIndex = Math.floor(Math.random() * numArray.length);
        randomNumber = numArray[randomIndex];
        const currentCount = numberCounts[randomNumber] || 0;
        const hasWinningNum = Object.values(numberCounts).some(count => count === 3);

        // 规则校验:
        // 1. 已有中奖数字时,其他数字最多出现1次(避免新增后达到3次,产生第二个中奖数字)
        // 2. 无中奖数字时,所有数字最多出现2次(避免超过3次)
        isValid = hasWinningNum ? currentCount < 2 : currentCount < 3;
      }

      numberCounts[randomNumber] = (numberCounts[randomNumber] || 0) + 1;
      row.push(randomNumber);
    }
    matrix.push(row);
  }

  return matrix;
}

function findNumberCount(matrix, searchingNumber) {
  let count = 0;
  for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
      if (matrix[i][j] === searchingNumber) {
        count++;
      }
    }
  }
  return count;
}

function findWinningNumber(matrix) {
  let numberCounts = {};
  for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
      let number = matrix[i][j];
      numberCounts[number] = (numberCounts[number] || 0) + 1;
    }
  }

  let winningNumbers = [];
  for (let number in numberCounts) {
    if (numberCounts[number] === 3) {
      winningNumbers.push(Number(number));
    }
  }

  // 按规则最多一个中奖数字,返回第一个或undefined
  return winningNumbers.length > 0 ? winningNumbers[0] : undefined;
}

关键修复点说明

  1. 实时计数优化:在矩阵生成时维护numberCounts对象,避免每次选号都遍历整个矩阵,提升效率
  2. 严格规则校验:
    • 已有中奖数字时,禁止任何数字出现次数接近3次,避免产生第二个中奖数字
    • 无中奖数字时,禁止任何数字出现超过2次,避免出现4次及以上的违规情况
  3. 遍历逻辑修复:findWinningNumber中使用matrix[i].length遍历列,适配非方阵场景(如4x3)
  4. 类型修正:将中奖数字转为Number类型,避免返回字符串格式

修复后的代码生成的矩阵将严格遵守规则:无数字出现超过3次,最多一个中奖数字,允许无中奖情况。

内容的提问来源于stack exchange,提问作者resobyte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:10:31