如何减少过度冗余的 for 循环
How to reduce overly-redundant for loops
我目前正在开发一款国际象棋游戏,运行 遇到了我的 Bishop class 中的代码冗余问题。我正在尝试创建一个函数来获取主教的所有可能动作。为此,我将创建一个 for 循环来评估主教的所有对角线,并在它到达棋盘或棋子的末端时中断循环。这段代码的问题是它是多余的,因为要评估主教可以走的所有对角线,我必须有 4 个 for 循环。代码的简化版本如下所示
var list = [1,0,0,0,1,0,0,1]; // 1d list
var index = 5; // position of "bishop"
for (let i = index, j = list.length; i < j; i++) {
if (list[i] === 1) { // if true, return instance of 1 and break loop
console.log("first instance of 1 going right, found at " + i);
break;
}
}
for (let i = index; i >= 0; i--) {
if (list[i] === 1) { // if true, return instance of 1 and break loop
console.log("first instance of 1 going left, found at " + i);
break;
}
}
虽然此代码有效,但在处理可以向 4 个方向移动的主教时,这是相当重复的,可能会在未来导致问题。有没有一种方法可以在不降低效率的情况下将 4 个 for 循环(或上例中的 2 个)减少到 1 个?因为答案需要正确的概念,所以没有太多可以展示我在这个问题上的尝试。
左右迭代器如何组合两个循环并同时查看两个方向。
var list = [1,0,0,0,1,0,0,1];
var index = 5;
var left = index - 1;
var right = index + 1;
while(left >= 0 || right < list.length)
{
if(list[left] === 1) {
console.log("first instance of 1 going left, found at " + left);
break;
}
if(list[right] === 1) {
console.log("first instance of 1 going right, found at " + right);
break;
}
if(left >= 0)
left--;
if(right < list.length)
right++;
}
我建议使用函数来替换循环。
这使得可以重复使用相同的循环而无需复制粘贴它。
这是一个代码示例:
// Board width and height.
const boardSize = 8;
// The chess board (2d array, x index first).
const board = [[0,0,1, ...],[1,0,1, ...], ...];
// Get the maximum distance a piece can travel in a direction.
function findTravelDistance(x,y,dirX,dirY) {
for (let n = 0;; n++) {
// Calculate the position from moving n spaces.
var newX = x + n*dirX,
newY = y + n*dirY;
// Return if the piece is off the board.
if (newX < 0 || newX >= boardSize || newY < 0 || newY >= boardSize)
return n - 1;
// Return if the piece hits a one.
if (board[newX][newY] === 1)
return n;
}
}
// Array containing all directions a bishop can move.
const bishopDirections = [[1,1], [1,-1], [-1,1], [-1,-1]];
// Take x and y as starting position.
// Return an array of distances corresponding to directions in bishopDirections
function findBishopTravelDistances(x,y) {
var distances = [0,0,0,0];
// Calculate distances for all directions.
for (let i = 0; i < bishopDirections.length; i++)
distances[i] = findTravelDistance()
return distances;
}
我目前正在开发一款国际象棋游戏,运行 遇到了我的 Bishop class 中的代码冗余问题。我正在尝试创建一个函数来获取主教的所有可能动作。为此,我将创建一个 for 循环来评估主教的所有对角线,并在它到达棋盘或棋子的末端时中断循环。这段代码的问题是它是多余的,因为要评估主教可以走的所有对角线,我必须有 4 个 for 循环。代码的简化版本如下所示
var list = [1,0,0,0,1,0,0,1]; // 1d list
var index = 5; // position of "bishop"
for (let i = index, j = list.length; i < j; i++) {
if (list[i] === 1) { // if true, return instance of 1 and break loop
console.log("first instance of 1 going right, found at " + i);
break;
}
}
for (let i = index; i >= 0; i--) {
if (list[i] === 1) { // if true, return instance of 1 and break loop
console.log("first instance of 1 going left, found at " + i);
break;
}
}
虽然此代码有效,但在处理可以向 4 个方向移动的主教时,这是相当重复的,可能会在未来导致问题。有没有一种方法可以在不降低效率的情况下将 4 个 for 循环(或上例中的 2 个)减少到 1 个?因为答案需要正确的概念,所以没有太多可以展示我在这个问题上的尝试。
左右迭代器如何组合两个循环并同时查看两个方向。
var list = [1,0,0,0,1,0,0,1];
var index = 5;
var left = index - 1;
var right = index + 1;
while(left >= 0 || right < list.length)
{
if(list[left] === 1) {
console.log("first instance of 1 going left, found at " + left);
break;
}
if(list[right] === 1) {
console.log("first instance of 1 going right, found at " + right);
break;
}
if(left >= 0)
left--;
if(right < list.length)
right++;
}
我建议使用函数来替换循环。 这使得可以重复使用相同的循环而无需复制粘贴它。
这是一个代码示例:
// Board width and height.
const boardSize = 8;
// The chess board (2d array, x index first).
const board = [[0,0,1, ...],[1,0,1, ...], ...];
// Get the maximum distance a piece can travel in a direction.
function findTravelDistance(x,y,dirX,dirY) {
for (let n = 0;; n++) {
// Calculate the position from moving n spaces.
var newX = x + n*dirX,
newY = y + n*dirY;
// Return if the piece is off the board.
if (newX < 0 || newX >= boardSize || newY < 0 || newY >= boardSize)
return n - 1;
// Return if the piece hits a one.
if (board[newX][newY] === 1)
return n;
}
}
// Array containing all directions a bishop can move.
const bishopDirections = [[1,1], [1,-1], [-1,1], [-1,-1]];
// Take x and y as starting position.
// Return an array of distances corresponding to directions in bishopDirections
function findBishopTravelDistances(x,y) {
var distances = [0,0,0,0];
// Calculate distances for all directions.
for (let i = 0; i < bishopDirections.length; i++)
distances[i] = findTravelDistance()
return distances;
}