More straightforward, until you want to do it with 6, 10, or 50 types of tiles. I'd definitely suggest Virex's way. Plus, the way that you set it up will mean that if you have two of your five values over the threshold, later checks will override earlier checks.
Good point, in fact I did that intentionally so that it draws oceans over swamps, which override beaches when present, and so on.
Of course if I where to have several more kinds of terrain a loop would be better, but I don't know how to do that yet...
Also:
I'm writing a terrain generator using C++. Unfortunately, I'm doing it after reading only the first three chapters...
Of course, it could be much more sophisticated, but I started making it for Haven & Hearth. It should eventually be possible to call something like "terrainGen(x,y)" and get a 0-5 result representing whatever the terrain at that tile is.
I'm basing it off of work I've done is AOI- in fact, I built a prototype generator using just a procedural texture:

My code at the moment:
//Peter Cymbalski; Nowhere Publishing Browninan Layer Map Generator v0.05
#include <iostream>
using namespace std;
//The Index:
float fractalMap(int,int,int);
int mapLayer(float,float,float,float,float);
void textout(int);
float floatcap(float);
int main()
{
cout << "NWP BLMG (c) Peter Cymbalski\nPlease enter the X co-ord.\n";
int iXin;
cin >> iXin;
cout << "Please enter the Y co-ord.\n";
int iYin;
cin >> iYin;
float fFracElvtn = fractalMap(iXin, iYin, 1);
float fFracSwamp = fractalMap(iXin, iYin, 2);
float fFracSand = fractalMap(iXin, iYin, 3);
float fFracForst = fractalMap(iXin, iYin, 4);
float fFracClay = fractalMap(iXin, iYin, 5);
return(0);
}
float fractalMap(int mapX, int mapY, int mapOffset) //mapX and mapY refer to the xy coords of the tile in the world. "Browninan" refers to Fractoral Browninan Motion, the basis for this generator.
{
//Offest adjustments:
mapX = mapX+(mapOffset*100);
mapY = mapY+(mapOffset*100); //*100 so that small values for mapOffset radically change the part of the noise we're looking at
//Generator fine-tuning: Universal for all layers, an improved but bulkier version may add these as variables
float fScaleLevelA = 1; //Defines the scale of the top layer of each Noise map
float fIntenseLevelA = 1; //Defines the intensity of the top layer of each Noise map
float fNLevelB = 2; //As above, for next layer intensity and scale.
float fIntenseLevelB = 0.5;
float fNLevelC = 4;
float fIntenseLevelC = 0.25;
float fLA = 0, fLB = 0, fLC = 0;
float fTotalHeight = 0;
//Combines, or "draws" the map layers and scales them:
fLA = ((Noise(mapX*fScaleLevelA),(mapY*fScaleLevelA))*fIntenseLevelA); //Draws and modifies layer A
fLB = (((Noise(mapX*fScaleLevelB),(mapY*fScaleLevelB))*fIntenseLevelB)-(0.5*fIntenseLevelB)); //Draws and modifies layer B, Displaces it for next step
fLC = (((Noise(mapX*fScaleLevelC),(mapY*fScaleLevelC))*fIntenseLevelC)-(0.5*fIntenseLevelC)); //Deaws and modifies layer C, Displaces it for next step
fTotalHeight = fLA+fLB+fLC;
fTotalHeight = floatcap(fTotalHeight);
return(fTotalHeight);
}
int mapLayer( float fElevation, float fSwamp, float fSand, float fForest, float fClay)
//BIG NOTE HERE: Replace magic numbers with variables that allow map customization, eventually
{
//subsection: transform terrain due to others. Lots of magic numbers here, but kind of unavoidable. These numbers should come from a config file, really.
float fElevSea = (fElevation-0.5); //Height above sea level.
if (fElevSea < 0) fElevSea = 0;
fElevSea = floatcap(fElevSea * 2);
fSwamp = floatcap(fSwamp-((0.4*fElevSea)-0.2));
fSand = floatcap(fSand-((1*fElevSea)-0.95));
fForest = floatcap(fForest-((0.1*fElevSea)-0.05));
fClay = floatcap(fClay+((0.4*fElevSea)-0.2));
//subsection: select tile.
int iTileOut = 0;
//Threshold variables. Magic Numbers good for changing later.
float fThElev = 0.5;
float fThSwmp = 0.5;
float fThSand = 0.5;
float fThFrst = 0.5;
float fThClay = 0.5;
if (fClay > fThClay) iTileOut = 5;
if (fForest > fThFrst) iTileOut = 4;
if (fSand > fThSand) iTileOut = 3;
if (fSwamp > fThSwmp) iTileOut = 2;
if (fElevation < fThElev) iTileOut = 1; //supposed to be reversed; if it's less than a value, it's under water!
return(iTileOut);
}
void textout(int iTerrainout)
{
if (iTerrainout = 0) cout << "Tile is grass.\n";
if (iTerrainout = 1) cout << "Tile is water.\n";
if (iTerrainout = 2) cout << "Tile is swamp.\n";
if (iTerrainout = 3) cout << "Tile is sand.\n";
if (iTerrainout = 4) cout << "Tile is forest.\n";
if (iTerrainout = 5) cout << "Tile is clay.\n";
return();
}
float floatcap(float x) //this is just used to keep the value between 0 and 1. large plateaus are OK...
{
if (x < 0) (x = 0);
if (x > 1) (x = 1);
return(x);
}What I need now is just the noise() function. Well, that and more debugging than you can shake a stick at.
What I'm trying to get is noise(float x,float y) that will return a perlin or even simplex noise for those coordinates. I've found a few, but they are rather over-implemented.
Anyone familiar with a very simple perlin function?