Javascript Tic Tac Toe minimax AI在游戏结束后不工作。递归问题,它们在哪里?
我设法为我的tic-tac-toe工作获得了一个非常简单的人工智能,但只有在最后一步,当这是两个明显的选择时——我可以让算法在剩下的一个空格中放置一个标记,看看是否有赢家,如果没有,清除棋盘,将其放在另一个空格中,看看是否有赢家,然后返回正确的选择 但是,当我尝试执行递归时,有些地方不正常。你能看一下并告诉我它在哪里散架吗?我躲开了,这对我来说似乎是对的。它也很慢,所以我一定是在什么地方搞砸了Javascript Tic Tac Toe minimax AI在游戏结束后不工作。递归问题,它们在哪里?,javascript,recursion,artificial-intelligence,tic-tac-toe,minimax,Javascript,Recursion,Artificial Intelligence,Tic Tac Toe,Minimax,我设法为我的tic-tac-toe工作获得了一个非常简单的人工智能,但只有在最后一步,当这是两个明显的选择时——我可以让算法在剩下的一个空格中放置一个标记,看看是否有赢家,如果没有,清除棋盘,将其放在另一个空格中,看看是否有赢家,然后返回正确的选择 但是,当我尝试执行递归时,有些地方不正常。你能看一下并告诉我它在哪里散架吗?我躲开了,这对我来说似乎是对的。它也很慢,所以我一定是在什么地方搞砸了 function bestAIMove() { var smartAIArray = listE
function bestAIMove() {
var smartAIArray = listEmptySpaces();
let bestScore = -100000
var move;
for (var i = 0; i < smartAIArray.length; i++) {
let smartAIpicked = smartAIArray[i];
origBoard[smartAIpicked].classList.add(TWO_CLASS);
origBoard[smartAIpicked].innerHTML = TWO_CLASS;
let score = minimax(origBoard)
origBoard[smartAIpicked].classList.remove(TWO_CLASS);
origBoard[smartAIpicked].innerHTML = "";
if (score > bestScore) {
bestScore = score;
move = smartAIpicked;
console.log(move)
}
}
origBoard[move].classList.add(TWO_CLASS);
origBoard[move].innerHTML = TWO_CLASS;
}
function minimax() {
if (playerhasWon() && playerOneTurn) {
return -10;
} else if (playerhasWon() && !playerOneTurn) {
return 10;
} else if (emptySpaceRemains() == false) {
return 0;
}
swapTurns()
// the recursive part from here down is the problem
if (!playerOneTurn) {
let bestScore = -100000;
var smartAIArray = listEmptySpaces();
for (var i = 0; i < smartAIArray.length; i++) {
let smartAIpicked = smartAIArray[i];
origBoard[smartAIpicked].classList.add(TWO_CLASS);
origBoard[smartAIpicked].innerHTML = TWO_CLASS;
let score = minimax(origBoard)
origBoard[smartAIpicked].classList.remove(TWO_CLASS);
origBoard[smartAIpicked].innerHTML = "";
if (score > bestScore) {
bestScore = score}
}
return bestScore;
}
else {
let bestScore = 100000;
var smartAIArray = listEmptySpaces();
for (var i = 0; i < smartAIArray.length; i++) {
let smartAIpicked = smartAIArray[i];
origBoard[smartAIpicked].classList.add(ONE_CLASS);
origBoard[smartAIpicked].innerHTML = ONE_CLASS;
let score = minimax(origBoard)
origBoard[smartAIpicked].classList.remove(ONE_CLASS);
origBoard[smartAIpicked].innerHTML = "";
if (score < bestScore) {
bestScore = score}
}
return bestScore;
}
}
函数bestAIMove(){
var smartAIArray=listemptyspace();
让bestScore=-100000
var移动;
对于(变量i=0;i最佳分数){
最佳分数=分数;
移动=智能拾取;
控制台日志(移动)
}
}
origBoard[move].classList.add(两个类);
origBoard[move].innerHTML=TWO_类;
}
函数minimax(){
如果(playerHaswen()&&playerTurn){
返回-10;
}else if(playerhasWon()&&!playerTurn){
返回10;
}else if(EmptySpaceResistings()==false){
返回0;
}
swapTurns()
//下面的递归部分就是问题所在
如果(!转){
让bestScore=-100000;
var smartAIArray=listemptyspace();
对于(变量i=0;i最佳分数){
最佳得分=得分}
}
返回最佳分数;
}
否则{
让bestScore=100000;
var smartAIArray=listemptyspace();
对于(变量i=0;i
如果我只是将代码限制为bestAIMove
和If
语句,该语句用于计算minimax()
中的分数,那么它会起作用。尽管它基本上是bestAIMove()
- 在
最小最大值的一部分,则从bestAIMove()李>
- 更改
以在[i]空间中放置标记李>origBoard
- 通过
评估分数李>minimax()
- 如果没有得分,则运行
,然后转到swapTurns()
部分else
李>minimax
- 再次转到listemptyspace()。运行另一个for循环。在[i]空间中再次放置一个标记
- 再次通过
评估分数李>minimax()
- 如果没有分数,则运行
李>swapTurns()
- 然后,如果(!playerOneTurn)
开始李>
- 重复,直到你得到分数李>
- 该分数位于bestAIMove中李>
- 移除用于测试斑点的标记李>
- 将评估下一个空空间李>
- 得分最高的空白区域是标记器的位置
- 相应的空格将被称为
,表示AI移动的位置move
- 更改
['1','X','3','4','5','O','7','8','9']
和一个播放器'X'
或'O'
。其想法是,该模型可以很容易地用作任何用户界面的基础,您可以选择显示和与游戏交互
设计
我们使用许多小的——甚至很小的——单一用途函数来操作简单的数据类型。所有数据都是不可变的。这些都不是全球性的。我们只需将必要的项传递给每个函数,并返回结果,而不是修改全局对象。此代码根本不处理用户界面。一个完整的系统将在这里的功能之上分层
代码
const randomChoice=(xs)=>
xs[Math.floor(Math.random()*xs.length)]
常量移动=(玩家、方块、棋盘)=>
board.map(x=>x==square?玩家:x)
const availableMoves=(板)=>
board.filter(x=>/\d/.test(x))
const checkWin=((赢)=>(玩家、棋盘)=>
赢。一些(方块=>方块。每个(方块=>棋盘[方块-1]==玩家))
) ([[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 5, 9], [3, 5, 7]])
常数分数=(板)=>
checkWin('X',板)?10:checkWin(“O”,板)-10 : 0
常数层=(玩家)=>
玩家=='X'?'O':'X'
常量比较=(测试)=>(最佳,{move,score})=>
测试(分数,最佳[0]。分数)
? [{移动,得分}]
:得分==最佳[0]。得分
? […最佳,{移动,得分}]
:最好的
常量最佳移动=(pla)