我想制作一个应用程序,它将选择 1 到 9 中的值,并遵循一些规则 In javascript
I want to make an application that will choose the values from 1 to 9 follow by some rules In javascript
我想制作一个应用程序,它会按照 javascript 中的一些规则(例如制作 9 位数独)选择 1 到 9 之间的值。
这是我的代码:
//This doesn't work anymore and only return value for xyz for once or return the same value every time.
var xyz = [];
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
var xy = arrays.length
setInterval(function() {
while (xy > 0) {
var x = Math.floor(Math.random() * xy)
xyz.push(arrays[x])
arrays.splice(x, 1);
xy = xy - 1;
console.log(xyz)
}
if (xyz[0] + xyz[1] + xyz[2] !== 15 && xyz[1] + xyz[4] + xyz[7] !== 15 &&
xyz[2] + xyz[5] + xyz[8] !== 15) {
xyz.length = 0;
arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
xy = arrays.length
}
if (xyz[0] + xyz[1] + xyz[2] == 15 && xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15) {
alert('it works!!!')
}
}, 100);
我也尝试让 xyz[0]+xyz[1]+xyz[2] == 15 && xyz[1]+xyz[4]+xyz[7] == 15 &&xyz[2]+xyz[5]+xyz[8] == 15
成为 while
循环的条件,但页面将继续加载并且不再工作。
有谁知道如何使它们工作或谁知道更好的算法?
您的条件表述不当。布尔表达式 A and B and C
的反面不是 not A and not B and not C
,而是 not A or not B or not C
.
此外,你只需要检查一个布尔表达式:使用else
来捕获相反的情况。
最后,成功后清空计时器。
这是一个更正,其中包括输出到控制台的尝试次数(不要使用 alert
):
var xyz = [];
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var xy = arrays.length;
var attempts = 1;
var timer = setInterval(function() {
console.log("attempt", attempts++);
while (xy > 0) {
var x = Math.floor(Math.random() * xy);
xyz.push(arrays[x]);
arrays.splice(x, 1);
xy = xy - 1;
}
if (xyz[0] + xyz[1] + xyz[2] !== 15 || xyz[1] + xyz[4] + xyz[7] !== 15 ||
xyz[2] + xyz[5] + xyz[8] !== 15) {
xyz.length = 0;
arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
xy = arrays.length;
} else {
clearInterval(timer);
console.log('it works!!!');
}
}, 50);
如果您的目的是用数字 1..9 创建一个 3x3 magic square,那么可能性就不多了。它们都是基于这种模式:
8 1 6
3 5 7
4 9 2
图案可以镜像and/or转动,共有8种解法可供选择。对 8 个解决方案进行硬编码并随机选择一个可能是最简单的方法:
let solutions = [
[8,1,6,3,5,7,4,9,2],
[8,3,4,1,5,9,6,7,2],
[4,3,8,9,5,1,2,7,6],
[4,9,2,3,5,7,8,1,6],
[2,9,4,7,5,3,6,1,8],
[2,7,6,9,5,1,4,3,8],
[6,7,2,1,5,9,8,3,4],
[6,1,8,7,5,3,2,9,4]
];
let solution = solutions[Math.floor(Math.random()*8)];
console.log(solution);
如果你制作更小的组件,它将是干的并且更容易测试
不需要间隔
尽可能避免否定
测试
=== 15 && === 15 && === 15
比
更容易阅读和理解
!== 15 || !== 15 || !== 15
const getXYZ = () => {
let xyz = [];
let arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let xy = arrays.length
// setInterval(function() {
while (xy > 0) {
let x = Math.floor(Math.random() * xy)
xyz.push(arrays[x])
arrays.splice(x, 1);
xy = xy - 1;
}
return xyz
};
let done = false;
while (!done) {
const xyz = getXYZ()
if (xyz[0] + xyz[1] + xyz[2] == 15 &&
xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15) {
console.log('it works!!!',xyz)
done = true;
}
}
使用 Fisher-Yates 更快的随机数:
const fy = (a,b,c,d) => { c=a.length;while(c)b=Math.random()*(--c+1)|0,d=a[c],a[c]=a[b],a[b]=d }
const getXYZ = () => {
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
fy(arr)
return arr
}
let done = false;
while (!done) {
const xyz = getXYZ()
if (xyz[0] + xyz[1] + xyz[2] == 15 &&
xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15) {
console.log('it works!!!',xyz)
done = true;
}
}
另一种可能方便的方法:
//This will fill array from 1 to 9 randomly and unique
function shuffle(array) {
var tmp,
current,
top = array.length;
if (top)
while (--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
return array;
}
//one simple algorithm of getting XYZ
function getXYZ(arrays) {
var itWorks = false;
while (!itWorks) {
xyz = shuffle(arrays);
if (
xyz[0] + xyz[1] + xyz[2] == 15 &&
xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15
) {
itWorks = true;
return xyz;
}
}
}
//Test
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var xys = getXYZ(arrays);
console.log("It works! " + xys);
我想制作一个应用程序,它会按照 javascript 中的一些规则(例如制作 9 位数独)选择 1 到 9 之间的值。
这是我的代码:
//This doesn't work anymore and only return value for xyz for once or return the same value every time.
var xyz = [];
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
var xy = arrays.length
setInterval(function() {
while (xy > 0) {
var x = Math.floor(Math.random() * xy)
xyz.push(arrays[x])
arrays.splice(x, 1);
xy = xy - 1;
console.log(xyz)
}
if (xyz[0] + xyz[1] + xyz[2] !== 15 && xyz[1] + xyz[4] + xyz[7] !== 15 &&
xyz[2] + xyz[5] + xyz[8] !== 15) {
xyz.length = 0;
arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
xy = arrays.length
}
if (xyz[0] + xyz[1] + xyz[2] == 15 && xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15) {
alert('it works!!!')
}
}, 100);
我也尝试让 xyz[0]+xyz[1]+xyz[2] == 15 && xyz[1]+xyz[4]+xyz[7] == 15 &&xyz[2]+xyz[5]+xyz[8] == 15
成为 while
循环的条件,但页面将继续加载并且不再工作。
有谁知道如何使它们工作或谁知道更好的算法?
您的条件表述不当。布尔表达式 A and B and C
的反面不是 not A and not B and not C
,而是 not A or not B or not C
.
此外,你只需要检查一个布尔表达式:使用else
来捕获相反的情况。
最后,成功后清空计时器。
这是一个更正,其中包括输出到控制台的尝试次数(不要使用 alert
):
var xyz = [];
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var xy = arrays.length;
var attempts = 1;
var timer = setInterval(function() {
console.log("attempt", attempts++);
while (xy > 0) {
var x = Math.floor(Math.random() * xy);
xyz.push(arrays[x]);
arrays.splice(x, 1);
xy = xy - 1;
}
if (xyz[0] + xyz[1] + xyz[2] !== 15 || xyz[1] + xyz[4] + xyz[7] !== 15 ||
xyz[2] + xyz[5] + xyz[8] !== 15) {
xyz.length = 0;
arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
xy = arrays.length;
} else {
clearInterval(timer);
console.log('it works!!!');
}
}, 50);
如果您的目的是用数字 1..9 创建一个 3x3 magic square,那么可能性就不多了。它们都是基于这种模式:
8 1 6
3 5 7
4 9 2
图案可以镜像and/or转动,共有8种解法可供选择。对 8 个解决方案进行硬编码并随机选择一个可能是最简单的方法:
let solutions = [
[8,1,6,3,5,7,4,9,2],
[8,3,4,1,5,9,6,7,2],
[4,3,8,9,5,1,2,7,6],
[4,9,2,3,5,7,8,1,6],
[2,9,4,7,5,3,6,1,8],
[2,7,6,9,5,1,4,3,8],
[6,7,2,1,5,9,8,3,4],
[6,1,8,7,5,3,2,9,4]
];
let solution = solutions[Math.floor(Math.random()*8)];
console.log(solution);
如果你制作更小的组件,它将是干的并且更容易测试
不需要间隔
尽可能避免否定
测试
=== 15 && === 15 && === 15
比
更容易阅读和理解
!== 15 || !== 15 || !== 15
const getXYZ = () => {
let xyz = [];
let arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let xy = arrays.length
// setInterval(function() {
while (xy > 0) {
let x = Math.floor(Math.random() * xy)
xyz.push(arrays[x])
arrays.splice(x, 1);
xy = xy - 1;
}
return xyz
};
let done = false;
while (!done) {
const xyz = getXYZ()
if (xyz[0] + xyz[1] + xyz[2] == 15 &&
xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15) {
console.log('it works!!!',xyz)
done = true;
}
}
使用 Fisher-Yates 更快的随机数:
const fy = (a,b,c,d) => { c=a.length;while(c)b=Math.random()*(--c+1)|0,d=a[c],a[c]=a[b],a[b]=d }
const getXYZ = () => {
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
fy(arr)
return arr
}
let done = false;
while (!done) {
const xyz = getXYZ()
if (xyz[0] + xyz[1] + xyz[2] == 15 &&
xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15) {
console.log('it works!!!',xyz)
done = true;
}
}
另一种可能方便的方法:
//This will fill array from 1 to 9 randomly and unique
function shuffle(array) {
var tmp,
current,
top = array.length;
if (top)
while (--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
return array;
}
//one simple algorithm of getting XYZ
function getXYZ(arrays) {
var itWorks = false;
while (!itWorks) {
xyz = shuffle(arrays);
if (
xyz[0] + xyz[1] + xyz[2] == 15 &&
xyz[1] + xyz[4] + xyz[7] == 15 &&
xyz[2] + xyz[5] + xyz[8] == 15
) {
itWorks = true;
return xyz;
}
}
}
//Test
var arrays = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var xys = getXYZ(arrays);
console.log("It works! " + xys);