我想制作一个应用程序,它将选择 1 到 9 中的值,并遵循一些规则 In javascript

I want to make an application that will choose the values from 1 to 9 follow by some rules In javascript

我想制作一个应用程序,它会按照 javascript 中的一些规则(例如制作 9 位数独)选择 1 到 9 之间的值。

这是我的代码:

//This doesn't work anymore and only return value for xyz for once or return the same value every time.
var xyz = [];
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
var xy = arrays.length
setInterval(function() {
  while (xy > 0) {
    var x = Math.floor(Math.random() * xy)
    xyz.push(arrays[x])
    arrays.splice(x, 1);
    xy = xy - 1;
    console.log(xyz)
  }
  if (xyz[0] + xyz[1] + xyz[2] !== 15 && xyz[1] + xyz[4] + xyz[7] !== 15 &&
    xyz[2] + xyz[5] + xyz[8] !== 15) {
    xyz.length = 0;
    arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    xy = arrays.length
  }
  if (xyz[0] + xyz[1] + xyz[2] == 15 && xyz[1] + xyz[4] + xyz[7] == 15 &&
    xyz[2] + xyz[5] + xyz[8] == 15) {
    alert('it works!!!')
  }
}, 100);

我也尝试让 xyz[0]+xyz[1]+xyz[2] == 15 && xyz[1]+xyz[4]+xyz[7] == 15 &&xyz[2]+xyz[5]+xyz[8] == 15 成为 while 循环的条件,但页面将继续加载并且不再工作。

有谁知道如何使它们工作或谁知道更好的算法?

您的条件表述不当。布尔表达式 A and B and C 的反面不是 not A and not B and not C,而是 not A or not B or not C.

此外,你只需要检查一个布尔表达式:使用else来捕获相反的情况。

最后,成功后清空计时器。

这是一个更正,其中包括输出到控制台的尝试次数(不要使用 alert):

var xyz = [];
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var xy = arrays.length;
var attempts = 1;
var timer = setInterval(function() {
  console.log("attempt", attempts++);
  while (xy > 0) {
    var x = Math.floor(Math.random() * xy);
    xyz.push(arrays[x]);
    arrays.splice(x, 1);
    xy = xy - 1;
  }
  if (xyz[0] + xyz[1] + xyz[2] !== 15 || xyz[1] + xyz[4] + xyz[7] !== 15 ||
    xyz[2] + xyz[5] + xyz[8] !== 15) {
    xyz.length = 0;
    arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    xy = arrays.length;
  } else {
    clearInterval(timer);
    console.log('it works!!!');
  }
}, 50);

如果您的目的是用数字 1..9 创建一个 3x3 magic square,那么可能性就不多了。它们都是基于这种模式:

    8 1 6
    3 5 7
    4 9 2

图案可以镜像and/or转动,共有8种解法可供选择。对 8 个解决方案进行硬编码并随机选择一个可能是最简单的方法:

let solutions = [
    [8,1,6,3,5,7,4,9,2],
    [8,3,4,1,5,9,6,7,2],
    [4,3,8,9,5,1,2,7,6],
    [4,9,2,3,5,7,8,1,6],
    [2,9,4,7,5,3,6,1,8],
    [2,7,6,9,5,1,4,3,8],
    [6,7,2,1,5,9,8,3,4],
    [6,1,8,7,5,3,2,9,4]
];

let solution = solutions[Math.floor(Math.random()*8)];
console.log(solution);

如果你制作更小的组件,它将是干的并且更容易测试

不需要间隔

尽可能避免否定

测试
=== 15 && === 15 && === 15
更容易阅读和理解 !== 15 || !== 15 || !== 15

const getXYZ = () => {
  let xyz = [];
  let  arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
  let xy = arrays.length
  // setInterval(function() {
  while (xy > 0) {
    let x = Math.floor(Math.random() * xy)
    xyz.push(arrays[x])
    arrays.splice(x, 1);
    xy = xy - 1;
  }
  return xyz
};

let done = false; 
while (!done) {
  const xyz = getXYZ()
  if (xyz[0] + xyz[1] + xyz[2] == 15 &&
      xyz[1] + xyz[4] + xyz[7] == 15 &&
      xyz[2] + xyz[5] + xyz[8] == 15) {
    console.log('it works!!!',xyz)
    done = true;
  }
}

使用 Fisher-Yates 更快的随机数:

const fy = (a,b,c,d) => { c=a.length;while(c)b=Math.random()*(--c+1)|0,d=a[c],a[c]=a[b],a[b]=d }


const getXYZ = () => {
  let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  fy(arr)
  return arr
}

let done = false; 
while (!done) {
  const xyz = getXYZ()
  if (xyz[0] + xyz[1] + xyz[2] == 15 &&
      xyz[1] + xyz[4] + xyz[7] == 15 &&
      xyz[2] + xyz[5] + xyz[8] == 15) {
    console.log('it works!!!',xyz)
    done = true;
  }
}

另一种可能方便的方法:

//This will fill array from 1 to 9 randomly and unique
function shuffle(array) {
  var tmp,
    current,
    top = array.length;
  if (top)
    while (--top) {
      current = Math.floor(Math.random() * (top + 1));
      tmp = array[current];
      array[current] = array[top];
      array[top] = tmp;
    }
  return array;
}

//one simple algorithm of getting XYZ
function getXYZ(arrays) {
  var itWorks = false;

  while (!itWorks) {
    xyz = shuffle(arrays);
    if (
      xyz[0] + xyz[1] + xyz[2] == 15 &&
      xyz[1] + xyz[4] + xyz[7] == 15 &&
      xyz[2] + xyz[5] + xyz[8] == 15
    ) {
      itWorks = true;
      return xyz;
    }
  }
}

//Test
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var xys = getXYZ(arrays);
console.log("It works! " + xys);