693 LOG_NG <<
"default_generate_map parameters"
694 <<
" width=" <<
data.width
695 <<
" height=" <<
data.height
696 <<
" nplayers=" <<
data.nplayers
697 <<
" nvillages=" <<
data.nvillages
698 <<
" iterations=" <<
data.iterations
699 <<
" hill_size=" <<
data.hill_size
700 <<
" castle_size=" <<
data.castle_size
701 <<
" island_size=" <<
data.island_size
702 <<
" island_off_center=" <<
data.island_off_center
703 <<
" max_lakes=" <<
data.max_lakes
704 <<
" link_castles=" <<
data.link_castles
705 <<
" show_labels=" <<
data.show_labels;
730 std::map<map_location,std::string>* misc_labels = naming.
empty() ? nullptr : labels;
732 std::shared_ptr<name_generator>
733 base_name_generator, river_name_generator, lake_name_generator,
734 road_name_generator, bridge_name_generator, mountain_name_generator,
735 forest_name_generator, swamp_name_generator;
737 if(misc_labels !=
nullptr) {
738 name_generator_factory base_generator_factory{ naming, {
"male",
"base",
"bridge",
"road",
"river",
"forest",
"lake",
"mountain",
"swamp"} };
743 base_name_generator = base_generator_factory.get_name_generator( (naming.
has_attribute(
"base_names") || naming.
has_attribute(
"base_name_generator")) ?
"base" :
"male" );
744 river_name_generator = base_generator_factory.get_name_generator(
"river");
745 lake_name_generator = base_generator_factory.get_name_generator(
"lake");
746 road_name_generator = base_generator_factory.get_name_generator(
"road");
747 bridge_name_generator = base_generator_factory.get_name_generator(
"bridge");
748 mountain_name_generator = base_generator_factory.get_name_generator(
"mountain");
749 forest_name_generator = base_generator_factory.get_name_generator(
"forest");
750 swamp_name_generator = base_generator_factory.get_name_generator(
"swamp");
756 LOG_NG <<
"Done generating height map. " << timer <<
" ticks elapsed";
759 std::string flatland =
cfg[
"default_flatland"];
760 if(flatland.empty()) {
766 std::vector<terrain_height_mapper> height_conversion;
768 height_conversion.emplace_back(
h);
772 for(std::size_t x = 0; x != heights.size(); ++x) {
773 for(std::size_t y = 0; y != heights[x].size(); ++y) {
774 for(
auto i : height_conversion) {
775 if(
i.convert_terrain(heights[x][y])) {
776 terrain[x][y] =
i.convert_to();
785 LOG_NG <<
"Placed landforms. " << timer <<
" ticks elapsed";
799 std::set<map_location> lake_locs;
801 std::map<map_location, std::string> river_names, lake_names, road_names, bridge_names, mountain_names, forest_names, swamp_names;
803 const std::size_t nlakes =
data.max_lakes > 0 ? (
rng_()%
data.max_lakes) : 0;
804 for(std::size_t lake = 0; lake != nlakes; ++lake) {
805 for(
int tries = 0; tries != 100; ++tries) {
809 if(heights[x][y] <=
cfg[
"min_lake_height"].to_int()) {
813 std::vector<map_location> river =
generate_river(heights, terrain, x, y,
cfg[
"river_frequency"].to_int());
815 if(!river.empty() && misc_labels !=
nullptr) {
816 const std::string base_name = base_name_generator->generate();
817 const std::string& name = river_name_generator->generate({{
"base", base_name}});
818 LOG_NG <<
"Named river '" << name <<
"'";
820 std::size_t name_frequency = 20;
821 for(std::vector<map_location>::const_iterator r = river.begin(); r != river.end(); ++r) {
824 if(((r - river.begin())%name_frequency) == name_frequency/2) {
825 misc_labels->emplace(
loc, name);
828 river_names.emplace(
loc, base_name);
832 LOG_NG <<
"Generating lake...";
834 std::set<map_location> locs;
835 if(
generate_lake(terrain, x, y,
cfg[
"lake_size"].to_int(), locs) && misc_labels !=
nullptr) {
836 bool touches_other_lake =
false;
838 std::string base_name = base_name_generator->generate();
839 const std::string& name = lake_name_generator->generate({{
"base", base_name}});
844 if(lake_locs.count(
i) != 0) {
845 touches_other_lake =
true;
849 const std::map<map_location,std::string>::const_iterator other_name = lake_names.find(
loc);
850 if(other_name != lake_names.end()) {
851 base_name = other_name->second;
858 if(!touches_other_lake) {
860 misc_labels->erase(
loc);
861 misc_labels->emplace(
loc, name);
866 lake_names.emplace(
loc, base_name);
874 LOG_NG <<
"Generated rivers. " << timer <<
" ticks elapsed";
876 const std::size_t default_dimensions = 40*40*9;
887 cfg[
"temperature_iterations"].to_size_t() *
data.width *
data.height / default_dimensions,
888 cfg[
"temperature_size"].to_size_t(), 0, 0);
890 LOG_NG <<
"Generated temperature map. " << timer <<
" ticks elapsed";
892 std::vector<terrain_converter> converters;
894 converters.emplace_back(cv);
898 for(
int x = 0; x !=
data.width; ++x) {
899 for(
int y = 0; y !=
data.height; ++y) {
900 for(
auto i : converters) {
901 if(
i.convert_terrain(terrain[x][y],heights[x][y],temperature_map[x][y])) {
902 terrain[x][y] =
i.convert_to();
909 LOG_NG <<
"Converted terrain. " << timer <<
" ticks elapsed";
910 LOG_NG <<
"Placing castles...";
921 std::vector<map_location> castles;
922 std::set<map_location> failed_locs;
931 const is_valid_terrain terrain_tester(terrain, list);
933 for(
int player = 0; player !=
data.nplayers; ++player) {
934 LOG_NG <<
"placing castle for " << player;
936 const int min_x =
data.width/3 + 3;
937 const int min_y =
data.height/3 + 3;
938 const int max_x = (
data.width/3)*2 - 4;
939 const int max_y = (
data.height/3)*2 - 4;
940 int min_distance = castle_config[
"min_distance"].to_int();
943 int best_ranking = 0;
944 for(
int x = min_x; x != max_x; ++x) {
945 for(
int y = min_y; y != max_y; ++y) {
947 if(failed_locs.count(
loc)) {
951 const int ranking =
rank_castle_location(x, y, terrain_tester, min_x, max_x, min_y, max_y, min_distance, castles, best_ranking);
953 failed_locs.insert(
loc);
956 if(ranking > best_ranking) {
957 best_ranking = ranking;
963 if(best_ranking == 0) {
964 ERR_NG <<
"No castle location found, for " <<
data.nplayers <<
" players aborting. ";
965 const std::string error =
_(
"No valid castle location found. Too many or too few mountain hexes? (please check the ‘max hill size’ parameter)");
970 castles.push_back(best_loc);
973 failed_locs.insert(best_loc);
976 LOG_NG <<
"Placed castles. " << timer <<
" ticks elapsed";
978 LOG_NG <<
"Placing roads...";
983 int nroads =
cfg[
"roads"].to_int();
984 if(
data.link_castles) {
985 nroads += castles.size()*castles.size();
988 std::set<map_location> bridges;
990 road_path_calculator calc(terrain,
cfg,
rng_());
991 for(
int road = 0; road != nroads; ++road) {
1007 if(
data.link_castles && road <
static_cast<int>(castles.size() * castles.size())) {
1008 const std::size_t src_castle = road/castles.
size();
1009 const std::size_t dst_castle = road%castles.size();
1010 if(src_castle >= dst_castle) {
1014 src = castles[src_castle];
1015 dst = castles[dst_castle];
1021 if(calc.cost(
src, 0.0) >= 1000.0 || calc.cost(
dst, 0.0) >= 1000.0) {
1028 const std::string& road_base_name = misc_labels !=
nullptr
1029 ? base_name_generator->generate()
1031 const std::string& road_name = misc_labels !=
nullptr
1032 ? road_name_generator->generate({{
"base", road_base_name}})
1034 const int name_frequency = 20;
1037 bool on_bridge =
false;
1041 for(std::vector<map_location>::const_iterator step = rt.
steps.begin();
1042 step != rt.
steps.end(); ++step) {
1044 const int x = step->x;
1045 const int y = step->y;
1047 if(x < 0 || y < 0 || x >=
static_cast<long>(
data.width) || y >=
static_cast<long>(
data.height)) {
1053 if(!child || child->empty()){
1064 const std::string& convert_to_bridge = child[
"convert_to_bridge"];
1065 if(!convert_to_bridge.empty()) {
1066 if(step == rt.
steps.begin() || step+1 == rt.
steps.end()) {
1077 if((last == adj[0] && next == adj[3]) || (last == adj[3] && next == adj[0])) {
1082 else if((last == adj[1] && next == adj[4]) || (last == adj[4] && next == adj[1])) {
1087 else if((last == adj[2] && next == adj[5]) || (last == adj[5] && next == adj[2])) {
1091 if(misc_labels !=
nullptr && !on_bridge) {
1093 std::string bridge_base_name = base_name_generator->generate();
1094 const std::string& name = bridge_name_generator->generate({{
"base", bridge_base_name}});
1096 misc_labels->emplace(
loc, name);
1097 bridge_names.emplace(
loc, bridge_base_name);
1098 bridges.insert(
loc);
1101 if(direction != -1) {
1102 const std::vector<std::string> items =
utils::split(convert_to_bridge);
1103 if(std::size_t(direction) < items.size() && !items[direction].empty()) {
1114 const std::string& convert_to = child[
"convert_to"];
1115 if(!convert_to.empty()) {
1117 if(misc_labels !=
nullptr && terrain[x][y] != letter && name_count++ == name_frequency && !on_bridge) {
1122 terrain[x][y] = letter;
1123 if(misc_labels !=
nullptr) {
1125 if(!road_base_name.empty())
1126 road_names.emplace(
loc, road_base_name);
1133 for(std::vector<map_location>::const_iterator
c = castles.begin();
c != castles.end(); ++
c) {
1140 const int player =
c - castles.begin() + 1;
1142 starting_positions.insert(t_translation::starting_positions::value_type(std::to_string(player), coord));
1145 const int castle_array[13][2] {
1146 {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {0, 1}, {-1, 1},
1147 {-2, 1}, {-2, 0}, {-2, -1}, {-1, -2}, {0, -2}, {1, -2}
1150 for(
int i = 0;
i <
data.castle_size - 1;
i++) {
1155 if(labels !=
nullptr) {
1157 for(
int i = 0;
i <
data.castle_size - 1;
i++) {
1163 LOG_NG <<
"Placed roads. " << timer <<
" ticks elapsed";
1169 if(misc_labels !=
nullptr) {
1170 std::set<std::string> used_names;
1171 for(
int x =
data.width / 3; x < (
data.width / 3)*2; x++) {
1172 for(
int y =
data.height / 3; y < (
data.height / 3) * 2;y++) {
1176 std::string name =
"", base_name;
1180 if((
rng_() % 15) == 0) {
1181 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1182 base_name = base_name_generator->generate();
1183 name = mountain_name_generator->generate({{
"base", base_name}});
1185 misc_labels->emplace(
loc, name);
1186 mountain_names.emplace(
loc, base_name);
1190 const std::map<map_location, std::string>::const_iterator forest_name = forest_names.find(
loc);
1191 if(forest_name == forest_names.end()) {
1192 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1193 base_name = base_name_generator->generate();
1194 name = forest_name_generator->generate({{
"base", base_name}});
1196 forest_names.emplace(
loc, base_name);
1202 const std::map<map_location, std::string>::const_iterator swamp_name = swamp_names.find(
loc);
1203 if(swamp_name == swamp_names.end()) {
1204 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1205 base_name = base_name_generator->generate();
1206 name = swamp_name_generator->generate({{
"base", base_name}});
1208 swamp_names.emplace(
loc, base_name);
1214 used_names.insert(name);
1220 LOG_NG <<
"Named landforms. " << timer <<
" ticks elapsed";
1221 LOG_NG <<
"Placing villages...";
1228 std::set<map_location> villages;
1230 if(
data.nvillages > 0) {
1233 const std::size_t tiles_per_village = ((
data.width*
data.height)/9)/
data.nvillages;
1234 std::size_t village_x = 1, village_y = 1;
1239 while(village_x*village_y < tiles_per_village) {
1240 if(village_x < village_y) {
1247 std::set<std::string> used_names;
1257 std::map<map_location,std::string>* village_labels = village_naming.
empty() ? nullptr : labels;
1259 for(
int vx = 0; vx <
data.width; vx += village_x) {
1260 LOG_NG <<
"village at " << vx;
1262 for(
int vy =
rng_()%village_y; vy <
data.height; vy += village_y) {
1263 const std::size_t add =
rng_()%3;
1264 const std::size_t x = (vx + add) - 1;
1265 const std::size_t y = (vy + add) - 1;
1269 if(res.
x <
static_cast<long>(
data.width ) / 3 ||
1270 res.
x >=
static_cast<long>(
data.width * 2) / 3 ||
1271 res.
y <
static_cast<long>(
data.height ) / 3 ||
1272 res.
y >=
static_cast<long>(
data.height * 2) / 3) {
1279 if(convert_to.empty()) {
1285 villages.insert(res);
1287 if(village_labels ==
nullptr) {
1292 {
"base",
"male",
"village",
"lake",
"river",
"bridge",
"grassland",
"forest",
"hill",
"mountain",
"mountain_anon",
"road",
"swamp"} };
1297 base_name_generator = village_name_generator_factory.get_name_generator(
1303 std::string name_type =
"village";
1310 std::size_t field_count = 0, forest_count = 0, mountain_count = 0, hill_count = 0;
1312 std::map<std::string,std::string> symbols;
1315 for(
n = 0;
n != 6; ++
n) {
1316 const std::map<map_location,std::string>::const_iterator road_name = road_names.find(adj[
n]);
1317 if(road_name != road_names.end()) {
1318 symbols[
"road"] = road_name->second;
1323 const std::map<map_location,std::string>::const_iterator river_name = river_names.find(adj[
n]);
1324 if(river_name != river_names.end()) {
1325 symbols[
"river"] = river_name->second;
1326 name_type =
"river";
1328 const std::map<map_location,std::string>::const_iterator bridge_name = bridge_names.find(adj[
n]);
1329 if(bridge_name != bridge_names.end()) {
1331 symbols[
"bridge"] = bridge_name->second;
1332 name_type =
"river_bridge";
1338 const std::map<map_location,std::string>::const_iterator forest_name = forest_names.find(adj[
n]);
1339 if(forest_name != forest_names.end()) {
1340 symbols[
"forest"] = forest_name->second;
1341 name_type =
"forest";
1345 const std::map<map_location,std::string>::const_iterator lake_name = lake_names.find(adj[
n]);
1346 if(lake_name != lake_names.end()) {
1347 symbols[
"lake"] = lake_name->second;
1352 const std::map<map_location,std::string>::const_iterator mountain_name = mountain_names.find(adj[
n]);
1353 if(mountain_name != mountain_names.end()) {
1354 symbols[
"mountain"] = mountain_name->second;
1355 name_type =
"mountain";
1359 const std::map<map_location,std::string>::const_iterator swamp_name = swamp_names.find(adj[
n]);
1360 if(swamp_name != swamp_names.end()) {
1361 symbols[
"swamp"] = swamp_name->second;
1362 name_type =
"swamp";
1368 if(std::count(field.begin(),field.end(),terr) > 0) {
1370 }
else if(std::count(forest.begin(),forest.end(),terr) > 0) {
1372 }
else if(std::count(hill.begin(),hill.end(),terr) > 0) {
1374 }
else if(std::count(mountain.begin(),mountain.end(),terr) > 0) {
1380 if(field_count == 6) {
1381 name_type =
"grassland";
1382 }
else if(forest_count >= 2) {
1383 name_type =
"forest";
1384 }
else if(mountain_count >= 1) {
1385 name_type =
"mountain_anon";
1386 }
else if(hill_count >= 2) {
1393 symbols[
"base"] = base_name_generator->generate();
1394 std::shared_ptr<name_generator> village_name_generator = village_name_generator_factory.get_name_generator(name_type);
1396 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1397 name = village_name_generator->generate(symbols);
1400 used_names.insert(name);
1401 village_labels->emplace(
loc, name);
1406 LOG_NG <<
"Placed villages. " << timer <<
" ticks elapsed";
1408 return output_map(terrain, starting_positions);