android中迷宫生成的递归除法算法

时间:2014-09-28 12:52:54

标签: android algorithm recursion implementation division

我有用于递归分割算法的java代码,它可以生成一个完美的迷宫,但问题是我想实现它,并且无法找到一种方法在android中打印生成的迷宫...因为它生成了一个字符数组垂直线“|”另一个用于水平线“ - ”。 我试图在两个数组上循环并绘制一条垂直线,如果“|”和一条水平线,如果“ - ”但显然不起作用,因为我无法在Android活动上设置线条的正确位置。 那么如何设置绘制迷宫的位置与生成完全一致? OR是他们在android上算法的另一个实现吗?

这是我使用的实现:

package com.jforeach.mazegame;

import java.util.*;
import android.util.Log;

class RecursiveDivision
{

    static final char VWALL = '|';
    static final char HWALL = '-';

    static final char MAZE_PATH = ' ';

    int rows;
    int cols;
    int act_rows;
    int act_cols;

    char[][] board;

    public RecursiveDivision(int row, int col)
    {

        //initialize instance variables
        rows = row*2+1;
        cols = col*2+1;
        act_rows = row;
        act_cols = col;
        board = new char[rows][cols];

        //set the maze to empty     
     /*   for(int i=0; i<rows; i++){
            for(int j=0; j<cols; j++){
                board[i][j] = MAZE_PATH;
            }
        }*/

        //make the outter walls
        for(int i=0; i<rows; i++){
            board[i][0] = VWALL;
            board[i][cols-1] = VWALL;
        }

        for(int i=0; i<cols; i++){
            board[0][i] = HWALL;
            board[rows-1][i] = HWALL;
        }


    }

    //storefront method to make the maze
    public void makeMaze()
    {
        makeMaze(0,cols-1,0,rows-1);
        makeOpenings();


    }

    //behind the scences actual mazemaking
    private void makeMaze(int left, int right, int top, int bottom)
    {
        int width = right-left;
        int height = bottom-top;

        //makes sure there is still room to divide, then picks the best
        //direction to divide into
        if(width > 2 && height > 2){

            if(width > height)
                divideVertical(left, right, top, bottom);

            else if(height > width)
                divideHorizontal(left, right, top, bottom);

            else if(height == width){
                Random rand = new Random();
                boolean pickOne = rand.nextBoolean();

                if(pickOne)
                    divideVertical(left, right, top, bottom);
                else
                    divideHorizontal(left, right, top, bottom);
            }
        }else if(width > 2 && height <=2){
            divideVertical(left, right, top, bottom);
        }else if(width <=2 && height > 2){
            divideHorizontal(left, right, top, bottom);
        }
    }

    private void divideVertical(int left, int right, int top, int bottom)
    {
        Random rand = new Random();

        //find a random point to divide at
        //must be even to draw a wall there
        int divide =  left + 2 + rand.nextInt((right-left-1)/2)*2;

        //draw a line at the halfway point
        for(int i=top; i<bottom; i++){
            board[i][divide] = VWALL;
        }

        //get a random odd integer between top and bottom and clear it
        int clearSpace = top + rand.nextInt((bottom-top)/2) * 2 + 1;

        board[clearSpace][divide] = MAZE_PATH;

        makeMaze(left, divide, top, bottom);
        makeMaze(divide, right, top, bottom);
    }

    private void divideHorizontal(int left, int right, int top, int bottom)
    {
        Random rand = new Random();

        //find a random point to divide at
        //must be even to draw a wall there
        int divide =  top + 2 + rand.nextInt((bottom-top-1)/2)*2;
        if(divide%2 == 1)
            divide++;

        //draw a line at the halfway point
        for(int i=left; i<right; i++){
            board[divide][i] = HWALL;
        }

        //get a random odd integer between left and right and clear it
        int clearSpace = left + rand.nextInt((right-left)/2) * 2 + 1;

        board[divide][clearSpace] = MAZE_PATH;

        //recur for both parts of the newly split section
        makeMaze(left, right, top, divide);
        makeMaze(left, right, divide, bottom);
    }

    public void makeOpenings(){

        Random rand = new Random(); //two different random number generators
        Random rand2 = new Random();//just in case

        //a random location for the entrance and exit
       int entrance_row = rand.nextInt(act_rows-1) * 2 +1;
       int exit_row = rand2.nextInt(act_rows-1) * 2 +1;

        //clear the location
        board[entrance_row][0] = MAZE_PATH;
        board[exit_row][cols-1] = MAZE_PATH;

    }

    public void printMaze()
    {           
        for(int i=0; i<rows; i++){
            for(int j=0; j<cols; j++){

                Log.d("MAZE",  i +" "+ j+" "+ String.valueOf(board[i][j]));

            }
        }
    }


    public Maze getMaze()
    {
        Maze maze = convert();
        return maze;
    }
}

提前致谢。

1 个答案:

答案 0 :(得分:1)

这种迷宫生成算法非常有效。请注意,最终的board数组中有4个可能的字符:pipe,minus,space和0 ascii character。我注意到墙之间确实没有真正的区别,因为你可以将它们视为块。所以也许你应该画出填充的矩形而不是绘制线条。看看这个打印迷宫的功能:

public void printMaze2()
{           
    for(int i=0; i<rows; i++){
        for(int j=0; j<cols; j++){
            System.out.print((board[i][j]));
        }
        System.out.println("");
    }
}

public void printMaze3()
{           
    for(int i=0; i<rows; i++){
        for(int j=0; j<cols; j++){
            if (board[i][j]==MAZE_PATH) System.out.print(" ");
            else if (board[i][j]==VWALL) System.out.print("#");
            else if (board[i][j]==HWALL) System.out.print("#");
            else System.out.print(" "); // this last case is for \0 
        }
        System.out.println("");
    }
}