improved side placement algorithm

This commit is contained in:
uid68803 2004-01-09 05:48:01 +00:00
parent f25376565a
commit 320d92f989
4 changed files with 54 additions and 36 deletions

View file

@ -163,7 +163,7 @@ road_windiness=3
[castle]
valid_terrain=g,f,h
min_distance=16
min_distance=24
[/castle]
[/map_generator]

View file

@ -1310,7 +1310,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image_override,
}
const int height_adjust = it->second.is_flying() ? 0 : int(map_.get_terrain_info(terrain).unit_height_adjust()*(zoom_/DefaultZoom));
const double submerge = it->second.is_flying() ? 0.0 : int(map_.get_terrain_info(terrain).unit_submerge());
const double submerge = it->second.is_flying() ? 0.0 : map_.get_terrain_info(terrain).unit_submerge();
draw_unit(xpos-xsrc,ypos-ysrc - height_adjust,unit_image,face_left,false,
highlight_ratio,blend_with,submerge);
@ -2208,7 +2208,6 @@ void display::draw_unit(int x, int y, SDL_Surface* image,
bool reverse, bool upside_down,
double alpha, Pixel blendto, double submerged)
{
std::cerr << "drawing unit submerged at " << submerged << "\n";
//the alpha value to use for submerged units
static const double unit_submerged_alpha = 0.2;

View file

@ -107,7 +107,7 @@ void default_map_generator::user_config(display& disp)
hillsize_rect.y = iterations_rect.y + iterations_rect.h + vertical_margin;
villages_rect.y = hillsize_rect.y + hillsize_rect.h + vertical_margin;
const int max_players = 9;
const int max_players = 8;
const int right_space = 100;

View file

@ -34,8 +34,8 @@ namespace {
{
int positions = 0, liked = 0;
const std::string& terrain_liked = side["terrain_liked"];
for(int i = pos.x-10; i != pos.x+10; ++i) {
for(int j = pos.y-10; j != pos.y+10; ++j) {
for(int i = pos.x-8; i != pos.x+8; ++i) {
for(int j = pos.y-8; j != pos.y+8; ++j) {
const gamemap::location pos(i,j);
if(map.on_board(pos)) {
++positions;
@ -48,6 +48,48 @@ namespace {
return (100*liked)/positions;
}
struct placing_info {
int side, score;
gamemap::location pos;
};
bool operator<(const placing_info& a, const placing_info& b) { return a.score > b.score; }
bool operator==(const placing_info& a, const placing_info& b) { return a.score == b.score; }
void place_sides_in_preferred_locations(gamemap& map, const config::child_list& sides)
{
std::vector<placing_info> placings;
const int num_pos = map.num_valid_starting_positions();
for(config::child_list::const_iterator s = sides.begin(); s != sides.end(); ++s) {
const int side_num = s - sides.begin() + 1;
for(int p = 1; p <= num_pos; ++p) {
const gamemap::location& pos = map.starting_position(p);
const int score = placing_score(**s,map,pos);
placing_info obj;
obj.side = side_num;
obj.score = score;
obj.pos = pos;
placings.push_back(obj);
}
}
std::sort(placings.begin(),placings.end());
std::set<int> placed;
std::set<gamemap::location> positions_taken;
for(std::vector<placing_info>::const_iterator i = placings.begin();
i != placings.end() && placed.size() != sides.size(); ++i) {
if(placed.count(i->side) == 0 && positions_taken.count(i->pos) == 0) {
placed.insert(i->side);
positions_taken.insert(i->pos);
map.set_starting_position(i->side,i->pos);
std::cerr << "placing side " << i->side << " at " << i->pos.x << "," << i->pos.y << "\n";
}
}
}
}
LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
@ -77,11 +119,13 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
int first_human_team = -1;
const bool modify_placing = (*level)["modify_placing"] == "true";
std::set<int> taken_places;
std::vector<gamemap::location> starting_locs;
const config::child_list& unit_cfg = level->get_children("side");
if((*level)["modify_placing"] == "true") {
std::cerr << "modifying placing...\n";
place_sides_in_preferred_locations(map,unit_cfg);
}
for(config::child_list::const_iterator ui = unit_cfg.begin(); ui != unit_cfg.end(); ++ui) {
if(first_human_team == -1 && (**ui)["controller"] == "human") {
@ -115,28 +159,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
}
}
int start = new_unit.side();
if(modify_placing) {
int best = -1, current = -1;
for(int i = 1; i <= unit_cfg.size(); ++i) {
if(taken_places.count(i))
continue;
const int res = placing_score(**ui,map,map.starting_position(i));
if(current == -1 || res > best) {
current = res;
best = i;
}
}
start = best;
taken_places.insert(start);
}
assert(start != -1);
const gamemap::location& start_pos = map.starting_position(start);
starting_locs.push_back(start_pos);
const gamemap::location& start_pos = map.starting_position(new_unit.side());
if(!start_pos.valid() && new_unit.side() == 1) {
throw gamestatus::load_game_failed("No starting position for side 1");
@ -179,10 +202,6 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
}
}
for(size_t pos = 0; pos != starting_locs.size(); ++pos) {
map.set_starting_position(pos+1,starting_locs[pos]);
}
const teams_manager team_manager(teams);
const config* const theme_cfg = game_config.find_child("theme","name",preferences::theme());