package pathgame.tilemap; import java.util.Random; public class TileMapGenerator { private static long seed = 1; /** Returns a random generated map * * @param width the width of the map * @param height the height of the map * @param towns the amount of towns * @return a random generated map */ public static TileMap getMap(int width, int height, int towns) { return getMap(width, height, seed++, towns); } /** Returns a random generated map * * @param width the width of the map * @param height the height of the map * @param seed the seed for the random number generator * @param towns the amount of towns * @return a random generated map */ public static TileMap getMap(int width, int height, long seed, int towns) { Random r = new Random(seed); HighMap highMap = HighMap.generate(seed, width, height); TileMap map = new TileMap(width, height); for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { if(highMap.get(x, y) < 0.15f) { map.setTile(x, y, Tiles.DEEP_WATER); } else if(highMap.get(x, y) < 0.3f) { map.setTile(x, y, Tiles.SHALLOW_WATER); } else if(highMap.get(x, y) < 0.7f) { map.setTile(x, y, randomGrass(r)); } else if(highMap.get(x, y) < 0.85f) { map.setTile(x, y, Tiles.HILL); } else { map.setTile(x, y, Tiles.MOUNTAIN); } } } int forestSize = ((width + height) / 2) / 10; forestSize *= forestSize; generateForest(map, r, forestSize, 10, 2, Tiles.FOREST); generateForest(map, r, forestSize, 5, 2, Tiles.SWAMP, Tiles.SWAMP, Tiles.SWAMP_DECO, Tiles.SWAMP_TREE); generateTowns(map, r, towns); return map; } private static Tile randomGrass(Random r) { if(r.nextFloat() < 0.3f) { return randomTile(Tiles.GRASS_VARIANTS, r); } return Tiles.GRASS; } private static void generateForest(TileMap map, Random r, int depth, int placements, int jumpRadius, Tile... t) { for(int i = 0; i < placements; i++) { int x = r.nextInt(map.getWidth()); int y = r.nextInt(map.getHeight()); while(map.getTile(x, y).getForestReplaceChance() < 1.0f) { x = r.nextInt(map.getWidth()); y = r.nextInt(map.getHeight()); } for(int j = 0; j < depth; j++) { int oldX = x; int oldY = y; x += r.nextInt(jumpRadius * 2 + 1) - jumpRadius; y += r.nextInt(jumpRadius * 2 + 1) - jumpRadius; x = Math.min(Math.max(x, 0), map.getWidth() - 1); y = Math.min(Math.max(y, 0), map.getHeight() - 1); if(r.nextFloat() < map.getTile(x, y).getForestReplaceChance()) { map.setTile(x, y, randomTile(t, r)); placeForest(map, r, x - 1, y, t); placeForest(map, r, x + 1, y, t); placeForest(map, r, x, y - 1, t); placeForest(map, r, x, y + 1, t); } else { x = oldX; y = oldY; } } } } private static Tile randomTile(Tile[] tiles, Random r) { if(tiles.length == 1) { return tiles[0]; } return tiles[r.nextInt(tiles.length)]; } private static void placeForest(TileMap map, Random r, int x, int y, Tile... t) { if(x >= 0 && x < map.getWidth() && y >= 0 && y < map.getHeight()) { if(r.nextFloat() * 2 < map.getTile(x, y).getForestReplaceChance()) { map.setTile(x, y, randomTile(t, r)); } } } private static void generateTowns(TileMap map, Random r, int towns) { int failCounter = 0; while(towns > 0 && failCounter < 100) { int x = r.nextInt(map.getWidth()); int y = r.nextInt(map.getHeight()); if(map.getTile(x, y).canHostTown() && checkNearbyTowns(map, x, y, 2)) { map.setTile(x, y, Tiles.TOWN); towns--; failCounter = 0; } else { failCounter++; } } } private static boolean checkNearbyTowns(TileMap map, int x, int y, int radius) { int startX = Math.max(x - radius, 0); int startY = Math.max(y - radius, 0); int endX = Math.min(x + radius, map.getWidth() - 1); int endY = Math.min(y + radius, map.getHeight() - 1); for(int mx = startX; mx <= endX; mx++) { for(int my = startY; my <= endY; my++) { if(map.getTile(mx, my) == Tiles.TOWN) { return false; } } } return true; } }