Need help on coding a procedural dungeon

Started by BaJankens, Thu 10/11/2016 21:07:44

Previous topic - Next topic

BaJankens

So, I have a general idea of how this code should work in my head, but trying to figure out how to get it into code isn't working too well. I've been searching the forums a bit, and found this which talks about pretty much what I was thinking about. I just can't figure out how to get started. The main part I'm trying to figure out right now is getting a grid made that I can work with. I've tried using arrays, and I've messed a bit with structs, but the way I was doing that required a dynamic array within the struct, which is apparently a no-no. So if anyone has some helpful tricks, I'd greatly appreciate it.

Retro Wolf

#1
I've been working on a procedurally generated RPG. I've put it down for now, but here's how I handle 2D arrays.

GlobalScript.ash
Code: ags
#define GRID_WIDTH 20
#define GRID_HEIGHT 12


GlobalScript.asc
Code: ags

int gridArray[];

// called when the game starts, before the first room is loaded
function game_start()  {
  gridArray = new int[GRID_WIDTH * GRID_HEIGHT];
}

// sets the cell in the grid to the specified value
void set_grid(int x, int y, int value)  {
  int i = (x + (GRID_WIDTH * y));
  gridArray[i] = value;
}

// returns the value stored in the specified cell
int get_grid(int x, int y)  {
  int i = (x + (GRID_WIDTH * y));
  return gridArray[i];
}


You can also get the xy position based on the supplied array index by:
Code: ags

  int i = //the array index
  int x = (i % GRID_WIDTH);
  int y = (i / GRID_WIDTH);


This would come in useful if you wanted to loop through every cell in the grid to do stuff and things.

BaJankens

So I've been working from your code and came up with this. I feel it should be working, but it stays stuck in a loop. I'm thinking it might be because X_Axis isn't a float, and so can't create a remainder. If that were the case, is there a way to turn it into a float that is also a number for an array?

Code: ags
// main global script file



bool Ready = false;
bool RoomLoc[];

export RoomLoc;

function MazeMake(){
  RoomLoc = new bool[X_Axis * Y_Axis];
  RoomLoc[X_Axis/Y_Axis] = true;
  RoomCount --;
  while (RoomCount > 0){
  int RoomCall = Random((X_Axis * Y_Axis)-1);
  if (RoomLoc[RoomCall] == false){
    if (RoomCall - X_Axis > 0){
       if (RoomLoc[RoomCall - X_Axis] == true){
         RoomLoc[RoomCall] = true;
         RoomCount --;
       }
    }
   else if (RoomCall + X_Axis < ((X_Axis * Y_Axis) - 1) ){
     if (RoomLoc[RoomCall + X_Axis] == true){
       RoomLoc[RoomCall] = true;
       RoomCount --;
     }
   }
   else if (RoomCall % X_Axis != 0){
     if (RoomLoc[RoomCall-1] == true){
       RoomLoc[RoomCall] = true;
       RoomCount --;
     }
   }
   else if ((RoomCall + 1) % X_Axis != 0){
     if (RoomLoc[RoomCall+1] == true){
       RoomLoc[RoomCall] = true;
       RoomCount --;
     }
   }
  }
  
  }
  while (Ready == false){
    int Startit = Random((X_Axis * Y_Axis)-1);
    if (RoomLoc[Startit] == true){
      StartingLocal = Startit;
      Ready = true;
    }
  }
  }

Mandle

I believe the command is IntToFloat or something like that...The autofiller should figure it out, or if not there's always the manual...

Retro Wolf

#4
I'm having trouble understanding what exactly is going on in your code, especially since there's no comments.
I've quickly put something together, it's not tested. You'd have to modify it for your own variable names.

Code: ags
// pick a random cell in the grid, if there's a neighbour room then place one here too
void build_level  {
  
  set_grid(GRID_WIDTH/2, GRID_HEIGHT/2, true); // the starting room
  
  #define MAX_ROOMS 10
  int roomsMade = 0;
  
  while (roomsMade < MAX_ROOMS)  {
    
    // The loop could possibly run too many times here if the program keeps choosing an invalid (no neighbours) cell.
    int cell = Random((GRID_WIDTH * GRID_HEIGHT) - 1);
    int x = (cell % GRID_WIDTH);
    int y = (cell / GRID_WIDTH);
    
    // Now you will want to add some array overflow checks here, eg: if we chose a cell at the bottom of the grid
      // and we try to find a cell below it, that would be outside of the array.
    bool foundNeighbour = get_grid(x-1, y);//left
    if (foundNeighbour == false)  {foundNeighbour = get_grid(x+1, y);}//right
    if (foundNeighbour == false)  {foundNeighbour = get_grid(x, y-1);}//up
    if (foundNeighbour == false)  {foundNeighbour = get_grid(x, y+1);}//down
    
    if (foundNeighbour == true)  {
      set_grid(x, y, true);
      roomsMade++;
    }
  }
}


EDIT: Just thought to avoid going off grid.

Code: ags
// The loop could possibly run too many times here if the program keeps choosing an invalid (no neighbours) cell.
    //int cell = Random((GRID_WIDTH * GRID_HEIGHT) - 1);
    //int x = (cell % GRID_WIDTH);
    //int y = (cell / GRID_WIDTH);
    
    // the edge cells on the grid are always ignored (a border of 1 cell thick)
    int x = (1 + Random(GRID_WIDTH - 2));
    int y = (1 + Random(GRID_HEIGHT - 2));

SMF spam blocked by CleanTalk