簡體   English   中英

如何在 Javascript 中存儲變量的先前值?

[英]How can I store the previous value of a variable in Javascript?

在我的一個項目中,我有一些“有問題”的代碼片段。 函數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是全局的。

如果您需要有關問題或代碼的任何說明,請隨時提問。

我建議您保留一個歷史數組,在移動之前,您可以在其中推送董事會受影響字段中的狀態。

當您回退/撤消歷史記錄時,您可以通過將它們從數組中彈出並將這些字段返回到它們的原始狀態來恢復這些狀態。

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; }
 <pre id="play"> </pre> <hr> <button id="reload">reload</button> <button id="next_move">next move</button> <button id="rewind">undo</button> <hr> <textarea id="moves"> [ {"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}} ] </textarea>

為什么不將最后一個值也與索引一起存儲,例如

[x, y, value]

並將數組中的最后一個值與位置一起保留。

為了向后走,從數組末尾獲取值及其位置,並獲得具有一定數量后退步數的板。

我建議你像這樣實現你的代碼:

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

為了移動,一個新的move被添加到moves數組中。 要撤消一個或多個移動,您可以調用undoMoves(<amount of moves to undo>)

最后,要獲得董事會的概述,您只需調用currentState()

你可以在這個JSFiddle上玩一個工作示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM