迷宫示例不生成迷宫

时间:2018-08-09 17:41:17

标签: android recursive-backtracking

我正在关注youtube Android Programming - Maze Game Pt4 上的迷宫游戏教程

视频中的导师代码会产生随机迷宫。我一直在代码后面加上“ T”,但是我的模拟器仅给出以下输出- My emulator's output

这是我的代码。谁能告诉我我所关注的教程所遗漏的内容,或者该教程本身是否存在一些编码错误? -

public class MazaGame extends View {
    private Cell[][] cells;
    private static final int COLS = 7, ROWS = 10;
    private static final float WALL_THICKNESS = 4;
    private float cellSize,hMargin,vMargin;
    private Paint wallPaint;
    private Random random;

    public MazaGame(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        wallPaint = new Paint();
        wallPaint.setColor(Color.BLACK);
        wallPaint.setStrokeWidth(WALL_THICKNESS);

        random = new Random();

        createMaze();
    }

    private Cell getNeighbor(Cell cell){
        ArrayList<Cell> neighbors = new ArrayList<>();

        //left neighbor
        if(cell.col >0)
            if(!cells[cell.col-1][cell.row].visited)
                neighbors.add(cells[cell.col-1][cell.row]);

        //right neighbor
        if(cell.col < COLS-1)
            if(!cells[cell.col+1][cell.row].visited)
                neighbors.add(cells[cell.col+1][cell.row]);

        //top neighbor
        if(cell.row >0)
            if(!cells[cell.col][cell.row-1].visited)
                neighbors.add(cells[cell.col][cell.row-1]);

        //bottom neighbor
        if(cell.row < ROWS-1)
            if(!cells[cell.col][cell.row+1].visited)
                neighbors.add(cells[cell.col][cell.row+1]);

        if(neighbors.size()>0) {
            int index = random.nextInt(neighbors.size());
            return neighbors.get(index);
        }
        return null;
    }

    private void removeWall(Cell current, Cell next){
        if(current.col == next.col && current.row == next.row+1){
            current.topWall = false;
            next.bottomWall = false;
        }

        if(current.col == next.col && current.row == next.row-1){
            current.bottomWall = false;
            next.topWall = false;
        }

        if(current.col == next.col+1 && current.row == next.row){
            current.leftWall = false;
            next.rightWall = false;
        }

        if(current.col == next.col-1 && current.row == next.row){
            current.rightWall = false;
            next.leftWall = false;
        }
    }

    private void createMaze() {
        Stack<Cell> stack = new Stack<>();
        Cell current, next;

        cells = new Cell[COLS][ROWS];

        for (int x = 0; x < COLS; x++) {
            for (int y = 0; y < ROWS; y++) {
                cells[x][y] = new Cell(x, y);
            }
        }
        do {
            current = cells[0][0];
            current.visited = true;

            next = getNeighbor(current);
            if (next != null) {
                removeWall(current, next);
                stack.push(current);
                current = next;
                current.visited = true;
            } else
                current = stack.pop();
        }while (!stack.empty());
    }
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.RED);

        int width = getWidth();
        int height = getHeight();

        if(width/height < COLS/ROWS)
            cellSize = width/(COLS+1);
        else
            cellSize = height/(ROWS+1);

        hMargin = (width-COLS*cellSize)/2;
        vMargin = (height-ROWS*cellSize)/2;

        canvas.translate(hMargin,vMargin);

        for(int x=0;x<COLS;x++){
            for(int y=0;y<ROWS;y++){
                if(cells[x][y].topWall)
                    canvas.drawLine(
                            x*cellSize,
                            y*cellSize,
                            (x+1)*cellSize,
                            y*cellSize,
                            wallPaint);

                if(cells[x][y].leftWall)
                    canvas.drawLine(
                            x*cellSize,
                            y*cellSize,
                            x*cellSize,
                            (y+1)*cellSize,
                            wallPaint);

                if(cells[x][y].bottomWall)
                    canvas.drawLine(
                            x*cellSize,
                            (y+1)*cellSize,
                            (x+1)*cellSize,
                            (y+1)*cellSize,
                            wallPaint);

                if(cells[x][y].rightWall)
                    canvas.drawLine(
                            (x+1)*cellSize,
                            y*cellSize,
                            (x+1)*cellSize,
                            (y+1)*cellSize,
                            wallPaint);
            }
        }
    }

    private class Cell{
        boolean
            topWall = true,
            rightWall = true,
            bottomWall = true,
            leftWall = true,
            visited = false;

        int col,row;

        public Cell(int col, int row) {
            this.col = col;
            this.row = row;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我不会花时间完全内部化您发布的代码的100%,但是此部分看起来可疑:

    do {
        current = cells[0][0];
        current.visited = true;

        next = getNeighbor(current);
        if (next != null) {
            removeWall(current, next);
            stack.push(current);
            current = next;
            current.visited = true;
        } else
            current = stack.pop();
    }while (!stack.empty());

我怀疑您希望它看起来像这样:

    current = cells[0][0];
    current.visited = true;

    do {
        next = getNeighbor(current);
        if (next != null) {
            removeWall(current, next);
            stack.push(current);
            current = next;
            current.visited = true;
        } else
            current = stack.pop();
    }while (!stack.empty());

您现在拥有的内容将连续地将current重置为(0,0)的单元格,因为每次通过循环,您都在执行

current = cells[0][0];
current.visited = true;

我怀疑这只是第一个单元的初始设置,并且您不希望每次循环都发生这种情况。