3

I have used Libgdx to generate a dungeon out of keyboard characters. I have decided to print out the array as a text file.

However this is what I got:

I get this

Furthermore, It isn't consistent

Sometimes I get this

I don't get what is wrong? I checked over my algorithm and didn't find anything wrong.

Here is my code:

public class test1 extends ApplicationAdapter {
    SpriteBatch batch;
    Texture img;

    int X = 50;
    int Y = 25;

    ////////// # wall
    ////////// . ground
    char[][][] mapChars = new char[1000][1000][1000];

        private void genDung() {
        int clearance = 4;
        for (int i = 0; i < Y; i++) {
            for (int j = 0; j <= X; j++) {
                if(j == X)
                    mapChars[0][i][j] = '\n';
                else
                    mapChars[0][i][j] = '#';
            }
        }
        int roomCount = MathUtils.random(2, 2);
        int[] roomPosX = new int[roomCount];
        int[] roomPosY = new int[roomCount];
        int[] roomCenterPosX = new int[roomCount];
        int[] roomCenterPosY = new int[roomCount];
        int[] roomSizeX = new int[roomCount];
        int[] roomSizeY = new int[roomCount];

        for (int i = 0; i < roomCount; i++) {
            int attempts = 0;
            while(true) {
                boolean rePosition = false;
                roomPosX[i] = MathUtils.random(1, X-1);
                roomPosY[i] = MathUtils.random(1, Y-1);
                roomSizeX[i] = MathUtils.random(2, 12);
                roomSizeY[i] = MathUtils.random(2, 8);
                for(int j = 0; j <= i; j++) {
                    if(i != j) {
                        if(roomPosX[i] >= roomPosX[j] && roomPosX[i] <= (roomPosX[j] + roomSizeX[j] + clearance)) {
                            if(roomPosY[i] >= roomPosY[j] && roomPosY[i] <= (roomPosY[j] + roomSizeY[j] + clearance)) {
                                rePosition = true;
                                break;
                            }
                        }
                        if((roomPosX[i]+roomSizeX[i]) >= roomPosX[j] && (roomPosX[i]+roomSizeX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
                            if((roomPosY[i]+roomSizeY[i]) >= roomPosY[j] && (roomPosY[i]+roomSizeY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
                                rePosition = true;
                                break;
                            }
                        }
                        if((roomPosX[i]) >= roomPosX[j] && (roomPosX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
                            if((roomPosY[i]+roomSizeY[i]) >= roomPosY[j] && (roomPosY[i]+roomSizeY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
                                rePosition = true;
                                break;
                            }
                        }
                        if((roomPosX[i]+roomSizeX[i]) >= roomPosX[j] && (roomPosX[i]+roomSizeX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
                            if((roomPosY[i]) >= roomPosY[j] && (roomPosY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
                                rePosition = true;
                                break;
                            }
                        }
                    }
                    else if(roomPosX[j] + roomSizeX[j] >= X-1){
                        rePosition = true;
                    }
                    else if(roomPosY[j] + roomSizeY[j] >= Y-1){
                        rePosition = true;
                    }
                }
                attempts++;
                if(attempts >= 10000) break;
                if(!rePosition) break;
            }
        }

        for(int r = 0; r < roomCount; r++) {
            for (int a = roomPosX[r]; a <= (roomPosX[r] + roomSizeX[r]); a++) {
                for (int b = roomPosY[r]; b <= (roomPosY[r] + roomSizeY[r]); b++) {
                    mapChars[0][b][a] = '.';
                }
            }
        }

        Gdx.app.log("roomCount", String.valueOf(roomCount)+"\n\n\n");
        for(int i =0; i< roomCount; i++) {
            roomCenterPosX[i] = roomPosX[i] + roomSizeX[i]/2;
            roomCenterPosY[i] = roomPosY[i] + roomSizeY[i]/2;
            Gdx.app.log("room", String.valueOf(i)+"\n");
            Gdx.app.log("roomPosX", String.valueOf(roomPosX[i]));
            Gdx.app.log("roomPosY", String.valueOf(roomPosY[i]));
            Gdx.app.log("roomSizeX", String.valueOf(roomSizeX[i]));
            Gdx.app.log("roomSizeY", String.valueOf(roomSizeY[i])+"\n");
            Gdx.app.log("RoomCenterPosX", String.valueOf(roomCenterPosX[i]));
            Gdx.app.log("RoomCenterPosY", String.valueOf(roomCenterPosY[i])+"\n\n");
        }

        int difference = X;
        int[] roomNum = new int[2];
        for(int i = 0; i < roomCount; i++) {
            for(int j = 0; j < roomCount; j++) {
                if(i != j) {
                    if(abs(roomCenterPosX[i] - roomCenterPosX[j]) < difference) {
                        difference = abs(roomCenterPosX[i] - roomCenterPosX[j]);
                        roomNum[0] = i;
                        roomNum[1] = j;
                    }
                }
            }
        }
        Gdx.app.log("FarthestRooms", String.valueOf(roomNum[0]));
        Gdx.app.log("FarthestRooms", String.valueOf(roomNum[1]));

        int differenceX = X;
        int differenceY = Y;
        int[] connectRooms = new int[2];
//        int[] roomsConnected = new int[roomCount];

        connectRooms[0] = MathUtils.random(0, roomCount - 1);
//        roomsConnected[0] = connectRooms[0];

        int count;

        for(int i = 0; i < roomCount-1; i++) {
            int j;
            while(true) {
                connectRooms[1] = MathUtils.random(0, roomCount - 1);
/*                while (true) {
                    connectRooms[1] = MathUtils.random(0, roomCount - 1);
                    count = 0;
                    for (j = 0; j < i; j++) {
                        if (connectRooms[1] != roomsConnected[j] && connectRooms[0] != roomsConnected[j]){
                            count++;
                        }
                    }
                    if(count >= i-2)
                        break;
                }*/
                if(connectRooms[0] != connectRooms[1])
                    break;
            }
//            roomsConnected[i+1] = connectRooms[1];

            differenceX = roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]];
            differenceY = roomCenterPosY[connectRooms[0]] - roomCenterPosY[connectRooms[1]];
            if(roomCenterPosX[connectRooms[0]] < roomCenterPosX[connectRooms[1]])
                differenceX *= -1;
            if(roomCenterPosY[connectRooms[0]] < roomCenterPosY[connectRooms[1]])
                differenceY *= -1;

            int k;

            try {
                if (differenceX > 0) {
                    for (k = 0; k < differenceX; k++) {
                        mapChars[0][roomCenterPosY[i]][roomCenterPosX[i] + k] = '.';
                    }
                } else if (differenceX < 0) {
                    for (k = 0; k > differenceX; k--) {
                        mapChars[0][roomCenterPosY[i]][roomCenterPosX[i] + k] = '.';
                    }
                } else k = 0;

                if (differenceY < 0) {
                    for (int z = 0; z > differenceY; z--) {
                        mapChars[0][roomCenterPosY[i] + z][roomCenterPosX[i] + k] = '.';
                    }
                } else if (differenceY > 0) {
                    for (int z = 0; z < differenceY; z++) {
                        mapChars[0][roomCenterPosY[i] + z][roomCenterPosX[i] + k] = '.';
                    }
                } else {
                }
            }
            catch (ArrayIndexOutOfBoundsException e) {
                Gdx.app.log("Non Fatal Exception", String.valueOf(e));
            }

            Gdx.app.log("Connect", String.valueOf(connectRooms[0]));
            Gdx.app.log("Connect", String.valueOf(connectRooms[1]));
            Gdx.app.log("DifferenceX", String.valueOf(differenceX));
            Gdx.app.log("DifferenceY", String.valueOf(differenceY)+"\n");

        }

        for(int q = 0; q < Y; q++) {
            mapChars[0][q][X] = '\n';
        }
        for(int w = 0; w < Y; w++) {
            mapChars[0][w][X-1] = '#';
        }
        for(int e = 0; e < Y; e++) {
            mapChars[0][Y-1][e] = '#';
        }

    }

    private void export() {
        if(Gdx.files.isLocalStorageAvailable()) {
            FileHandle fileHandle = Gdx.files.local("map.txt");
            if(Gdx.files.local("map.txt").exists())
                fileHandle.writeString("", false);
            for(int i = 0; i<= Y; i++) {
                for (int j = 0; j <= X; j++) {
                    fileHandle.writeString(""+mapChars[0][i][j] , true);
                }
            }
        }
    }

    @Override
    public void create () {
        batch = new SpriteBatch();
        img = new Texture("badlogic.jpg");

//        genMap();
//        for(int i = 0; i< 4; i++)
//            refineMap();
        genDung();
        export();
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw(img, 0, 0);
        batch.end();

        if(Gdx.input.isTouched()) {
//            genMap();
//            for(int i = 0; i< 4; i++)
//                refineMap();
            genDung();
            export();
        }

    }
}

I want the two rooms to connect properly every time. As you can see, one of the time, the rooms connected The other time the rooms don't connect.

Thanks in advance

harshtuna
  • 757
  • 5
  • 14
Fish
  • 1,689
  • 1
  • 18
  • 28
  • did you only get the two displayed versions? Or are there more different ones? – Zorian Mar 30 '15 at 11:14
  • This is the only version, genMap() and refineMap() are both cave generation stuff – Fish Mar 30 '15 at 12:01
  • 1
    Note that you force the `difference*` variables always to positive, with the `differenceX *= -1;` lines, so the tunnels are always done to positive direction. The code would probably work without that. – kiheru Mar 30 '15 at 12:03
  • 3
    You didn't describe what you want, so there's no way to interpret what's "wrong" or know what you mean by "not consistent". Just looks like two perfectly fine dungeon layouts to me, as far as I know from looking at it. – Tenfour04 Apr 03 '15 at 13:13

1 Answers1

4

The whole thing can be simplified and definitely needs refactoring. Regarding the 2 room connection - check this piece carefully

        differenceX = roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]];
        differenceY = roomCenterPosY[connectRooms[0]] - roomCenterPosY[connectRooms[1]];
        if(roomCenterPosX[connectRooms[0]] < roomCenterPosX[connectRooms[1]])
            differenceX *= -1;
        if(roomCenterPosY[connectRooms[0]] < roomCenterPosY[connectRooms[1]])
            differenceY *= -1;

As @kiheru pointed out it is equivalent to Math.abs(roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]]) (same for Y). So you always "dig" to right and down, never up or left.

Drop that invertion and have fun with the rest of your algorithm :)

harshtuna
  • 757
  • 5
  • 14