Minmax JavaScript algorithm return console error Uncaught TypeError: Cannot read property 'cost' of undefined
Minmax JavaScript algorithm return console error Uncaught TypeError: Cannot read property 'cost' of undefined
我正在使用 JavaScrip 开发井字游戏。当我调用 MinMax 函数时,我得到错误的日志序列。在这里,我调用了 minmax 函数,据我所知,我分配的值是正确的。
const value = minmax(gridCopy, depth+1, ((player===PLAYER_TOKEN)?COMPUTER_TOKEN:PLAYER_TOKEN));
我在控制台中遇到错误
main.js:86 Uncaught TypeError: Cannot read property 'cost' of undefined
at minmax (main.js:86)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at computerMove (main.js:120)
如果你想看看我的完整功能,这里是代码。
function minmax(newGrid, depth, player) {
const gameState= gameOver(newGrid);
if(gameState === false) {
const values= [];
for (var i=0; i<3; i++) {
for (var j = 0; j<3;j++){
const gridCopy = _.cloneDeep(newGrid);
if (gridCopy[i][j]!=='') continue;
gridCopy[i][j]=player;
const value = minmax(gridCopy, depth+1, ((player===PLAYER_TOKEN)?COMPUTER_TOKEN:PLAYER_TOKEN));
values.push({
cost:value,
cell: {
i:i,
j:j
}
});
}
}
if (player === COMPUTER_TOKEN) {
const max = _.maxBy(values, (v) => {
return v.cost;
});
if (depth === 0) {
return max.cell;
}
else {
return max.cost;
}
}
else {
const min = _.minBy(values, (v) => {
return v.cost;
});
if (depth === 0) {
return min.cell;
}
else {
return min.cost;
}
}
}else if (gameState === null){
return 0;
}
else if (gameState===PLAYER_TOKEN) {
return depth - 10;
}
else if (gameState===COMPUTER_TOKEN) {
return 10 - depth;
}
}
function computerMove(){
return minmax(grid,0,COMPUTER_TOKEN);
}
这里link 完成项目
我认为这里的错误是你的递归函数。您正在调用 minmax
九次,当 depth
最终达到 8 时,它应该解析它的值,但它不能,因为值是根据永远不会填充的 values
数组计算的。并使用空 values
数组调用 .min/.max 方法得到结果。
最内部的递归调用应该从常量或其他东西而不是某些依赖于递归函数本身的变量 (values
) 解析其 return 值。
所以在我看来 minmax
函数的下半部分应该看起来像这样。但是我不知道你的成本?算法所以只是 returning 1 作为结果。
if (player === COMPUTER_TOKEN) {
const max = _.maxBy(values, (v) => {
return v.cost;
});
if (depth === 8) {
return 1;
} else {
return max.cost;
}
} else {
const min = _.minBy(values, (v) => {
return v.cost;
});
if (depth === 8) {
return 1;
} else {
return min.cost;
}
}
但是这里还有一个问题。 minmax
函数 returns 一个整数值和
let value = minmax(gridCopy, depth + 1, ((player === PLAYER_TOKEN) ? COMPUTER_TOKEN : PLAYER_TOKEN));
期望整数值可以,但是
const move = computerMove();
期望位置对象但得到一个整数。
编辑
抱歉回复晚了。我又看了一遍代码,我错了。
您正在使用 const gameState = gameOver();
模拟 minmax
函数中的每次迭代的游戏结束。但是 gameOver 函数使用全局 grid
变量,它是真实的当前游戏状态。所以我用 const gameState = gameOver(newGrid);
改变了它。并且在框点击处理更改为 let gameState = gameOver();
到 let gameState = gameOver(grid);
为游戏重新启动进行了其他更改,并且如果游戏结束或网格单元不为空则不允许更改网格单元。
修改后的代码here
我正在使用 JavaScrip 开发井字游戏。当我调用 MinMax 函数时,我得到错误的日志序列。在这里,我调用了 minmax 函数,据我所知,我分配的值是正确的。
const value = minmax(gridCopy, depth+1, ((player===PLAYER_TOKEN)?COMPUTER_TOKEN:PLAYER_TOKEN));
我在控制台中遇到错误
main.js:86 Uncaught TypeError: Cannot read property 'cost' of undefined
at minmax (main.js:86)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at minmax (main.js:64)
at computerMove (main.js:120)
如果你想看看我的完整功能,这里是代码。
function minmax(newGrid, depth, player) {
const gameState= gameOver(newGrid);
if(gameState === false) {
const values= [];
for (var i=0; i<3; i++) {
for (var j = 0; j<3;j++){
const gridCopy = _.cloneDeep(newGrid);
if (gridCopy[i][j]!=='') continue;
gridCopy[i][j]=player;
const value = minmax(gridCopy, depth+1, ((player===PLAYER_TOKEN)?COMPUTER_TOKEN:PLAYER_TOKEN));
values.push({
cost:value,
cell: {
i:i,
j:j
}
});
}
}
if (player === COMPUTER_TOKEN) {
const max = _.maxBy(values, (v) => {
return v.cost;
});
if (depth === 0) {
return max.cell;
}
else {
return max.cost;
}
}
else {
const min = _.minBy(values, (v) => {
return v.cost;
});
if (depth === 0) {
return min.cell;
}
else {
return min.cost;
}
}
}else if (gameState === null){
return 0;
}
else if (gameState===PLAYER_TOKEN) {
return depth - 10;
}
else if (gameState===COMPUTER_TOKEN) {
return 10 - depth;
}
}
function computerMove(){
return minmax(grid,0,COMPUTER_TOKEN);
}
这里link 完成项目
我认为这里的错误是你的递归函数。您正在调用 minmax
九次,当 depth
最终达到 8 时,它应该解析它的值,但它不能,因为值是根据永远不会填充的 values
数组计算的。并使用空 values
数组调用 .min/.max 方法得到结果。
最内部的递归调用应该从常量或其他东西而不是某些依赖于递归函数本身的变量 (values
) 解析其 return 值。
所以在我看来 minmax
函数的下半部分应该看起来像这样。但是我不知道你的成本?算法所以只是 returning 1 作为结果。
if (player === COMPUTER_TOKEN) {
const max = _.maxBy(values, (v) => {
return v.cost;
});
if (depth === 8) {
return 1;
} else {
return max.cost;
}
} else {
const min = _.minBy(values, (v) => {
return v.cost;
});
if (depth === 8) {
return 1;
} else {
return min.cost;
}
}
但是这里还有一个问题。 minmax
函数 returns 一个整数值和
let value = minmax(gridCopy, depth + 1, ((player === PLAYER_TOKEN) ? COMPUTER_TOKEN : PLAYER_TOKEN));
期望整数值可以,但是
const move = computerMove();
期望位置对象但得到一个整数。
编辑
抱歉回复晚了。我又看了一遍代码,我错了。
您正在使用 const gameState = gameOver();
模拟 minmax
函数中的每次迭代的游戏结束。但是 gameOver 函数使用全局 grid
变量,它是真实的当前游戏状态。所以我用 const gameState = gameOver(newGrid);
改变了它。并且在框点击处理更改为 let gameState = gameOver();
到 let gameState = gameOver(grid);
为游戏重新启动进行了其他更改,并且如果游戏结束或网格单元不为空则不允许更改网格单元。
修改后的代码here