我一直在尝试制作一个使用Javascript随机创建Sudoku的程序。我在Atom中同时包含了代码和该代码的图片,以使其更具可读性。

基本上从16-20行开始,我在行中添加了9个数字,然后将它们混洗并将结果存储在newRow中。

从第25行开始,我开始一个循环,遍历所有过去的行,这些行存储在名为“ actualRow”的数组中。因此,将行改组为newRow,将newRow存储在actualRow中。从第二个newRow开始,我要检查是否有重复的值。这就是为什么我启动loop1和loop2的原因。 Loop1遍历所有先前的行,而其中的loop2遍历所有值。

if语句旨在捕获重复项,但永远不会求值为true,显然应该这样做,因为总是有很多重复项。如果为true,则error = true,因此我不会在实际行中添加特定的newRow ,但请重新开始循环,直到没有重复为止。

因此,真正的问题出在第32行的if语句中。我在这里错过了什么?



  <script>
    var row = [];
    var newRow = [];
    var actualRow = [];
    var mistake;

function makeSudoku() {
  for (var j = 0; j < 9; j++) {
    row = [1,2,3,4,5,6,7,8,9];
    newRow = [];
    mistake = false;

    for (var i = 1; i < 10; i++) {
      newRow.push( row.splice( Math.floor( Math.random() * row.length) , 1) );
    }

    if ( j !== 0) { // no need to check for duplicates in first row

      loop1:
      for (var k = j-1; k > -1 ; k--) { // for every row that came before..
        loop2:
        for (var l = 0; l < 9; l++) { // for every value in that row..
          if ( actualRow[j-1][l] == newRow[l] ) { // issue here!!!
            mistake = true;
            console.log("duplicate row value");
          } else {
            console.log("Why does this if statement always evaluate to else?");
          }
        }
      }
    }

    if ( mistake == false) {
      actualRow.push(newRow);
    } else if ( mistake == true) {
      j -= 1;
    } else {
    }
}

console.log(actualRow);
}

makeSudoku();




javascript - 我的if语句返回了意外的结果,使用Javascript生成了随机数独-LMLPHP

javascript - 我的if语句返回了意外的结果,使用Javascript生成了随机数独-LMLPHP

最佳答案

您的主要问题在于此行:

  newRow.push( row.splice( Math.floor( Math.random() * row.length) , 1) );


这将构建一个数组,但不是数字数组,而是一个单元素数组!以后进行比较时,总会得出false,并说明了为什么总是进入else部分。

原因在于splice方法的工作方式。即使仅提取一个元素,它也会返回一个数组。解决方案是,从您从splice获得的数组中“解包”值:

  newRow.push( row.splice( Math.floor( Math.random() * row.length) , 1)[0] );


现在可以使用,但是请注意您的算法效率很低。生成最后一行时,将需要进行多次尝试才能使其正确,因为最后一行仅允许一个排列。这使您的代码迭代了数千次,试图通过纯随机改组使其正确。

10-06 04:33