//Create intager map void CreateMap() { //Generate primary biome and apply automata map = stdMath.GenerateMatrix(mapSize, primeSpawnRate); map = stdMath.CellularAutomata(map, refinements, birthLimit, deathLimit, countCenter, countOutside); //create primary influence map mapInfluence = stdMath.BiomeInfluenceMapper(map, 1); //cycle through number of biomes for (int i = 0; i < numBiomes - 1; i++) { //create modified biome int[,] mat = stdMath.ModifiedMatrix(mapSize, subSpawnRate, refinements, birthLimit, deathLimit, mapInfluence); //create biomes mat = biomeRules.AutomataToBiome(mat, 2, birthLimit, deathLimit); //Assign random/ set sub biome int sub = (useRandomSub | i > 0) ? biomeRules.GetNewBiome((int)primeTile) : (int)subTile; mat = stdMath.ConvertMatrix(mat, sub); //apply biome rules mat = biomeRules.ApplyRules(mat, sub, false); //check if first biome created if (i == 0) { biomes.Add(mat); biomeKey.Add(stdMath.TilesInMatrix(mat, sub)); } else { //establish number of tiles in current biome int tiles = stdMath.TilesInMatrix(mat, sub); //Not first Biome. Cycle biome list for (int b = 0; b < biomes.Count; b++) { //check if the number of tiles in current matrix is less than the number in the current element. if (!(tiles < biomeKey [b])) { //More tiles in current matrix. Insert current matrix before current element. biomes.Insert(b, mat); biomeKey.Insert(b, tiles); break; } else if (b == biomes.Count - 1) { //if less tiles in current matrix than any others add to the end biomes.Add(mat); biomeKey.Add(tiles); } } } } //cycle biomes list to create combined biome map int[,] biomeMap = new int[mapSize, mapSize]; for (int i = 0; i < biomes.Count; i++) { Debug.Log("Biome " + i + " has " + biomeKey [i] + " tiles"); //cycle biome axises for (int x = 0; x < mapSize; x++) { for (int y = 0; y < mapSize; y++) { //if valid tile set map tile to biome tile if (biomes [i] [x, y] >= 0) { biomeMap [x, y] = biomes [i] [x, y]; } } } } //cycle map a final time to create composite map for (int x = 0; x < mapSize; x++) { for (int y = 0; y < mapSize; y++) { //check if valid tile and influence is greater than spawn if (map [x, y] != 0) { //Set prime tile biomeMap [x, y] = (int)primeTile; } } } //set final map map = biomeMap; }
//Convert Automata to biomes public int[,] AutomataToBiome(int[,] mat, int numRefine, int birth, int death) { //declare/initialize arrays int[,] bio; int[,] hold = mat; bool[,] control = new bool[mat.GetLength(0), mat.GetLength(0)]; //initialize random x and y coordinates int rx = 0; int ry = 0; //cycle initial matrix x and y axises for (int i = 0; i < mat.GetLength(0); i++) { for (int j = 0; j < mat.GetLength(0); j++) { //generate random coordinate rx = Random.Range(0, mat.GetLength(0)); ry = Random.Range(0, mat.GetLength(1)); //check if point was previously used. if previously used continue to next, else set to true. if (control[rx, ry]) { continue; } else { control[rx, ry] = true; } //set tile type int type = mat[rx, ry]; //generate random biome width/ height int w = Random.Range(biomeMinSize, biomeMaxSize + 1); int h = Random.Range(biomeMinSize, biomeMaxSize + 1); bio = new int[w, h]; //fill biome for (int x = 0; x < bio.GetLength(0); x++) { for (int y = 0; y < bio.GetLength(1); y++) { //get x and y radius float xr = bio.GetLength(0) / 2; float yr = bio.GetLength(1) / 2; //apply smallest as used radiues float r = Mathf.Min(xr, yr); //generate euclidic distance float e = Mathf.Sqrt(Mathf.Pow((x - xr), 2) + Mathf.Pow((y - yr), 2)); //if the euclidic distance of the biomes cell is within the smallest radius fill cell. if (e < r) { bio[x, y] = type; } } } //refine the new biome bio = stdMath.CellularAutomata(bio, numRefine, birth, death, false, false); //replace tiles in matrix with new biome for (int x = 0; x < bio.GetLength(0); x++) { for (int y = 0; y < bio.GetLength(1); y++) { //biome real coordiates int xr = rx + x; int yr = ry + y; //ensure that tile can be placed on mat if (!(xr >= mat.GetLength(0) || yr >= mat.GetLength(1))) { hold[xr, yr] = bio[x, y]; } } } } } //return modified holding map return(hold); }