static map_location place_village(const t_translation::t_map& map,
	const size_t x, const size_t y, const size_t radius, const config& cfg,
	tcode_list_cache &adj_liked_cache)
{
	const map_location loc(x,y);
	std::set<map_location> locs;
	get_tiles_radius(loc,radius,locs);
	map_location best_loc;
	int best_rating = 0;
	for(std::set<map_location>::const_iterator i = locs.begin();
			i != locs.end(); ++i) {

		if(i->x < 0 || i->y < 0 || i->x >= static_cast<long>(map.size()) ||
				i->y >= static_cast<long>(map[i->x].size())) {

			continue;
		}

		const t_translation::t_terrain t = map[i->x][i->y];
		const std::string str = t_translation::write_terrain_code(t);
		if (const config &child = cfg.find_child("village", "terrain", str)) {
			tcode_list_cache::iterator l = adj_liked_cache.find(t);
			t_translation::t_list *adjacent_liked;
			if (l != adj_liked_cache.end()) {
				adjacent_liked = &(l->second);
			} else {
				adj_liked_cache[t] = t_translation::read_list(child["adjacent_liked"]);
				adjacent_liked = &(adj_liked_cache[t]);
			}

			int rating = child["rating"];
			map_location adj[6];
			get_adjacent_tiles(map_location(i->x,i->y),adj);
			for(size_t n = 0; n != 6; ++n) {
				if(adj[n].x < 0 || adj[n].y < 0 ||
						adj[n].x >= static_cast<long>(map.size()) ||
						adj[n].y >= static_cast<long>(map[adj[n].x].size())) {

					continue;
				}

				const t_translation::t_terrain t2 = map[adj[n].x][adj[n].y];
				rating += std::count(adjacent_liked->begin(),adjacent_liked->end(),t2);
			}

			if(rating > best_rating) {
				best_loc = map_location(i->x,i->y);
				best_rating = rating;
			}
		}
	}

	return best_loc;
}
void terrain_builder::parse_mapstring(const std::string &mapstring,
		struct building_rule &br, anchormap& anchors,
		const config& global_images)
{

	const t_translation::t_map map = t_translation::read_builder_map(mapstring);

	// If there is an empty map leave directly.
	// Determine after conversion, since a
	// non-empty string can return an empty map.
	if(map.empty()) {
		return;
	}

	int lineno = (map[0][0] == t_translation::NONE_TERRAIN) ? 1 : 0;
	int x = lineno;
	int y = 0;
	for(size_t y_off = 0; y_off < map.size(); ++y_off) {
		for(size_t x_off = x; x_off < map[y_off].size(); ++x_off) {

			const t_translation::t_terrain terrain = map[y_off][x_off];

			if(terrain.base == t_translation::TB_DOT) {
				// Dots are simple placeholders,
				// which do not represent actual terrains.
			} else if (terrain.overlay != 0 ) {
				anchors.insert(std::pair<int, map_location>(terrain.overlay, map_location(x, y)));
			} else if (terrain.base == t_translation::TB_STAR) {
				add_constraints(br.constraints, map_location(x, y), t_translation::STAR, global_images);
			} else {
					ERR_NG << "Invalid terrain (" << t_translation::write_terrain_code(terrain) << ") in builder map\n";
					assert(false);
					return;
			}
		x += 2;
		}

		if(lineno % 2 == 1) {
			++y;
			x = 0;
		} else {
			x = 1;
		}
		++lineno;
	}
}