简体   繁体   English

如何清理用Java写的这种方法?

[英]How can I clean up this method I wrote in Java?

I'm working on writing a Maze generator. 我正在编写迷宫生成器。 I have a "Cell" class which is as follows: 我有一个“细胞”类,如下所示:

public class Cell {
    public boolean northWall;
    public boolean southWall;
    public boolean eastWall;
    public boolean westWall;

    public Cell north;
    public Cell south;
    public Cell east;
    public Cell west;

    public boolean visited;

    public Cell() {
        northWall = true;
        southWall = true;
        eastWall = true;
        westWall = true;
        visited = false;
    }

    public boolean hasUnvisitedNeighbors() {
        return ((north != null && !north.Visited)
                || (south != null && !south.Visited)
                || (east != null && !east.Visited) || (west != null && !west.Visited));
    }

    public Cell removeRandomWall() {
        List<Cell> unvisitedNeighbors = new ArrayList<Cell>();
        if (north != null && !north.Visited)
            unvisitedNeighbors.add(north);
        if (south != null && !south.Visited)
            unvisitedNeighbors.add(south);
        if (west != null && !west.Visited)
            unvisitedNeighbors.add(west);
        if (east != null && !east.Visited)
            unvisitedNeighbors.add(east);



        if (unvisitedNeighbors.size() == 0) {
            return null;
        } else {
            Random randGen = new Random();
            Cell neighbor = unvisitedNeighbors.get(randGen
                    .nextInt((unvisitedNeighbors.size())));

            if (neighbor == north) {
                northWall = false;
                north.southWall = false;
                return north;
            } else if (neighbor == south) {
                southWall = false;
                south.northWall = false;
                return south;
            } else if (neighbor == west) {
                westWall = false;
                west.eastWall = false;
                return west;
            } else if (neighbor == east) {
                eastWall = false;
                east.westWall = false;
                return east;
            }

            return null;
        }

    }
}

A maze in my program is simply a 2d dimensional array of Cells. 我程序中的迷宫只是细胞的二维数组。 After I create the array I manually go in and set all the references to the adjancent cells (North, South, East, West). 创建阵列后,我手动进入并设置对相邻单元格(北,南,东,西)的所有引用。

What I'm trying to clean up is removeRandomWall() . 我要清理的是removeRandomWall() It is suppose to randomly choose an adjacent Cell which has its visited flag set to false, and remove the wall in both this cell and the adjacent cell that connects them. 假定随机选择一个其访问标记设置为false的相邻单元,并移除此单元和连接它们的相邻单元中的墙。

So, it needs to consider all adjacent cells who haven't been visited, randomly choose one, then set the wall in this cell and the adjacent one to false so there is a path between them now. 因此,它需要考虑所有尚未访问过的相邻单元格,随机选择一个,然后将该单元格中的墙和相邻的单元格设置为false,以便它们之间现在有了一条路径。 I've attempted it above but it seems very cludgey. 我在上面尝试过,但是看起来很笨拙。

Can anyone help me out? 谁能帮我吗?

Instead of having 4 separate members: 而不是拥有4个单独的成员:

public Cell North;
public Cell South;
public Cell East;
public Cell West;

just have 1 array of them: 只有1个数组:

public Cell [] cells = new Cell[4];

And 4 constants: 还有4个常量:

public final int NORTH = 0;
public final int EAST = 1;
public final int SOUTH = 2;
public final int WEST = 3;

it makes things like remove random wall so much easier. 它使移除随机墙之类的事情变得如此容易。

Make an enumeration for the direction, then access the walls and the neighbors by giving the direction. 对该方向进行枚举,然后通过给出方向访问墙壁和邻居。

You should make your member variables private and write them in lower case. 您应该将成员变量设为私有,并以小写形式编写它们。

A first attempt, I would make the member variable private final if you can: 第一次尝试,如果可以的话,我将成员变量设为private final:

public class Cell {
    public boolean NorthWall;
    public boolean SouthWall;
    public boolean EastWall;
    public boolean WestWall;

    public Cell North;
    public Cell South;
    public Cell East;
    public Cell West;

    public boolean Visited;

    public Cell() {
        NorthWall = true;
        SouthWall = true;
        EastWall = true;
        WestWall = true;
        Visited = false;
    }

    public boolean hasUnvisitedNeighbors() {
        return unvisited(North) || unvisited(South) || unvisited(East) || unvisited(West);
    }

    private List<Cell> getUnvisitedNeighbors() {
        List<Cell> result = new ArrayList<Cell>();
        if (unvisited(North))
            result.add(North);
        if (unvisited(South))
            result.add(South);
        if (unvisited(West))
            result.add(West);
        if (unvisited(East))
            result.add(East);
        return result;
    }

    private boolean unvisited(Cell cell) {
        return cell != null && !cell.Visited;
    }

    private Cell getRandomUnvisitedNeighbor() {
        Random randGen = new Random();
        List<Cell> unvisitedNeighbors = getUnvisitedNeighbors();
        return unvisitedNeighbors.get(randGen.nextInt((unvisitedNeighbors.size())));
    }

    public Cell removeRandomWall() {
        if (!hasUnvisitedNeighbors()) {
            return null;
        }
        Cell neighbor = getRandomUnvisitedNeighbor();
        if (neighbor == North) {
            NorthWall = false;
            North.SouthWall = false;
        } else if (neighbor == South) {
            SouthWall = false;
            South.NorthWall = false;
        } else if (neighbor == West) {
            WestWall = false;
            West.EastWall = false;
        } else if (neighbor == East) {
            EastWall = false;
            East.WestWall = false;
        }

        return neighbor;

    }
}

Try to remove checks for null, by using a "null Cell" object... 尝试使用“空单元格”对象删除对空值的检查...

public static final Cell NULL_CELL = new Cell();

so where you would have use null to indicate that no such cell existed, you can now use NULL_CELL. 因此,在您将使用null指示不存在此类单元格的地方,现在可以使用NULL_CELL。

Now you can replace 现在您可以更换

if (north != null && !north.Visited)
                unvisitedNeighbors.add(north);

with

if (!north.isVisited()) {
    unvisitedNeighbors.add(north);
}

Typically in Java, member variables are private, and you use "getters" to access them... 通常,在Java中,成员变量是私有的,您可以使用“获取器”来访问它们。

private boolean northWall;
private boolean southWall;
private boolean eastWall;
private boolean westWall;

private Cell north;
private Cell south;
private Cell east;
private Cell west;

private boolean visited;

public boolean hasNorthWall() {
  return northWall;
}

public Cell getNorthCell() {
  return north;
}

// etc.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM