JavaScript中获取游戏棋子当前位置,如何避免触发移动操作?
问题解答
核心结论
你不能直接调用现有movePiece函数时跳过掷骰子和移动操作却获取返回值——因为当前函数的逻辑是耦合在一起的:移动操作和返回位置的逻辑绑定在了同一个函数里。最佳实现方式是解耦逻辑,把「获取棋子位置」和「执行移动操作」拆成两个独立的函数。
具体解决方案
1. 单独抽取获取位置的函数
这是最符合代码设计原则(单一职责)的方案,直接创建一个专门用来获取当前玩家棋子位置的函数,完全不需要触发移动逻辑:
// 先补全原代码缺失的players变量 const players = ['player1', 'player2']; // 专门获取当前棋子位置的函数 function getCurrentPiecePosition() { return currentPlayer === 'player1' ? currentPosition1 : currentPosition2; }
调用方式非常简单,想拿位置时直接执行:
const currentPosition = getCurrentPiecePosition();
2. 修正原movePiece函数的问题
原代码存在几个bug,需要先修复:
- 最后一个
if语句误用了赋值运算符=,应改为严格相等判断=== players变量未定义,必须提前声明getElementsByClassName返回的是HTMLCollection,建议转成数组避免后续操作问题
修正后的movePiece函数(专注于移动逻辑):
let pieceOne = document.getElementById('piece-one'); let pieceTwo = document.getElementById('piece-two'); // 转成数组更方便操作 const squares = Array.from(document.getElementsByClassName('board-square')); let currentPosition1 = 0; let currentPosition2 = 0; let currentPlayer = 'player1'; // 初始化当前玩家 const players = ['player1', 'player2']; const board = [ 'recharge', 'city-garden', 'earthship', 'hydroponics', 'ev-car', 'greenway', 'cycle-path', 'greenspace', 'hydroelectric', 'solar-farm', 'community-work', 'habitat-survey' ]; function movePiece() { const diceRoll = rollDice(); if (currentPlayer === 'player1') { currentPosition1 += diceRoll; // 处理循环棋盘逻辑 if (currentPosition1 >= board.length) { currentPosition1 -= board.length; } squares[currentPosition1].appendChild(pieceOne); currentPlayer = players[1]; } else { currentPosition2 += diceRoll; if (currentPosition2 >= board.length) { currentPosition2 -= board.length; } squares[currentPosition2].appendChild(pieceTwo); currentPlayer = players[0]; } // 这里可以保留返回位置,但获取位置优先用专门的函数 return getCurrentPiecePosition(); }
3. 可选方案:给movePiece加控制参数(不推荐)
如果不想大幅修改现有代码,可以给movePiece添加一个参数,控制是否跳过移动操作。但这种方式会让函数逻辑变复杂,违反单一职责原则,仅作为临时方案:
function movePiece(skipMove = false) { let diceRoll = 0; if (!skipMove) { diceRoll = rollDice(); // 原移动逻辑 if (currentPlayer === 'player1') { currentPosition1 += diceRoll; if (currentPosition1 >= board.length) { currentPosition1 -= board.length; } squares[currentPosition1].appendChild(pieceOne); currentPlayer = players[1]; } else { currentPosition2 += diceRoll; if (currentPosition2 >= board.length) { currentPosition2 -= board.length; } squares[currentPosition2].appendChild(pieceTwo); currentPlayer = players[0]; } } // 修正判断条件的赋值错误 return currentPlayer === players[1] ? currentPosition1 : currentPosition2; }
调用时传入true即可跳过移动获取位置:
const currentPosition = movePiece(true);
总结
优先选择解耦逻辑的方案,让每个函数只做一件事:getCurrentPiecePosition负责获取位置,movePiece负责执行移动操作。这种方式代码更清晰,也更容易维护和扩展。
内容的提问来源于stack exchange,提问作者NovaBrownie
相关产品推荐
相关产品推荐

