Jump to content

  • Log In with Google      Sign In   
  • Create Account

Random Level Builder Help


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Lance5057   Members   -  Reputation: 100

Like
0Likes
Like

Posted 30 June 2011 - 09:51 PM

Ok I'm trying to make a Level builder that'll build rooms and halls but its become rather hit and miss and I'm stuck on it. For one the checker that makes sure it wont build over itself only fires when it wants it seems and two it can go from putting completely random garbage all over to getting stuck in infinite loops.

Build Level:
#include "BL.h"

bool CollisionCheck(Tile LevelCurrent[100][100],int x,int y,int width,int height)
{
  int check=0;
  bool fin;
  for(y; y<height; y++)
  {
	for(x; x<width; x++)
	{
  	if(LevelCurrent[x][y].walkable==1)
    	check++;
	}
  }
  if(check>0)
	fin=false;
  else if(check==0)
	fin=true;
  return fin;
}

void BuildLevel(Tile LevelCurrent[100][100],int stair_x,int stair_y)
{
  bool finish=false,cont=false;
  int x,y,x2,y2,type,length,roll,counter;
  type=4;

  for(y=0; y<100; y++)
	{
  	for(x=0; x<100; x++)
  	{
    	LevelCurrent[x][y].walkable=0;
    	LevelCurrent[x][y].flag_build=0;
    	LevelCurrent[x][y].tries=0;
  	}
	}

	LevelCurrent[stair_x][stair_y].flag_build=1;
	LevelCurrent[stair_x][stair_y].tries=5;
	
	
  while(!finish)
  {	
	/*
	TYPES:
  	Halls= 0-3
  	Standard Rooms= 4-24
  	Uncommon Rooms= 25-45
  	Rare Rooms= 46-66
	*/
	type=rand()%5;
	for(y=0; y<100; y++)
	{
  	for(x=0; x<100; x++)
  	{  	
    	
//===========HALLS============================================================================================//
    	//===UpHall============//
    	if((LevelCurrent[x][y].flag_build==1||LevelCurrent[x][y].flag_build==2)&&type==0)
    	{
      	length=rand()%20;
      	while(!CollisionCheck(LevelCurrent,x,y-length,1,length)&&y-length>4)
      	{
        	if(length<=4)
          	break;
        	length--;
      	}
      	if(length>4)
      	{
        	for(int i=0; i<length; i++)
        	{
          	LevelCurrent[x][y-i].walkable=1;
        	}
        	LevelCurrent[x][y].flag_build=0;
        	LevelCurrent[x][y-length].flag_build=1;
      	}
      	else{
        	if(LevelCurrent[x][y].tries>0)
          	LevelCurrent[x][y].tries++;
        	else
          	LevelCurrent[x][y].flag_build=0;
      	}
    	}
    	//=====================//

    	//===RightHall=========//
    	if((LevelCurrent[x][y].flag_build==2)&&type==1)
    	{
      	length=rand()%20;
      	while(!CollisionCheck(LevelCurrent,x,y,length,1)&&x+length<92)
      	{
        	if(length<=4)
          	break;
        	length--;
      	}
      	if(length>4)
      	{
        	for(int i=0; i<length; i++)
        	{
          	LevelCurrent[x+i][y].walkable=1;
        	}
        	LevelCurrent[x][y].flag_build=0;
        	LevelCurrent[x+length][y].flag_build=1;
      	}
      	else{
        	if(LevelCurrent[x][y].tries>0)
          	LevelCurrent[x][y].tries++;
        	else
          	LevelCurrent[x][y].flag_build=0;
      	}
    	}
    	//=====================//

    	//===DownHall==========//
    	if((LevelCurrent[x][y].flag_build==2)&&type==2)
    	{
      	length=rand()%20;
      	while(!CollisionCheck(LevelCurrent,x,y,1,length)&&y+length<92)
      	{
        	if(length<=4)
          	break;
        	length--;
      	}
      	if(length>4)
      	{
        	for(int i=0; i<length; i++)
        	{
          	LevelCurrent[x][y+i].walkable=1;
        	}
        	LevelCurrent[x][y].flag_build==0;
        	LevelCurrent[x][y+length].flag_build=1;
      	}
      	else{
        	if(LevelCurrent[x][y].tries>0)
          	LevelCurrent[x][y].tries++;
        	else
          	LevelCurrent[x][y].flag_build=0;

      	}
    	}
    	//=====================//

    	//===LeftHall==========//
    	if((LevelCurrent[x][y].flag_build==2)&&type==3)
    	{
      	length=rand()%20;
      	while(!CollisionCheck(LevelCurrent,x-length,y,length,1)&&x-length>4)
      	{
        	if(length<=4)
          	break;
        	length--;
      	}
      	if(length>4)
      	{
        	for(int i=0; i<length; i++)
        	{
          	LevelCurrent[x-1][y].walkable=1;
        	}
        	LevelCurrent[x][y].flag_build=0;
        	LevelCurrent[x-length][y].flag_build=1;
      	}
      	else{
        	if(LevelCurrent[x][y].tries>0)
          	LevelCurrent[x][y].tries++;
        	else
          	LevelCurrent[x][y].flag_build=0;
      	}
    	}
    	//=====================//
//============================================================================================================//

//===========COMMON_ROOMS=====================================================================================//

        	//Diamond - Medium - Type 4
    	if(LevelCurrent[x][y].flag_build==1&&type==4)
    	{
        	if(CollisionCheck(LevelCurrent,x-3,y-3,7,7))
        	{
        	//=Y-3========================//
        	LevelCurrent[x][y-3].walkable=1;
        	//============================//

        	//=Y-2========================//
        	LevelCurrent[x-1][y-2].walkable=1;
        	LevelCurrent[x][y-2].walkable=1;
        	LevelCurrent[x+1][y-2].walkable=1;
        	//============================//

        	//=Y-1========================//
        	LevelCurrent[x-2][y-1].walkable=1;
        	LevelCurrent[x-1][y-1].walkable=1;
        	LevelCurrent[x][y-1].walkable=1;
        	LevelCurrent[x+1][y-1].walkable=1;
        	LevelCurrent[x+2][y-1].walkable=1;
        	//============================//

        	//=Y+0========================//
        	LevelCurrent[x-3][y].walkable=1;
        	LevelCurrent[x-2][y].walkable=1;
        	LevelCurrent[x-1][y].walkable=1;
        	LevelCurrent[x][y].walkable=1;
        	LevelCurrent[x+1][y].walkable=1;
        	LevelCurrent[x+2][y].walkable=1;
        	LevelCurrent[x+3][y].walkable=1;
        	//============================//

        	//=Y+1========================//
        	LevelCurrent[x-2][y+1].walkable=1;
        	LevelCurrent[x-1][y+1].walkable=1;
        	LevelCurrent[x][y+1].walkable=1;
        	LevelCurrent[x+1][y+1].walkable=1;
        	LevelCurrent[x+2][y+1].walkable=1;
        	//============================//

        	//=Y+2========================//
        	LevelCurrent[x-1][y+2].walkable=1;
        	LevelCurrent[x][y+2].walkable=1;
        	LevelCurrent[x+1][y+2].walkable=1;
        	//============================//

        	//=Y+3========================//
        	LevelCurrent[x][y+3].walkable=1;
        	//============================//

        	//=Flags======================//
        	if(LevelCurrent[x][y+4].walkable==0&&y+4<92) LevelCurrent[x][y+3].flag_build=2;
        	if(LevelCurrent[x][y-4].walkable==0&&y-4>4) LevelCurrent[x][y-3].flag_build=2;
        	if(LevelCurrent[x+4][y].walkable==0&&x+4<92) LevelCurrent[x+3][y].flag_build=2;
        	if(LevelCurrent[x-4][y].walkable==0&&x-4>4) LevelCurrent[x-3][y].flag_build=2;
        	//============================//
        	//=Tries======================//
        	if(LevelCurrent[x][y+4].walkable==0&&y+4<92) LevelCurrent[x][y+3].tries=5;
        	if(LevelCurrent[x][y-4].walkable==0&&y-4>4) LevelCurrent[x][y-3].tries=5;
        	if(LevelCurrent[x+4][y].walkable==0&&x+4<92) LevelCurrent[x+3][y].tries=5;
        	if(LevelCurrent[x-4][y].walkable==0&&x-4>4) LevelCurrent[x-3][y].tries=5;
        	//============================//
        	LevelCurrent[x][y].tries=0;
        	}
        	/*else{
          	if(LevelCurrent[x][y].tries>0)
            	LevelCurrent[x][y].tries++;
          	else
            	LevelCurrent[x][y].flag_build=0;
      	}*/
    	}

//============================================================================================================//

//===========RARE_ROOMS=======================================================================================//

        	//Hall Of Heroes - Type 46
        	if(type==46)
        	{

        	}
//============================================================================================================//
      	}
    	}
  	counter=0;
   for(y2=0; y2<100; y2++)
	{
  	for(x2=0; x2<100; x2++)
  	{
    	if(LevelCurrent[x2][y2].flag_build!=0)
      	counter++;
  	}
	}
   if(counter==0)
 	finish=true;
   counter=0;
  }
return;
}


