Reputation: 251
I am trying to generate a random 2D array, from a number of smaller arrays. I plan to use it some day to generate a random game map.
Each smaller array is called "Island". Each of them is manually predefined.
char[,] Island1 = new char[,]
{
{'A', 'A', 'A'},
{'A','B','A'},
{'A','A','A'}
};
char[,] Island2 = new char[,]
{
{'C', 'C'},
{'C','C'}
};
char[,] Island3 = new char[,]
{
{'D', 'D', 'D'},
{'D','D','D'},
{'D','D','D'}
};
I am trying to generate a larger array, with all smaller ones inside, placed randomly.
What's important, is that smaller arrays shouldn't overlap each other.
public static Boolean CanPlaceIsland(int StartX, int StartY, Island thisIsland)
{
Boolean Answer = true;
for (int i = StartX; i<StartX+thisIsland.CellArray.GetLength(0);i++)
{
for (int j = StartX; j<StartY+thisIsland.CellArray.GetLength(1);j++)
{
if (WorldMap[i,j].Terrain!='.')
Answer = false;
}
}
return Answer;
}
I am trying to go through each island, one by one, and only add new one, if it doesn't overlap non-empty squares.
Here's updated method for filling the map with islands (previous version could cause infinite loop).
public static void CreateEmptyMap()
{
WorldMap = new Cell[WorldX, WorldY];
for (int i=0; i<WorldX; i++)
for (int j=0; j<WorldY; j++)
WorldMap[i,j] = new Cell('.');
}
public static void FillMap()
{
int IslandsPlaced=0;
foreach(Island thisIsland in IslandsList)
{
Boolean check = false;
int x = 0;
int y = 0;
Random w = rnd;
int SideA = thisIsland.CellArray.GetLength(0);
int SideB = thisIsland.CellArray.GetLength(1);
int WorldSideA = WorldMap.GetLength(0);
int WorldSideB = WorldMap.GetLength(1);
x = w.Next(2, WorldSideA-SideA-1);
y = w.Next(2,WorldSideB-SideB-1);
check = CanPlaceIsland(x,y,thisIsland);
if (check==true)
{
PlaceIsland(x,y,thisIsland);
IslandsPlaced++;
}
}
if (IslandsPlaced!=IslandsList.Count())
{
CreateEmptyMap();
FillMap();
}
}
The placing:
public static void PlaceIsland(int x, int y, Island thisIsland)
{
int SideA = thisIsland.CellArray.GetLength(0);
int SideB = thisIsland.CellArray.GetLength(1);
for (int i=0; i<SideA;i++)
{
for (int j=0; j<SideB;j++)
{
WorldMap[x+i,y+j] = thisIsland.CellArray[i,j];
}
}
}
However, sometimes islands still overlap, and I can't find why.
..........
..........
..........
..........
....AAA...
..DDDBA...
..DDDAA...
..DDD.....
..........
..........
Upvotes: 1
Views: 185
Reputation: 32740
Your bug is in CanPlaceIsland
:
for (int j = StartX; //error here!
j < StartY + thisIsland.CellArray.GetLength(1);
j++) { ... }
Should be:
for (int j = StartY;
j < StartY + thisIsland.CellArray.GetLength(1);
j++) { ... }
Looks like a typical copy and paste bug...
Apart from that, if your maps are rather crowded, you risk entering an infinite loop if there is no solution for a given island.
Computing if one or more valid solutions exist and if the combination you are currently in is one of them can be expensive and somewhat tricky so, unless you really have to deal with crowded maps where a solution must be given, I'd bale out after a predetermined number of failed attempts placing an island; you might get false negatives once in a while but its probably something you can live with.
Upvotes: 1