0

I'm developing a map generator in java for my top down shooter game and I'm implementing something similar to what nuclear throne does. It creates a "walker" that runs through the map creating floor tiles.There is a chance that it will turn 90, -90 and 180 degrees after it moves one tile.

The walker its supposed to run until the desired number of floor tiles are placed.

The function sometimes takes forever and the times it works returns a map that has less floor tiles than its supposed to and it always has the same estrange pattern. This is an example output:

 00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000010000000000000000000000
00000000000000000000000000011000000000000000000000
00000000000000000000000000001111000000000000000000
00000000000000000000000000000001100000000000000000
00000000000000000000000000000000100000000000000000
00000000000000000000000000000000110000000000000000
00000000000000000000000000000000011000000000000000
00000000000000000000000000000000001100000000000000
00000000000000000000000000000000000111000000000000
00000000000000000000000000000000000001110000000000
00000000000000000000000000000000000000010000000000
00000000000000000000000000000000000000011000000000
00000000000000000000000000000000000000001100000000
00000000000000000000000000000000000000000111000000
00000000000000000000000000000000000000000001000000
00000000000000000000000000000000000000000001100000
00000000000000000000000000000000000000000000100000
00000000000000000000000000000000000000000000110000
00000000000000000000000000000000000000000000011000
00000000000000000000000000000000000000000000001000
00000000000000000000000000000000000000000000001110
00000000000000000000000000000000000000000000000011  

1 being floor tiles. 0 begin nothing.

That map has only 44 floor tiles and the generateMap funcion was called with 50 desired floor tiles.

Here its my code:

public static int[][]generateMap(int floorTiles){
    int map[][] = new int[floorTiles][floorTiles];
    int currentX, currentY;
    for (int x = 0; x<floorTiles;x++){
        for (int y = 0; y<floorTiles;y++){
            map[x][y] = 0;
        }
    }
    boolean movingThroughX = true;
    boolean Forward = true;
    Random rand = new Random();
    int counter = 0;
    int decide = 0;
    currentX = (floorTiles/8)*2 + (int)(Math.random() * ((floorTiles/8)*6 - (floorTiles/8)*2) + 1);
    currentY = (floorTiles/8)*2 + (int)(Math.random() * ((floorTiles/8)*6 - (floorTiles/8)*2) + 1);
    while(counter < floorTiles){
        if(map[currentX][currentY] ==0){
            map[currentX][currentY] = 1;
            counter++;
        }

        //aply movement
        if(movingThroughX){
            if(Forward){
                if(currentX<floorTiles-1){
                    currentX++;
                }
            }else{
                if(currentX>floorTiles+1){
                    currentX--;
                }
            }
        }else{
            if(Forward){
                if(currentY<floorTiles-1){
                    currentY++;
                }
            }else{
                if(currentY>floorTiles+1){
                    currentY--;
                }
            }
        }

        decide = rand.nextInt(100);
        if(decide<20){
            //keep walking forward
        }
        else if(decide<45){
            //turn 90degres
            if(movingThroughX){
                if(Forward){
                    movingThroughX = false;
                    Forward = false;
                }else{
                    movingThroughX = false;
                    Forward = true;
                }
            }else{
                if(Forward){
                    movingThroughX = true;
                    Forward = true;
                }else{
                    movingThroughX = false;
                    Forward = true;
                }
            }
        }else if(decide<70){
            //turn -90degres
            if(movingThroughX){
                if(Forward){
                    movingThroughX=false;
                    Forward = true;
                }else{
                    movingThroughX = false;
                    Forward = false;
                }
            }else{
                if(Forward){
                    movingThroughX = true;
                    Forward = false;
                }else{
                    movingThroughX = true;
                    Forward = true;
                }
            }
        }else{
            //turn 180 degres
            Forward = !Forward;
        }


    }
    return map;

}

I have no idea of whats wrong with it.

rai nalasa
  • 849
  • 1
  • 12
  • 32
Juan Alvarez
  • 29
  • 1
  • 6
  • You use the same values for `movingThroughX`/`Forward` twice. Shouldn't there be 4 distinct cases? – Jongware May 15 '16 at 01:07
  • You are right but that wasent the problem since i still get the ascendent patron and less floortiles than expected – Juan Alvarez May 15 '16 at 01:10
  • Shouldn't there be a movingThroughX and a movingThroughY? I only see X. Also, I highly recommend that, instead of representing direction with booleans, you should use "dx" and "dy" integers to represent the change in position with the next step. Print those and you'll easily be able to see the direction that it SHOULD be moving. That will make your code a lot easier to debug. – Luke May 15 '16 at 01:14
  • When moving throughX is false your moving ThroughY since i cant have diagonal movement since that would make unreachable map spaces – Juan Alvarez May 15 '16 at 01:16
  • Also, your "applyMovement" code looks incorrect. You should do currentX += dx; currentY += dy (however you choose to represent dx and dy). Then you should check array bounds. E.g. set currentX = min(max(0,currentX),floorTiles-1) – Luke May 15 '16 at 01:18

1 Answers1

0

I got it working

public static int[][]generateMap(int floorTiles){
    int map[][] = new int[floorTiles][floorTiles];
    int currentX, currentY;
    for (int x = 0; x<floorTiles;x++){
        for (int y = 0; y<floorTiles;y++){
            map[x][y] = 0;
        }
    }
    int dx, dy;
    dx = 0;
    dy= 1;
    Random rand = new Random();
    int counter = 0;
    int decide = 0;
    currentX = (floorTiles/8)*2 + (int)(Math.random() * ((floorTiles/8)*6 - (floorTiles/8)*2) + 1);
    currentY = (floorTiles/8)*2 + (int)(Math.random() * ((floorTiles/8)*6 - (floorTiles/8)*2) + 1);
    while(counter < floorTiles){

        //rotate
        decide = rand.nextInt(100);
        if(decide<25){

        }else if(decide<50){
            if(dx == 1){
                dy = -1;
                dx = 0;
            }else if(dx == -1){
                dy = 1;
                dx = 0;
            }else if(dy == 1){
                dx = 1;
                dy = 0;
            }else{
                dx = -1;
                dy = 0;
            }
        }else if(decide<75){
            if(dx == 1){
                dy = 1;
                dx = 0;
            }else if(dx == -1){
                dy = -1;
                dx = 0;
            }else if(dy == 1){
                dx = -1;
                dy = 0;
            }else{
                dx = 1;
                dy = 0;
            }
        }else{
            dx = -dx;
            dy = -dy;
        }


        //aply movement
        currentX += dx; 
        currentY += dy;
        currentX = Math.min(Math.max(0,currentX),floorTiles-1);
        currentY = Math.min(Math.max(0,currentY),floorTiles-1);


        //place tiles

        if(map[currentX][currentY] == 0){
            map[currentX][currentY] = 1;
            counter++;
        }


    }
    return map;

}
Juan Alvarez
  • 29
  • 1
  • 6