2014-04-12 37 views
2

我最近使用JavaScript编写的极小极大算法,但是当我执行递归,JavaScript的递归变量问题

似乎以一种不可思议的方式变量的变化,这里是代码:

function moveValue(istate, move, moveFor, nextTurn, depth){ 

    console.log("the original state is: ", istate) 
    var state = stateMove(istate, move, nextTurn); 
    var winner = status.detectWin(state) 
    console.log("now the istate is:", istate) 
    console.log("now the state is: ", state) 

    if (winner == 'tie'){ 
     return 0; 
    } else if (winner != 0){ 
     if (moveFor == nextTurn) return 10 - depth; 
     else return depth - 10; 
    } 

    //if the the current operation is not the same with the original, minimum scenario 
    //if the the current operation is the same with the original, maximum scenario 
    var hope = 999; 
    if (moveFor != nextTurn) hope = -999; 

    var moves = getLegalMoves(state); 

    for (var i=0; i<9; i++){ 
     if (moves.indexOf(i) > -1) { 
      var value = moveValue(state, i, moveFor, -nextTurn, depth+1); 
      if (moveFor == nextTurn && value < hope ||moveFor != nextTurn && value > hope){ 
       hope = value; 
      }    

     } 
    } 

    return hope; 

} 

其中函数在moveValue函数调用

function perfectMove(){ 
    var state = status.getState(); 
    var winner = status.detectWin(state); 

    if (winner == 0){ 
     var moves = getLegalMoves(state); 

     //Because the AI is unbeatable, so this is the minimum scenario 
     var hope = -999; 
     var goodMoves = [] 
     //var is = [] 

     //not blank or just one scenario 
     if (goodMoves.length == 0){ 
      for (var i=0; i<9; i++){ 
       //for these legal move 
       if (moves.indexOf(i)> -1) { 
        var value = moveValue(state, i, turn, turn, 1); 
        if (value > hope){ 
         hope = value; 
         goodMoves = []; 
        } 
        //get all the possible best move 
        if (hope == value){ 
         goodMoves.push(i); 
        } 
       } 
      } 
     } 
     moveRandom(goodMoves); 
    } 
} 

,我CONSOLE.LOG状态和即将状态置,我发现,状态和即将状态置在这也是让我无法同时变化了解有关程序,并在递归

回报的状态保持不变(不回到以前的调用堆栈值)

getState是,我在文件中创建单元格并使用require.js注入每次我想要使用它。

function getState(){ 
    var state = []; 
    for (var i=0; i<9; i++){ 
     state.push(cells[i].value) 
    } 

    return state; 
} 

stateMove功能在这里,并且firstPlayer,secondPlayer是相同的方式与细胞

function stateMove(state, move, nextTurn){ 
    var value = firstPlayer; 
    if (nextTurn == -1) value = secondPlayer; 
    state[move] = value 
    return state 
} 
+1

我怀疑你的'stateMove'功能改变'istate'阵列_in place_而不是复制。如果您为该功能添加代码,则会使问题更易于诊断。 –

+0

嗨,@musically_ut,我添加它,谢谢你的回答 –

回答

1

stateMove功能突变传递给它的阵列。改变它,使得它创建数组的副本将解决这个问题:

function stateMove(state, move, nextTurn){ 
    var nextState = state.slice(0); 
    var value = firstPlayer; 
    if (nextTurn == -1) value = secondPlayer; 
    nextState[move] = value; 
    return nextState; 
} 
+0

哇,你能解释一下吗?它怎么能改变通过参数传递的状态?它关闭了吗?但它非常不典型@musically_ut –

+0

@ user3526776除了在基元的情况下,Javascript成为通过引用语言传递的关键。所以如果你改变了对象的所有_property_(记住索引值也是属性)(数组也是一个对象+ niceties),那么原始值将被改变。这里的解释更加完整:http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language –

+0

非常感谢!我一直呆在这里一整天!再次感谢 –