在Javascript/jquery中为数独游戏生成随机数组

在Javascript/jquery中为数独游戏生成随机数组,javascript,jquery,arrays,random,Javascript,Jquery,Arrays,Random,我希望通过考虑以下条件从阵列填充9 x 9网格 特定数字不应在同一列中重复 同一行中不应重复特定的数字 当我执行下面提到的代码时,它会用没有上面提到的条件的随机值填充所有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[

我希望通过考虑以下条件从阵列填充9 x 9网格

  • 特定数字不应在同一列中重复
  • 同一行中不应重复特定的数字
  • 当我执行下面提到的代码时,它会用没有上面提到的条件的随机值填充所有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)]);
    
    });
    

    您需要跟踪您之前插入的内容,以便执行以下命令:

     $(this).val(sudoku_array[Math.floor(Math.random()*sudoku_array.length)]);
    
    例如,您可以使用一个锯齿状数组(数组的数组,类似于二维数组),而不是您为跟踪可用数字而创建的“数独数组”。实际上,您可以创建两个锯齿状数组,一个用于列,一个用于行。由于您不跟踪以前插入的内容,因此会随机生成数字

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

    • 生成编号后,将其从锯齿状数组的相应行和列中删除,以将其标记为对这些行和列不可用
    • 在创建任何数字之前,请检查它是否在锯齿数组中可用(同时检查列和行)。如果不可用,请尝试其他号码
    注意:您可以将生成的随机数限制减少为可用数。如果您这样做,您生成的随机数x将意味着该单元格的第x个可用数。这样,您就不会得到一个不可用的数字,因此它的工作速度要快得多


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

    生成和解决数独游戏实际上并不像其他(错误的)答案那样简单,但它也不是火箭科学。我想告诉你的不是从维基百科上复制和粘贴

    然而,由于仅仅指向外部链接是一种不好的做法,我想通过至少为您提供一种直觉来证明这一点,为什么天真的方法会失败

    如果你开始生成一个数独棋盘,用随机数填充一些字段(从而考虑到你的限制),你会得到一个部分填充的棋盘。完成它相当于解决一个数独游戏,它只不过是通过遵守数独规则完成一个部分填充的棋盘。如果您曾经尝试过,您将知道,如果您仅针对3x3框、列和行选择一个有效数字来决定下一个数字,那么这是不可能的。除了最简单的数独游戏外,所有数独游戏都有一些尝试和错误,因此需要一种回溯形式


    我希望这有帮助

    为了确保一行中没有重复的数字,您可能需要一个洗牌功能。对于列,您只需以艰难的方式进行操作(检查以前的解决方案,查看该列上是否存在数字)。我希望我没有把行和列混淆,我经常这样做

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

    这段代码需要一段时间,但它可以完成这项工作

    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;
    }
    
    Array.prototype.shuffle=函数(){
    var arr=this.valueOf();
    var-ret=[];
    而(返回长度<到达长度){
    var x=arr[Math.floor(Number(Math.random()*arr.length));
    如果(!(返回索引of(x)>=0))返回推送(x);
    }
    返回ret;
    }
    函数getSudoku(){
    var数独=[];
    var-arr=[1,2,3,4,5,6,7,8,9];
    数独推(arr);
    对于(变量i=1;i<9;i++){
    
    while(sudoku.length)能否请您将html和Js添加到JSFIDDLE中?我想说的是,您可能需要首先使用数据构建一个数组,也许
    null
    应该为null的位置,然后在页面中创建元素会更容易。@fitype“到目前为止您做了哪些尝试?”请参见OP@guest271314-是的,我想知道OP是否考虑过如何实现这一点,或者他是否不确定从何处开始。您是否需要填充每行中的所有项目?不幸的是,这通常不起作用。您可能很容易陷入死胡同,下一个字段不可能有更多的数字。您需要某种回溯。另请参见我的答案。@lex82是的,为了生成理想的解决方案,需要回溯。谢谢,我删除了第二个。我想在撰写本文时,我有另一个回溯,但混淆了它,并意外地发布了两次相同的链接。