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

寻求终端棋盘角色移动代码的更优雅实现方案

Hey Brandon, great start on getting your character moving with WASD! That repetitive if/else chain definitely works, but we can clean it up to make the code more maintainable, scalable, and easy to read. Let's break down a couple of elegant approaches:

The Core Problem with Your Current Code

Right now, you’re repeating almost identical logic for each direction—only the coordinate offsets and direction symbol change. This means if you ever want to add new movement directions (like diagonal movement) or tweak the swap logic, you’d have to update four separate blocks of code, which is error-prone.

Optimized Approach 1: Use an Enum (Type-Safe & Clean)

Enums are perfect here because they let you bundle together all related data for each direction (key, X/Y offsets, direction symbol) in one place.

First, define a Direction enum outside your class:

enum Direction {
    UP("w", -1, 0, "[ ^ ]"),
    DOWN("s", 1, 0, "[ v ]"),
    LEFT("a", 0, -1, "[ < ]"),
    RIGHT("d", 0, 1, "[ > ]");

    private final String inputKey;
    private final int xOffset;
    private final int yOffset;
    private final String displaySymbol;

    Direction(String inputKey, int xOffset, int yOffset, String displaySymbol) {
        this.inputKey = inputKey;
        this.xOffset = xOffset;
        this.yOffset = yOffset;
        this.displaySymbol = displaySymbol;
    }

    // Helper to find the Direction matching the input key
    public static Direction fromInput(String input) {
        for (Direction dir : values()) {
            if (dir.inputKey.equals(input)) {
                return dir;
            }
        }
        return null; // Handle invalid input
    }

    // Getters for our direction data
    public int getXOffset() { return xOffset; }
    public int getYOffset() { return yOffset; }
    public String getDisplaySymbol() { return displaySymbol; }
}

Now rewrite your moveYou method to use this enum—all the repeated logic gets condensed into a single block:

public void moveYou(String wasd, You person) {
    Direction direction = Direction.fromInput(wasd);
    if (direction == null) {
        // Optional: Handle invalid input (e.g., print a message)
        return;
    }

    int currentX = person.getX();
    int currentY = person.getY();
    int newX = currentX + direction.getXOffset();
    int newY = currentY + direction.getYOffset();

    // Critical: Add boundary check to avoid array index out-of-bounds errors
    if (newX < 0 || newX >= ground.length || newY < 0 || newY >= ground[0].length) {
        System.out.println("Oops, can't move there—you're at the edge of the map!");
        return;
    }

    // Perform the swap logic once, no repetition!
    ground[currentX][currentY] = ground[newX][newY];
    ground[newX][newY] = person;
    person.setXandY(newX, newY);
    person.setDir(direction.getDisplaySymbol());

    printMap();
}

Optimized Approach 2: Use HashMaps (Simpler, No Enum)

If you don’t want to use enums, you can store direction data in HashMaps to centralize the configuration:

// Define these as class-level constants
private static final Map<String, int[]> OFFSET_MAP = new HashMap<>();
private static final Map<String, String> SYMBOL_MAP = new HashMap<>();

// Initialize the maps once when the class loads
static {
    OFFSET_MAP.put("w", new int[]{-1, 0});
    OFFSET_MAP.put("s", new int[]{1, 0});
    OFFSET_MAP.put("a", new int[]{0, -1});
    OFFSET_MAP.put("d", new int[]{0, 1});

    SYMBOL_MAP.put("w", "[ ^ ]");
    SYMBOL_MAP.put("s", "[ v ]");
    SYMBOL_MAP.put("a", "[ < ]");
    SYMBOL_MAP.put("d", "[ > ]");
}

public void moveYou(String wasd, You person) {
    if (!OFFSET_MAP.containsKey(wasd)) {
        return; // Invalid input
    }

    int[] offset = OFFSET_MAP.get(wasd);
    String dirSymbol = SYMBOL_MAP.get(wasd);

    int currentX = person.getX();
    int currentY = person.getY();
    int newX = currentX + offset[0];
    int newY = currentY + offset[1];

    // Same boundary check as before
    if (newX < 0 || newX >= ground.length || newY < 0 || newY >= ground[0].length) {
        System.out.println("Can't move out of bounds!");
        return;
    }

    // Swap logic (only written once)
    ground[currentX][currentY] = ground[newX][newY];
    ground[newX][newY] = person;
    person.setXandY(newX, newY);
    person.setDir(dirSymbol);

    printMap();
}

Why These Improvements Matter

  • Less repetition: All movement logic lives in one place, so you only ever need to fix or update it once.
  • Scalability: Adding a new direction (like diagonal q for up-left) just requires adding a new enum entry or map entry—no changes to the core movement code.
  • Readability: Anyone looking at the code can instantly see what each direction does, without digging through four if/else blocks.
  • Safety: The boundary check prevents crashes from moving outside the map, which your original code doesn’t handle.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:50:12