Hi!
I'm writing a map generator for a game that uses a hexgrid.
At the moment I'm just trying to make continents but I've been having some issues.
The current problem is that somehow more hexagons are added then exists on the map. I don't know why it happens but I can tell you a little about my generation code:
/*picks a random seed, if it randoms to water set all ungenerated neighbours
to water else add ungenerated neighbours to the m_ActiveSeeds and repeat until empty */
void Map::generateCrude(){
//mod >1 increases chance for water
int mod = 1;
//shuffle it to get a random element
random_shuffle(m_ActiveSeeds.begin(), m_ActiveSeeds.end());
pair<int,int> ID = m_ActiveSeeds.front()->getID();
//to steer the generation away from complete randomness
if(getTypeNeighbours("land", ID.first, ID.second) > 3) mod = 0.9;
if(getTypeNeighbours("water", ID.first, ID.second) > 3) mod = 1.2;
string type = randomType(mod);
cout << m_ActiveSeeds.size() << endl;
m_ActiveSeeds.front()->setTerrain(type,1);
vector<Block*> temp = getAllNeighbours(ID.first, ID.second);
if(type == "water"){
do{
// if it's already generated
if(temp.front()->terrainExists("land") || temp.front()->terrainExists("water") ){
temp.erase(temp.begin());
}
else{
//set to water and if it exists in the m_ActiveSeeds remove it from there
temp.front()->setTerrain("water", 1);
for(std::vector<Block*>::iterator it = m_ActiveSeeds.begin();it != m_ActiveSeeds.end();it++){
if(checkSameID(temp.front(), *it)){
m_ActiveSeeds.erase(it);
break;
}
}
temp.erase(temp.begin());
}
}while(temp.empty() == false);
}
else{
//else just check if the neighbours exists in the list otherwise add them.
for(int i = 0; i < temp.size();i++){
addSeed(temp.at(i));
}
}
//remove the used element
m_ActiveSeeds.erase(m_ActiveSeeds.begin());
return;
}
I've been through my program many times in the past few days but I can't find it.
And also it generates perculiar maps... it's like it's split in two from the middle and generates the same thing on both sides...
Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) are guaranteed to keep referring to the same elements they were referring to before the call.
I don't go back after I've found a matching object, because there can only be one matching object maximum. So I'm guessing pointer validity isn't a problem-
But I can't get remove_if() to work.
And what do you mean by changing? yes, I remove an element, but when I have I break the loop.
I'm going mad here, is there someway to find this problem? I'll keep looking at it today but then I'll probably just rewrite the entire thing to save time -.-.
I've added lots of safeguards to make sure that the check if it already exists works, and it appear to be doing that.
There appear to be nothing wrong with the ID system, all pointers inside the m_ActiveSeeds have allowed IDs.
And it appear to be removing the correct amount of pointers as it should.
W
W WWWW
WWWW WWW#WW
WWW#WW WW###W
WW###W WWWWW
WWWWW W W
W W
W
W WWW
WWW WW#WW
WW#WW WW#WWW W
WW#WWW W W WW####WWWWWWW
W WW####WWWWWWWWW WW#####W##WW
WW WW#####W##WW#WW WW###WWWW#W#
#WW WW###WWWW#W#WW WWW#WWWW###
WW WWW#WWWW###W WWWW WW###
W WWWW WW### W WWWW
W WWWW WWW
WWW
PS: I did couple of more small changes, just removed warnings where you are assigning a double to an int.
I'm not sure why that fixed the problem though. Must be that it now adds less then normally and therefor runs out of stuff to generate much faster, it also messes up the water generation since now the chance of water has greater chance / tile to occur.
So, I'm generating a hexmap, not a square one, so that won't do. I'm just using the textfile as a temporary solution until I fixed the first parts of this function, after that I'll make some SDL or SFML interface. Not sure which yet.
each block of the map is a hex and the world is cylindrical meaning that you can walk from the far left edge to the far right (in a step, you know what I mean).
I place a number of land spots on the map. Called seeds.
I then remove these land blocks from the list with "active seeds" simply stuff that can be generated next. and add their neighbours to that list.
I then, for the rest of the process:
1. shuffle the list.
2. Choose what it randoms to.
3. If it randoms to land then remove that seed from the list and add it's neighbours if the neighbours are not on the list.... and not already generated. Hold on might found the problem here...
Changed the Map::addSeed function so that it checks that the block isn't already generated. But now it won't generate at all, it just places the initial seeds.
brb an hour or so. btw changed the randomPlace function so that it uses push_back instead of addSeed since they are already generated when I add them.