首页 > 解决方案 > 如何组合所有类似的数组循环方法?Java 1.8

问题描述

为了学习编程,我正在用java制作一个游戏2048。游戏有一个类,其中有很多重复的片段——字段迭代循环。问题是,是否有可能创建一个接受枚举边界值和可执行代码的方法?

类似这样的分配和比较。

public void forField(int borderX, int borderY, ??? code){
    for (int x = 0; x < borderX; x++)
        for (int y = 0; y < borderY; y++)
            do code;
}

public boolean checkField(int borderX, int borderY, ??? code, boolean default_answer){
    for (int x = 0; x < borderX; x++)
        for (int y = 0; y < borderY; y++)
            return code;
    return default_answer;
}

如果没有,您能否推荐如何使我的代码更好?感谢您的关注。

public class Field {
    private int[][] field;
    private int width, heigth;

    public Field(int sizeX, int sizeY) {
        this.width = sizeX;
        this.heigth = sizeY;
        this.field = new int[sizeX][sizeY];
    }

    public int getCell(int x, int y) {
        return this.field[x][y];
    }

    public void setCell(int val, int x, int y) {
        this.field[x][y] = val;
    }

    // for restart
    public void reset() {
        for (int x = 0; x < width; x++)
            for (int y = 0; y < heigth; y++)
                this.field[x][y] = 0;
    }

    // for step cancelling function
    public void copyOf(Field f) {
        for (int x = 0; x < width; x++)
            for (int y = 0; y < heigth; y++)
                this.field[x][y] = f.getCell(x, y);
    }

    // can field changed after pressing a key
    public boolean isEqualTo(Field f) {
        for (int x = 0; x < width; x++)
            for (int y = 0; y < heigth; y++)
                if (field[x][y] != f.getCell(x, y))
                    return false;
        return true;
    }

    private boolean canMergeByY() {
        for (int x = 0; x < width; x++)
            for (int y = 0; y < heigth - 1; y++)
                if (field[x][y] == field[x][y + 1])
                    return true;
        return false;
    }

    private boolean canMergeByX() {
        for (int x = 0; x < width - 1; x++)
            for (int y = 0; y < heigth; y++)
                if (field[x][y] == field[x + 1][y])
                    return true;
        return false;
    }

    // checking the possibility of continuing the game
    public boolean canMerge() {
        return canMergeByX() && canMergeByY();
    }

    // checking 0 and 2048 cells for different tasks
    public boolean contains(int i) {
        for (int x = 0; x < width; x++)
            for (int y = 0; y < heigth; y++)
                if (field[x][y] == i)
                    return true;
        return false;
    }
}

标签: java

解决方案


???inforField可以是一个,或者如果你不喜欢装箱,BiConsumer<Integer, Integer>你可以声明你自己的接口:IntBiConsumer

interface IntBiConsumer {
    void accept(int i, int j);
}

forField然后可以声明为:

public void forField(int borderX, int borderY, IntBiConsumer code){
    for (int x = 0; x < borderX; x++)
        for (int y = 0; y < borderY; y++)
           code.accept(x, y);
}

copyOf那么可以写成:

public void copyOf(Field f) {
    forField(width, height, (x, y) -> {
        this.field[x][y] = f.getCell(x, y);
    });
}

checkField有点棘手,您提出的代码实际上不会起作用,因为您没有return在内部循环中检查任何内容。循环只会循环一次,并立即返回。它应该更像:

public boolean checkField(int borderX, int borderY, ??? condition, boolean default_answer){
    for (int x = 0; x < borderX; x++)
        for (int y = 0; y < borderY; y++)
            if (condition) 
                return !default_answer;
    return default_answer;
}

???这里可以是一个BiPredicate<Integer, Integer>,或者你自己的界面,如下所示:

interface IntBiPredicate {
    boolean test(int i, int j);
}

checkField然后可以这样声明:

public boolean checkField(int borderX, int borderY, IntBiPredicate condition, boolean defaultAnswer){
    for (int x = 0; x < borderX; x++)
        for (int y = 0; y < borderY; y++)
            if (condition.test()) 
                return !defaultAnswer;
    return defaultAnswer;
}

isEqualTo可以改写为:

public boolean isEqualTo(Field f) {
    return checkField(width, height, (x, y) -> field[x][y] != f.getCell(x, y), true);
}

推荐阅读