Объект не клонируется - Javascript

У меня есть класс Javascript, который мне нужно клонировать, чтобы создать алгоритм минимакс с альфа-бета-обрезкой в ​​javascript. Но когда я передаю объект доски в функцию минимакс, предполагается, что он глубоко копирует объект доски, а затем вносит изменения, но он вносит изменения в исходную доску. Почему оно это делает?

var Buddha = function() {

  this.movehistory = 0;
  this.color = "b";
  this.opp = "w";

  this.clone = function(board) {
    return $.extend(true, {}, board)
  }

  this.minimax = function(board, depth, alpha, beta) {
    if(depth === 0 || board.game_over() === true) {
      return [this.eval_board(board), null]
    } else {
      if(board.turn() === "w") {
        var bestmove = null

        var possible_moves = board.moves()
        for (index = 0; index < possible_moves.length; ++index) {
          var new_board = this.clone(board)
          new_board.move(possible_moves[index])

          var mini = this.minimax(new_board, --depth, alpha, beta)
          var score = mini[0];
          var move = mini[1];

          if(score > alpha) {
            alpha = score;
            bestmove = possible_moves[index];
            if(alpha >= beta) {
              break;
            }
          }
        }
        return [alpha, bestmove]
      } else if(board.turn() === "b") {
        var bestmove = null

        var possible_moves = board.moves()
        for (index = 0; index < possible_moves.length; ++index) {
          var new_board = this.clone(board)
          new_board.move(possible_moves[index])

          var mini = this.minimax(new_board, --depth, alpha, beta)
          var score = mini[0];
          var move = mini[1];

          if(score < beta) {
            beta = score;
            bestmove = possible_moves[index];
            if(alpha >= beta) {
              break;
            }
          }
        }
        return [beta, bestmove]
      }
    }
  }

  this.eval_board = function(board) {
    if(board.in_check()) {
      if(board.turn() == this.opp) {
        return Number.POSITIVE_INFINITY;
      } else {
        return Number.NEGATIVE_INFINITY;
      }
    } else if(board.in_checkmate()) {
      if(board.turn() == this.opp) {
        return Number.POSITIVE_INFINITY;
      } else {
        return Number.NEGATIVE_INFINITY;
      }
    } else if(board.in_stalemate()) {
      if(board.turn() == this.opp) {
        return Number.POSITIVE_INFINITY;
      } else {
        return Number.NEGATIVE_INFINITY;
      }
    }
  }

  this.move = function(board) {
    console.log(board.fen());
    var bestmove = this.minimax(this.clone(board), 8, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY) 

    console.log(board.fen());
  }

}

Вывод журнала консоли:

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
R2r1b2/2q1k1p1/2n4n/2P2Q2/8/8/4K2P/1NBQ1BNR b - - 30 55

В моем модуле используется API chess.js из: https://github.com/jhlywa/chess.js.


Редактировать: я сузил его до функции клонирования, которая неправильно клонирует функцию Chess. Это потому, что функция Chess не объявляет переменные с помощью декоратора this?


person TimCPogue    schedule 07.03.2014    source источник
comment
Он не должен делать глубокую копию. Он должен вести себя как все объекты и передавать ссылку.   -  person cookie monster    schedule 07.03.2014
comment
Как я могу сделать глубокую копию? Я не хочу изменять исходный объект.   -  person TimCPogue    schedule 07.03.2014
comment
Взгляните на некоторые ссылки справа под заголовком Связанные.   -  person cookie monster    schedule 07.03.2014
comment
Я просмотрел другие ответы и реализовал лучший ответ в функции клонирования, которая использует функцию расширения jQuery, но она явно не работает.   -  person TimCPogue    schedule 07.03.2014
comment
потому что $.extend ничего не клонирует. Если ваши объекты являются чистыми данными, вы можете сериализовать/десериализовать их с помощью функций JSON, чтобы закрыть их.   -  person mpm    schedule 07.03.2014


Ответы (1)


Библиотека chess.js создает свои переменные статически. Затруднение клонирования объекта. К счастью, объект Chess позволяет передавать переменную FEN. Позволяет мне клонировать доску следующим образом:

var clonedBoard = new Chess(oldBoard.fen());

Это предотвращает модификацию исходной платы.

person TimCPogue    schedule 07.03.2014