You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将经典代码转换为函数式:优化国际象棋棋盘空位检查代码

Refactoring Imperative Chess Diagonal Path Check to Functional Style

Got it, let's turn that clunky imperative diagonal path check into a sleek, functional-style solution. The core idea is to move away from manual loops and conditional branches to declarative code that focuses on what we need to verify, not how to iterate through each square.

First, let's recap the original logic: we need to confirm all intermediate squares along a diagonal move (from (xSrc, ySrc) to (xDst, yDst)) are empty (no alive chessmen). The original code splits this into two cases (backslash vs slash moves) and uses a mutable loop variable to track the y-coordinate—functional style eliminates that complexity entirely.

Step 1: Eliminate Direction Branches with Step Calculation

Instead of manually checking if we're moving in a "backslash" or "slash" direction, we can use Integer.signum() to automatically get the step direction for both x and y axes. This handles all diagonal directions (top-left to bottom-right, top-right to bottom-left, etc.) in one go, no conditional branches needed.

Step 2: Generate Intermediate Squares as a Stream

We'll use an IntStream to generate the number of steps between the start and end points, then map each step to the corresponding coordinate pair. This replaces the manual loop entirely with a clean, declarative sequence.

Step 3: Declaratively Check for Alive Chessmen

Use noneMatch() to verify that none of the intermediate squares contain an alive chessman—this directly expresses our intent without mutable state or loop boilerplate.

Refactored Code

Here's the cleaned-up functional implementation:

// First, confirm we're dealing with a valid diagonal move (same as original)
if (Math.abs(xDst - xSrc) != Math.abs(yDst - ySrc)) {
    // Handle non-diagonal moves as needed (return true/false based on your logic)
    return true;
}

// Calculate step direction: +1 for increasing axis, -1 for decreasing
int xStep = Integer.signum(xDst - xSrc);
int yStep = Integer.signum(yDst - ySrc);
int totalSteps = Math.abs(xDst - xSrc);

// Check that ALL intermediate squares have no alive chessmen
return IntStream.range(1, totalSteps)
        .mapToObj(step -> new int[]{xSrc + (xStep * step), ySrc + (yStep * step)})
        .noneMatch(coords -> board.getActiveChessmanAt(coords[0], coords[1]).isAlive());

Even More Reusable: Extract a Helper Method

For better code organization and reusability, we can extract the coordinate generation into a dedicated helper function:

// Helper to generate intermediate diagonal squares as a Stream of coordinate pairs
private Stream<int[]> getIntermediateDiagonalSquares(int xSrc, int ySrc, int xDst, int yDst) {
    if (Math.abs(xDst - xSrc) != Math.abs(yDst - ySrc)) {
        return Stream.empty();
    }
    int xStep = Integer.signum(xDst - xSrc);
    int yStep = Integer.signum(yDst - ySrc);
    int totalSteps = Math.abs(xDst - xSrc);
    
    return IntStream.range(1, totalSteps)
            .mapToObj(step -> new int[]{xSrc + (xStep * step), ySrc + (yStep * step)});
}

// Usage in your main logic
return getIntermediateDiagonalSquares(xSrc, ySrc, xDst, yDst)
        .noneMatch(coords -> board.getActiveChessmanAt(coords[0], coords[1]).isAlive());

Why This Is Better

  • No mutable state: We eliminate the y variable that was being modified in the loop, reducing the chance of off-by-one errors.
  • Declarative intent: The code reads like plain English: "Check none of the intermediate squares have an alive chessman."
  • No direction branches: The step calculation handles all diagonal directions automatically, removing redundant conditional logic.
  • Reusable: The helper method can be called anywhere you need to check diagonal paths in your chess engine.

内容的提问来源于stack exchange,提问作者Krzysztof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:07:52