我一直在尝试制作一个使用 Javascript 随机创建数独的程序。我已将代码和该代码的图片包含在 Atom 中,以使其更具可读性。
基本上,从第 16-20 行开始,我将 9 个数字添加到 row 中,然后将它们打乱并将结果存储在 newRow 中。
从第 25 行开始,我开始一个循环,遍历所有过去的行,这些行存储在名为“actualRow”的数组中。因此 row 被混入 newRow,newRow 存储在actualRow 中。从第二个 newRow 开始,我想检查是否有重复值。这就是我启动loop1和loop2的原因。 Loop1 循环遍历之前的所有行,loop2 循环遍历所有值。
if 语句的目的是捕获重复项,但永远不会计算为 true,这显然应该是这样,因为总是有很多重复项。如果它是 true,则错误 = true,因此我不会添加该特定的newRow 到actualRow,但重新开始循环,直到不遇到重复项。
所以问题实际上出在第 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();
最佳答案
您的主要问题在这一行:
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] );
现在它可以工作了,但要注意你的算法效率非常低。生成最后一行时,需要多次尝试才能正确,因为最后一行中只允许一个排列。这使得您的代码迭代数千次,试图通过纯随机洗牌来使其正确。
关于javascript - 我的 if 语句返回意外结果,用 Javascript 制作随机数独,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39318976/