I'm at a complete lose at this point so any help would be greatly appreciated. Thanks.

Sponsor:

#2 PrestoChung   Members   -  Reputation: 184

Like
1Likes
Like

Posted 30 June 2011 - 09:54 PM

Have you tried debugging it step-by-step?

Maybe adding some asserts would help pinpoint the problem(s).

#3 Lance5057   Members   -  Reputation: 100

Like
0Likes
Like

Posted 30 June 2011 - 09:59 PM

Have you tried debugging it step-by-step?

Maybe adding some asserts would help pinpoint the problem(s).


Yea I've debugged if for a few hours now and I still cant find the issue.

#4 LorenzoGatti   Crossbones+   -  Reputation: 2694

Like
2Likes
Like

Posted 01 July 2011 - 02:56 AM

CollisionCheck() reports true if any walkable cell is in the portion of the map with coordinates between (x,y) and (width,height): it doesn't seem to match the call in BuildLevel(); parameter values are not checked; it assumes x<=width and y<=height; the parameters aren't, obviously, a width and height; you shouldn't iterate using x and y.
[source lang="cpp"]bool CollisionCheck(const Tile** LevelCurrent, const int x1,const int y1,const int x2,const int y2,const int width,const int height){ int xmin,xmax,ymin,ymax;//iteration limits if(x1>x2) { xmin=x2; xmax=x1; } else { xmin=x1; xmax=x2; } if(y1>y2) { ymin=y2; ymax=y1; } else { ymin=y1; ymax=y2; } if (xmin<0) xmin=0; if (ymin<0) ymin=0; if (xmax>width) xmax=width; if (ymax>height) ymax=height; for(int y=ymin; y<ymax; y++) { for(int x=xmin; x<xmax; x++) { if(LevelCurrent[x][y].walkable==1)//should probably be a bool, not an integer //if(LevelCurrent[x][y].walkable) return false; } } return true;}[/source]
Produci, consuma, crepa

#5 Lance5057   Members   -  Reputation: 100

Like
0Likes
Like

Posted 07 July 2011 - 12:46 AM

Ok I got the issues with the checking function (Thanks Lorenzo) and they now work fine with building the rooms but the hallways still build over everything as if nothing is there.


Here's how it does hallways moving up. All the other hall builders are basically the same as this.
if((LevelCurrent[x][y].flag_build==1||LevelCurrent[x][y].flag_build==2)&&type==0)
    	{
      	length=rand()%10;
      	while(!cont||y-length<4||!CollisionCheck(LevelCurrent,x,y-length,x,y))
      	{
   		length--;
   		if(length<=4)
          	cont=true;
      	}
      	if(length>4&&y>4&&LevelCurrent[x][y].direction!=2)
      	{
        	for(int i=0; i<length; i++)
        	{
          	LevelCurrent[x][y-i].walkable=1;
        	}
        	LevelCurrent[x][y].flag_build=0;
        	LevelCurrent[x][y-length].flag_build=1;
        	LevelCurrent[x][y-length].tries=5;
        	LevelCurrent[x][y-length].direction=0;
      	}
      	else
      	{
        	if(LevelCurrent[x][y].tries>0)
          	LevelCurrent[x][y].tries--;
        	else if(LevelCurrent[x][y].tries==0)
          	LevelCurrent[x][y].flag_build=0;
      	}
    	}

I'm starting to think I'm doing halls all wrong to be honest. Any input would be great.

Edit: Also if I set the compiler to Release instead of Debug (MS VC++ 2010) and set a break in the collision check function it claims it will never be hit.

#6 rip-off   Moderators   -  Reputation: 8212

Like
1Likes
Like

Posted 07 July 2011 - 02:22 AM

Don't debug Release builds unless you're trying to reproduce an error that only happens in Release. Debugging Release builds is a tedious process.

Have you considered putting some output into this function? For some processes, debugging step-by-step is too fine grained to figure out what is going wrong. Instead, if you printed a representation of the level at the start of each loop (possibly pausing the generation in the process), you'd be clearly able to see what was happening. Once you figure out where it is going wrong, you can use the debugger to find out why.

Your function is very big. One thing that might help narrow it down is to split it into several smaller functions.

A different idea is to build the rooms first and then create the tiled level from it. So you might build a set of objects which represent the topology of the level in terms of rooms, corridors, etc. Then use a second pass to turn that into a tile map.

#7 Lance5057   Members   -  Reputation: 100

Like
0Likes
Like

Posted 07 July 2011 - 03:59 AM

Ah I've discovered the source of the issue! My only issue now is that I don't know how to actually fix it.

CollisionCheck snippet:
  for(int y=x1; y<y2; y++)
  {
    	for(int x=x1; x<x2; x++)
    	{
      	if(LevelCurrent[x][y].walkable==1) 		
     		return false;
    	}
  } 
  return true;

The issue is that since the halls are 1 tile in width whenever it goes through y<y2 or x<x2 its equal to it so it just passes by without being checked.

y=y1;
x=x1;

  while(y<=y2)
  {
    	while(x<=x2)
    	{
      	if(LevelCurrent[x][y].walkable==1) 		
     		return false;
      	x++;
    	}
   y++;
  } 
  return true;
^ I tried doing this so it wouldnt just pass on and the only thing it would do after that was build halls straight up for some odd reason.

Ya know what disregard all of that I completely forgot about do while loops and it's now working perfectly. Thank you all for your help.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS