as3 二维数组,随机数不会在行或列中产生 3 个

as3 2d array with random numbers that does not produce 3 of a kind in rows or columns

标题几乎概括了我的目标。我在业余时间制作 Candy Crush 克隆版。 table 是 7 行和 8 列,所以基本上是一个二维数组。 我想用 1-8 的随机数填充二维数组,以避免在行和列中出现 3、4、5 种。这是为了让首发table避免瞬间触发玩家积分的必要

到目前为止,处理二维数组的代码如下所示:(对其进行了调整,使其看起来不那么蹩脚)

    private function getRandomSequence(min:int=1, max:int=8):Vector.<uint>{
        var values:Vector.<uint>=new Vector.<uint>;
        for (var i:int = min; i <= max; i++) values.push(i);
        var result:Vector.<uint>=new Vector.<uint>;
        while (values.length > 0) result = result.concat(values.splice(Math.floor(Math.random() * values.length), 1));
        return result;
    }


    private function getRandomArr():Vector.<Vector.<uint>>{
        var j:uint=0;
        var i:uint=0;
        var multiArray:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>(7, true);
        for(j = 0; j < 7; j++) multiArray[j] = getRandomSequence(1,8);

        for(i = 0; j < 5; j++){
            for(j = 0; j < 8; j++){
                if(multiArray[i][j] == multiArray[i+1][j] == multiArray[i+2][j]){
                    //3 of a kind detected
                    while(multiArray[i][j] == multiArray[i+1][j]) multiArray[i][j] = main.mein.rng(1,8);
                }
            }
        }
        return multiArray;
    }

问题是第一个给你随机序列的函数避免了 3 种,是的,但它也避免了 2 种。需要进一步的测试来制作一个函数,该函数提供长度为 8 的可靠随机数序列,允许 2 种但不允许 3 种或更多。

有很多方法可以做到这一点,但为了简单起见,我建议这样做 - 正如我所说 - 'naive' 方式,非常简单:

  1. 用 1-8 之间的随机整数初始化数组
  2. 遍历数组,看看是否找到至少 3 个相同数字 水平
  3. 如果出现 3 次,请用 1-8 之间的新随机整数替换数组中的第三次出现,确保它与前两次出现的数字不同
  4. 遍历数组,看看是否找到至少 3 个相同数字垂直
  5. 如果出现 3 次,请用 1-8 之间的新随机整数替换数组中的第三次出现,确保它与前两次出现的数字不同
  6. 如果您必须在第 3 步或第 5 步替换数字,请返回到第 2 步 - 否则您就完成了

所以基本上你必须编写一个递归函数,只要水平或垂直出现三个数字,它就会调用自身。

下面是一个展示该想法的 Javascript 示例。只需点击 'Run code snippet' 按钮并查看显示清理前后数组的结果面板。

function checkGrid(arr) {
  var previousNumberr = -1;
  var counter = 0;
  var currentNumber = 0;
  var tempNumber = 0;
  var failed = false;
  for (var a = 0; a < arr.length; a++) {
    previousNumber = -1;
    counter = 0;
    for (var b = 0; b < arr[0].length; b++) {
      currentNumber = arr[a][b];
      if (currentNumber != previousNumber) {
        previousNumber = currentNumber;
        counter = 0;
      } else {
        counter++;
        if (counter == 2) {
          do {
            tempNumber = Math.ceil(Math.random() * maxNum)
          }
          while (tempNumber == currentNumber);
          arr[a][b] = tempNumber;
          failed = true;
        }
      }
    }
  }

  for (var c = 0; c < arr[0].length; c++) {
    previousNumber = -1;
    counter = 0;
    for (var d = 0; d < arr.length; d++) {
      currentNumber = arr[d][c];
      if (currentNumber != previousNumber) {
        previousNumber = currentNumber;
        counter = 0;
      } else {
        counter++;
        if (counter == 2) {
          do {
            tempNumber = Math.ceil(Math.random() * maxNum)
          }
          while (tempNumber == currentNumber);
          arr[d][c] = tempNumber;
          failed = true;
        }
      }
    }
  }

  if (failed) {
    checkGrid(arr);
  }
}

var rows = 7;
var columns = 8;
var maxNum = 8;

var grid = new Array(
  new Array(2, 6, 8, 4, 8, 5, 8),
  new Array(4, 6, 7, 2, 4, 6, 4),
  new Array(1, 6, 2, 4, 4, 2, 7),
  new Array(5, 1, 1, 1, 8, 6, 3),
  new Array(5, 8, 1, 5, 4, 5, 6),
  new Array(1, 1, 1, 5, 7, 7, 7),
  new Array(6, 3, 3, 1, 2, 1, 3),
  new Array(2, 2, 7, 1, 8, 2, 7)
);
for (var a = 0; a < columns; a++) {
  console.log(grid[a].toString());
}
console.log("");
console.log("cleaning");
console.log("");
checkGrid(grid);
for (var b = 0; b < columns; b++) {
  console.log(grid[b].toString());
}