【问题标题】:Generate a random array in Javascript/jquery for Sudoku puzzle在 Javascript/jquery 中为数独拼图生成一个随机数组
【发布时间】:2016-01-04 06:05:56
【问题描述】:

我想通过处理以下条件来填充数组中的 9 x 9 网格

  1. 不应在同一列中重复特定数字。
  2. 特定数字不应在同一行中重复。

当我执行下面提到的代码时,它会在没有上述条件的情况下用随机值填充所有 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

【问题讨论】:

  • 能否在jsfiddle中添加html和Js
  • 我会说,也许你需要先用数据构建一个数组数组,也许null应该为空,然后在页面中创建元素会更容易。
  • @Filype “到目前为止你尝试过什么?”请参阅 OP 的 js
  • @guest271314 - 对,我想知道 OP 是否考虑过如何实现这一点,或者他不确定从哪里开始。
  • 是否需要填充每一行中的所有项目?

标签: javascript jquery arrays random


【解决方案1】:

为确保没有数字在一行中重复,您可能需要一个改组函数。对于列,您只需要以艰难的方式进行(检查以前的解决方案以查看该列上是否存在数字)。我希望我不会将行与列混淆,我经常这样做。

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

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

您可以遍历返回的二维数组,并填充数独框。如果您需要任何帮助,欢迎您

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}<br/>`;
      }
    }
  }
  return sudoku;
}

getSudoku()

【讨论】:

    【解决方案2】:

    生成和解决数独问题实际上并不像其他(错误)答案所暗示的那么简单,但这也不是火箭科学。我不想从 Wikipedia 复制和粘贴,而是将您指向 this question

    但是,由于只指向外部链接是不好的做法,我想通过至少让您直观地了解为什么幼稚的方法会失败来证明这一点。

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

    我希望这会有所帮助。

    【讨论】:

    • 谢谢,我删除了第二个。我想在写这篇文章的时候我还有一个,但是把它弄混了,不小心把同一个链接发了两次。
    【解决方案3】:

    您需要跟踪您之前插入的内容,如下一行:

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

    例如,您可以使用锯齿状数组(数组的数组,类似于二维数组)而不是您创建的“sudoku_array”来跟踪可用数字。实际上,您可以创建两个交错数组,一个用于列,一个用于行。由于您不跟踪之前插入的内容,因此数字是随机生成的。

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

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

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

    编辑:正如 Lex82 在 cmets 和他的回答中指出的那样,您还需要回溯以避免死胡同,或者您需要更深入地研究数学。我只是保留我的答案,以防它给你一个想法。

    【讨论】:

    • 不幸的是,这通常不起作用。您很容易陷入死胡同,下一个字段不可能有更多的数字。您将需要某种回溯。另见我的回答。
    • @lex82 是的,需要支持跟踪才能生成理想的解决方案。
    猜你喜欢
    • 2010-12-30
    • 2021-03-11
    • 1970-01-01
    • 2023-01-03
    • 2014-05-23
    • 2014-06-30
    • 2016-01-26
    • 2016-03-27
    • 2018-04-21
    相关资源
    最近更新 更多