You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复JavaScript中Minimax算法未向初始调用返回分数的井字棋问题

问题:Minimax算法无法正确返回最优移动分数

我认为问题可能出在对emptyIndexes的调用上,返回的IndexArray总是为0,Moves数组无法将分数返回给初始的8个空位。

如何让分数返回至最初的minimax调用函数?我尝试过调试但找不到问题所在。

根据我的理解,递归会持续到触发终止条件(分数为10、-10、0),随后将这些值反向传递至初始调用,再基于所有结果更新最优分数并返回包含BestMove的对象。但目前BestMove的调用仅返回0值。

const minimax = (newBoard,currentPlayer)=>{
            
            let availSpots = emptyIndexes(newBoard)
            newBoard = Array.from(newBoard)
            if(CheckForWin(newBoard) && currentPlayer === players[0]){
                return {"score":-10}
            }
         else if(CheckForWin(newBoard) && currentPlayer ===players[1]){
                return {"score":10}
            }
            else if (availSpots.length === 0){
                return {"score":0}
            }
            
            let Moves = []
            for(let k = 0;k<availSpots.length;k++){
                let move = {}
                move.index = availSpots[k]
                newBoard[availSpots[k]] = currentPlayer
                if(currentPlayer === players[1] ){
                    let result = minimax(newBoard,players[0]).score
                    move.score = result
                }
                else{
                    let result = minimax(newBoard,players[1]).score
                    move.score = result
                }
                newBoard[availSpots[k]] = move.index
                Moves.push(move)
                console.log(Moves)
                
            }
            let BestMove;
                if(currentPlayer === players[1]){    
                    let bestscore1 = -Infinity
                        for(let j = 0;j < Moves.length;j++){
                            if(Moves[j].score > bestscore1){
                                bestscore1 = Moves[j].score
                                BestMove = j
                            }    
                        }
                }
                else if(currentPlayer === players[0]){
                    let bestscore = Infinity
                        for(let i = 0;i < Moves.length;i++){
                            if(Moves[i].score < bestscore){
                                bestscore = Moves[i].score
                                BestMove = i 
                            }
                        }
                }
                return Moves[BestMove]
    }                               
function emptyIndexes(array){
        let indexArray = []
        for(i = 0;i<array.length;i++){
            if(array[i] == ''){
                indexArray.push(i)
            }
        }
        return indexArray
    }

问题修复说明

  • 添加深度计算:move.score = Math.sign(move.score) * (Math.abs(move.score)-1)
  • 修改棋盘赋值逻辑:将Board[availSpots[k]] = currentPlayer改为Board[availSpots[k]] = currentPlayer.mark
  • 调整返回分数:此前人类玩家获胜时返回10,AI获胜时返回-10,由于调用minimax(Board,players[0]).score会切换当前玩家,且CheckForWin函数未区分获胜者是AI还是人类,因此反转分数后才能向初始调用返回正确值。

感谢所有尝试提供帮助的人,希望这能帮助到其他开发者。

内容的提问来源于stack exchange,提问作者Byrie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:21:02