在Javascript / jquery中为Sudoku难题生成随机数组

时间:2015-10-07 06:10:49

标签: javascript jquery arrays random

我希望通过处理以下条件来填充阵列中的9 x 9网格

  1. 不应在同一列中重复特定的数字。
  2. 不应在同一行重复特定的数字。
  3. 当我执行下面提到的代码时,它会在没有上述条件的情况下用随机值填充所有9 X 9网格。如何在将值插入到我的9 X 9网格之前添加这两个条件。

    var sudoku_array = ['1','2','3','4','6','5','7','8','9'];
    
    $('.smallbox input').each(function(index) {
        $(this).val(sudoku_array[Math.floor(Math.random()*sudoku_array.length)]);
    
    });
    

    My JSFIDDLE LINK

3 个答案:

答案 0 :(得分:3)

生成和解决Sudokus实际上并不像其他(错误的)答案那样简单,但它也不是火箭科学。我不想复制和粘贴维基百科,而是指向this question

然而,由于仅仅指向外部链接是不好的做法,我想通过向你提供直觉为什么天真的方法失败来证明它是正确的。

如果您通过使用随机数填充某些字段(从而考虑到您的约束)来开始生成数独板,则会获得部分填充的板。完成它就相当于解决一个数独,这只不过是通过遵守数独规则来完成部分填充的棋盘。如果您曾经尝试过,如果您仅通过选择3x3框,列和行选择有效数字来决定下一个数字,您就会知道这是不可能的。除了最简单的Sudokus之外,还有一些试验和错误,所以你需要一种回溯形式。

我希望这会有所帮助。

答案 1 :(得分:2)

要确保一行中不重复任何数字,您可能需要一个随机播放功能。对于列,您只需要艰难地完成它(检查以前的解决方案以查看该列上是否存在数字)。我希望我不会混淆列的行,我倾向于做很多。

它类似于进化计算中的八个皇后问题。回溯,纯随机游走或进化解决方案可以解决问题。

此代码需要一段时间,但它会完成这项工作。

Array.prototype.shuffle = function () {
    var arr = this.valueOf();
    var ret = [];
    while (ret.length < arr.length) {
       var x = arr[Math.floor(Number(Math.random() * arr.length))];
       if (!(ret.indexOf(x) >= 0)) ret.push(x);
    }
    return ret;
}

function getSudoku() {
   var sudoku = [];
   var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
   sudoku.push(arr);
   for (var i = 1; i < 9; i++) {

      while (sudoku.length <= i) {
        var newarr = arr.shuffle();
        var b = false;
        for (var j = 0; j < arr.length; j++) {
            for (var k = 0; k < i; k++) {
                if (sudoku[k].indexOf(newarr[j]) == j) b = true;
            }

        }
        if (!b) {
            sudoku.push(newarr);
            document.body.innerHTML += newarr;
        }
     }
  }
  return sudoku;
}

您现在可以遍历返回的二维数组,并填充数独框。霍拉,如果你需要任何帮助

答案 2 :(得分:0)

您需要跟踪之前插入的内容,对于以下行:

 $(this).val(sudoku_array[Math.floor(Math.random()*sudoku_array.length)]);

例如,你可以有一个锯齿状数组(数组数组,它​​就像一个二维数组),而不是“数独数组”。您已创建以跟踪可用数字。实际上,您可以创建两个锯齿状数组,一个用于列,另一个用于行。由于您没有跟踪之前插入的内容,因此会随机生成数字。

创建保留可用数字的数组后,执行以下操作:

  • 生成数字后,将其从锯齿状阵列的相应行和列中删除,以标记它们对于那些行和列不可用。
  • 在创建任何数字之前,检查它是否在锯齿状数组中可用(检查列和行)。如果没有,请尝试使用其他号码。

注意:您可以将生成的随机数限制减少到可用数字。如果这样做,您生成的随机数x将表示该单元格的第x个可用数字。这样你就不会得到一个不可用的数字,因此它的工作速度要快得多。

编辑:正如Lex82在评论和答案中指出的那样,你还需要回溯以避免死路,或者你需要更深入地学习数学。我会保留我的答案,以防它给你一个想法。