Как я могу сохранить предыдущее значение переменной в Javascript? - PullRequest
2 голосов
/ 13 февраля 2020

В моем проекте у меня есть фрагмент некоторого "глючного" кода. Функция makeMove обновляет глобальную переменную board, а функция takeMove сбрасывает плату. Пока плата заменяется, я помещаю значение платы в массив, а затем сбрасываю плату. Проблема в том, что когда я обращаюсь к этому массиву, значения платы, хранящиеся внутри него, являются значениями платы сброса, когда я хочу значения обновленной платы в массиве.

Я попытался поверхностно скопировать обновленную плату и затем сохранить ее, но это не работает, я не копирую массив глубоко, так как я буду использовать этот код тысячи итераций, а глубокое копирование может занять много времени. производительности.

Вот фрагмент кода:

let board = [
    ["C", "H", "B", "Q", "K", "B", "H", "C"],
    ["P", "P", "P", "P", "P", "P", "P", "P"],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    ["p", "p", "p", "p", "p", "p", "p", "p"],
    ["c", "h", "b", "q", "k", "b", "h", "c"]
];

function makeMove(from, to) {
    let piece = board[from.y][from.x];
    board[from.y][from.x] = " ";
    pieceBeforeOnToSQ = board[to.y][to.x];
    board[to.y][to.x] = piece;
}

function takeMove(from, to) {
    let piece = board[to.y][to.x];
    board[to.y][to.x] = pieceBeforeOnToSQ;
    board[from.y][from.x] = piece;
}

makeMove(position, {
    x: index % 8,
    y: Math.floor(index / 8)
});
pseudoLegalNodeList.push(board);
takeMove(position, {
    x: index % 8,
    y: Math.floor(index / 8)
});

Примечание: переменная pieceBeforeOnToSQ является глобальной.

Если вам нужны какие-либо разъяснения по этому вопросу или код, не стесняйтесь спрашивать.

Ответы [ 3 ]

1 голос
/ 13 февраля 2020

Я предлагаю вам реализовать свой код следующим образом:

let moves = [];

function initialState() {
    return [
        ["C", "H", "B", "Q", "K", "B", "H", "C"],
        ["P", "P", "P", "P", "P", "P", "P", "P"],
        [" ", " ", " ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " ", " ", " "],
        ["p", "p", "p", "p", "p", "p", "p", "p"],
        ["c", "h", "b", "q", "k", "b", "h", "c"]
    ];
}

function currentState() {
    const board = initialState();
    moves.forEach(function (move) {
        const currentPiece = board[move.from.y][move.from.x];
        board[move.from.y][move.from.x] = " ";
        board[move.to.y][move.to.x] = currentPiece;
    });
    return board;
}

function makeMove(move) {
    moves.push(move);
}

function undoMoves(amountOfMoves) {
    moves = moves.slice(0, -1 * amountOfMoves);
}

makeMove({
    from: {
        x: 0,
        y: 1
    },
    to : {
        x: 0,
        y: 2
    }
});

Чтобы сделать ход, в массив moves добавляется новый move. Чтобы отменить ход или несколько ходов, вы можете просто позвонить undoMoves(<amount of moves to undo>);

Наконец, чтобы получить обзор доски, вы просто позвоните currentState();

Вы можете поиграть с рабочий пример этого JSFiddle .

1 голос
/ 13 февраля 2020

Я бы посоветовал вам сохранить массив истории, в котором вы находились sh состояний в соответствующих полях доски до того, как был сделан ход.

Когда вы перематываете / отменяете историю, вы восстанавливаете эти состояния, выталкивая их из массива и возвращая эти поля в исходное состояние.

Преимущество этого метода по сравнению с методом Titulum заключается в том, что с помощью этого метода вы также создаете историю выполненных ходов, и вы можете проанализировать ход позже, не отфильтровывая, какие ходы были особенно сделаны со всей доски.

См. пример ниже. Вы можете расширить нужные шаги, отредактировав json в текстовом поле и нажав перезагрузить

function getOriginalBoard() { return [
    ["C", "H", "B", "Q", "K", "B", "H", "C"],
    ["P", "P", "P", "P", "P", "P", "P", "P"],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " "],
    ["p", "p", "p", "p", "p", "p", "p", "p"],
    ["c", "h", "b", "q", "k", "b", "h", "c"]
    ]
};
let board = getOriginalBoard();
let history = [
];

function makeHistoryEntry(from, to) {
   history.push({
      from : {
         location: from,
         value: board[from.y][from.x]
      },
      to : {
          location: to,
          value: board[to.y][to.x]          
      }
   });
}
function rewind() {
   if(history.length > 0) {
     let previousState = history.pop();
     let from = previousState.from;
     board[from.location.y][from.location.x] = from.value;
     let to = previousState.to;
     board[to.location.y][to.location.x] = to.value;
     renderField();
   }
}

function makeMove(from, to) {
    makeHistoryEntry(from, to);
    let piece = board[from.y][from.x];
    
    board[from.y][from.x] = " ";
    board[to.y][to.x] = piece;

    renderField();
}

function renderField() {
   let play = document.getElementById('play');
   let content = [];
   content.push('Y   -' + ([...Array(board[0].length)].join("---")))
   for(let i = 0; i < board.length; i++) {
      content.push(i +' : ' + board[i].join('  '));
   }
   content.push('    -' + ([...Array(board[0].length)].join("---")))
   content.push(' X: ' + ([...Array(board[0].length).keys()].join("  ")))
   play.innerText = content.join('\n');
}

let movesElement = document.getElementById('moves');
let moves = JSON.parse(movesElement.value);

document.getElementById('next_move').addEventListener('click', (e)=>{
   let move = moves.shift();
   if(move) {
     makeMove(move.from, move.to);
   } else { window.alert("No more moves"); }
});
document.getElementById('rewind').addEventListener('click', rewind);
document.getElementById('reload').addEventListener('click', (e) => {
   moves = JSON.parse(movesElement.value);
   history = [];
   board = getOriginalBoard();
   renderField();
});
renderField();
#play {
  background: #333;
  color: #eee;
  font-weight: 800;
  padding: 12px;
  display: inline-block;
}
#moves {
  width: 300px;
  height: 200px;
}


перезагрузить следующий ход отменить
[{"from": {"x": 7, "y": 7}, "to": {"x": 6, "y": 5}}, {"from": {"x": 0 , "y": 0}, "to": {"x": 0, "y": 3}}, {"from": {"x": 1, "y": 0}, "to": {"x": 1, "y": 4}}, {"from": {"x": 0, "y": 6}, "to": {"x": 0, "y": 3 }}]
0 голосов
/ 13 февраля 2020

Почему бы не сохранить последнее значение с индексами, например,

[x, y, value]

и сохранить последнее значение в массиве вместе с позицией.

Для перехода в обратном направлении возьмите значения с конца массива с их позицией и получим доску с определенным количеством обратных шагов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...