2

I recently write the MinMax algorithm using javascript, but when I implement the recursion,

it seems that the variable changes in a weird way, here is the code:

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;

}

where the function be called

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);
    }
}

in the moveValue function, I console.log the state and istate, I found that state and istate change at the same time which is so beyond my understand about program, and when the recursion

return the state remain the same (doesn't get back to the previous call stack value)

getState is, I create the cells in a file and using require.js to inject everytime I want to use it.

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

    return state;
}

stateMove function is here, and firstPlayer, secondPlayer is the same way with cells

function stateMove(state, move, nextTurn){
    var value = firstPlayer;
    if (nextTurn == -1) value = secondPlayer;
    state[move] = value
    return state
}
daniel-xu
  • 25
  • 7
  • 1
    I suspect your `stateMove` function is changing the `istate` array _in place_ instead of copying it. If you add the code for that function, it would make the problem easier to diagnose. – musically_ut Apr 12 '14 at 13:09

1 Answers1

1

The stateMove function is mutating the array passed to it. Changing it such that it creates a copy of the array will fix the problem:

function stateMove(state, move, nextTurn){
    var nextState = state.slice(0);
    var value = firstPlayer;
    if (nextTurn == -1) value = secondPlayer;
    nextState[move] = value;
    return nextState;
}
musically_ut
  • 34,028
  • 8
  • 94
  • 106
  • Wow, Can you explain a little bit? how could it change the state passed by parameter? is it closure? But it's so untypical @musically_ut – daniel-xu Apr 12 '14 at 13:18
  • @user3526776 Javascript comes _close_ to being a pass by reference language, except in case of primitives. So if you change any _property_ (keep in mind that index values are also properties) of the object (array is also an object + niceties) passed, then the original value will be altered. The explanation here is more complete: http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language – musically_ut Apr 12 '14 at 13:28
  • Thanks a lot! I've been stuck here for a whole day! Thanks again – daniel-xu Apr 12 '14 at 13:38
  • @user3526776 No problem. Also, it was your debugging skills which brought you to an inch of your solution. – musically_ut Apr 12 '14 at 13:39