widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #03897
[Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
TiborB has proposed merging lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/militarysites_tweaks/+merge/255132
Here I reworked positioning of new militarysites and dismantling of old ones. I made the code cleaner and I hope better to understand. AI now builds more big buildings.
Also I did some smaller tweaks where needed. But everything was purely AI stuff.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands.
=== modified file 'src/ai/ai_hints.cc'
--- src/ai/ai_hints.cc 2015-03-26 06:59:37 +0000
+++ src/ai/ai_hints.cc 2015-04-02 19:22:42 +0000
@@ -48,7 +48,8 @@
} else {
if (!strcmp(section ? section->get_string("trainingsite_type", "basic") : "basic", "basic")) {
trainingsite_type_ = TrainingSiteType::kBasic;
- } else if (!strcmp(section ? section->get_string("trainingsite_type", "basic") : "basic", "advanced")) {
+ } else if (!strcmp(section ? section->get_string("trainingsite_type", "basic") :
+ "basic", "advanced")) {
trainingsite_type_ = TrainingSiteType::kAdvanced;
} else {
trainingsite_type_ = TrainingSiteType::kNoTS;
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc 2015-03-26 20:35:19 +0000
+++ src/ai/defaultai.cc 2015-04-02 19:22:42 +0000
@@ -904,14 +904,13 @@
// stones are not renewable, we will count them only if previous state si nonzero
if (field.stones_nearby_ > 0 && gametime % 3 == 0) {
- int32_t const stone_attr = MapObjectDescr::get_attribute_id("granite");
- field.stones_nearby_ = 0;
+ field.stones_nearby_ =
+ map.find_immovables(Area<FCoords>(map.get_fcoords(field.coords), 6),
+ nullptr,
+ FindImmovableAttribute(MapObjectDescr::get_attribute_id("granite")));
- for (uint32_t j = 0; j < immovables.size(); ++j) {
- if (immovables.at(j).object->has_attribute(stone_attr)) {
- ++field.stones_nearby_;
- }
- }
+ //adding 10 if stones found
+ field.stones_nearby_ = (field.stones_nearby_ > 0) ? field.stones_nearby_ + 10:0;
}
// ground water is not renewable and its amount can only fall, we will count them only if
@@ -964,7 +963,9 @@
if (radius > dist) {
field.area_military_capacity_ +=
target_ms_d->get_max_number_of_soldiers() / 2 + 1;
- field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
+ if (field.coords != immovables.at(i).coords) {
+ field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
+ }
field.military_in_constr_nearby_ += 1;
}
}
@@ -985,7 +986,9 @@
field.military_stationed_ += 1;
}
- field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
+ if (field.coords != immovables.at(i).coords) {
+ field.military_loneliness_ *= static_cast<double_t>(dist) / radius;
+ }
}
}
}
@@ -1196,7 +1199,7 @@
// sometimes there is too many military buildings in construction, so we must
// prevent initialization of further buildings start
const int32_t vacant_plus_in_construction_minus_prod =
- vacant_mil_positions_ + 2 * num_milit_constructionsites - productionsites.size() / 15;
+ vacant_mil_positions_ + 2 * num_milit_constructionsites - productionsites.size() / 7;
if (vacant_plus_in_construction_minus_prod > 20) {
expansion_mode = MilitaryStrategy::kNoNewMilitary;
} else if (vacant_plus_in_construction_minus_prod > 13) {
@@ -1275,9 +1278,8 @@
// checking we have enough critical material on stock
for (uint32_t m = 0; m < bo.critical_built_mat_.size(); ++m) {
WareIndex wt(static_cast<size_t>(bo.critical_built_mat_.at(m)));
- // using default ware quantity, not the best solution but will do
- if (get_warehoused_stock(wt) <
- tribe_->get_ware_descr(wt)->default_target_quantity() * 2 / 3) {
+ // shortage = less then 1 items in warehouses
+ if (get_warehoused_stock(wt) < 3) {
bo.build_material_shortage_ = true;
}
}
@@ -1454,7 +1456,9 @@
}
prio = bf->stones_nearby_;
- if (prio <= 0) {
+ // value is initialized with 1 but minimal value that can be
+ // calculated is 11
+ if (prio <= 1) {
continue;
}
@@ -1550,8 +1554,8 @@
continue;
}
- // sometimes all area is blocked by trees so this is to prevent this
- if (buildable_fields.size() < 4 && bo.total_count() > 0) {
+ // for small starting spots - to prevent crowding by rangers and trees
+ if (spots_ < (10 * bo.total_count()) && bo.total_count() > 0) {
continue;
}
@@ -1578,9 +1582,6 @@
bf->producers_nearby_.at(bo.production_hint_) * 5 -
new_buildings_stop_ * 15;
- // considering space consumers nearby
- prio -= bf->space_consumers_nearby_ * 5;
-
} else { // FISH BREEDERS and GAME KEEPERS
if (new_buildings_stop_ && (bo.total_count() - bo.unconnected_) > 0) {
continue;
@@ -1666,7 +1667,8 @@
// we attempt to cluster space consumers together
if (bo.space_consumer_) { // need to consider trees nearby
- prio += bf->space_consumers_nearby_ * 2;
+ prio += bf->space_consumers_nearby_ * 10;
+ prio += (bf->space_consumers_nearby_ > 2)?2:bf->space_consumers_nearby_ * 2;
}
if (bo.space_consumer_ && !bf->water_nearby_) { // not close to water
@@ -1682,7 +1684,6 @@
prio -= bf->producers_nearby_.at(bo.outputs_.at(0)) * 20;
} // leave some free space between them
- prio -= bf->space_consumers_nearby_ * 3;
}
else if (bo.is_shipyard_) {
@@ -1725,14 +1726,8 @@
}
} // production sites done
else if (bo.type == BuildingObserver::MILITARYSITE) {
- // we allow 1 exemption from big buildings prohibition
- if (bo.build_material_shortage_ &&
- (bo.cnt_under_construction_ > 0 || !(bf->enemy_nearby_))) {
- continue;
- }
if (!bf->unowned_land_nearby_) {
-
continue;
}
@@ -1740,6 +1735,48 @@
continue;
}
+ prio = 0;
+
+ // calculating some sub-scores, some of them are prohibitive
+ // decreasing score if some critical materials are missing
+ // (relevant for medium and big buildings)
+ int32_t prio_for_mat_shortage = 0;
+ if (bf->enemy_nearby_) {
+ prio_for_mat_shortage =
+ -bo.cnt_under_construction_ * bo.build_material_shortage_ * 50;
+ } else {
+ prio_for_mat_shortage = -bo.cnt_under_construction_ * bo.build_material_shortage_ *
+ 1000; // = prohibitive
+ }
+
+ // decreasing score if other militarysites constuctions
+ // are nearby
+ int32_t prio_for_in_constr = 0;
+ prio_for_in_constr -= 700 *
+ (((static_cast<int32_t>(num_milit_constructionsites) - 2) < 0) ?
+ 0 :
+ (num_milit_constructionsites - 2)) /
+ (militarysites.size() + 2);
+ if (!bf->enemy_nearby_) {
+ prio_for_in_constr *= 3;
+ }
+
+ // similarly if unmanned militarysites are nearby
+ int32_t prio_for_unmanned_nearby = 0;
+ if (bf->enemy_nearby_) {
+ prio_for_unmanned_nearby -=
+ (bf->military_in_constr_nearby_ + bf->military_unstationed_) * 20;
+ } else {
+ prio_for_unmanned_nearby -=
+ (bf->military_in_constr_nearby_ + bf->military_unstationed_) * 1000;
+ }
+
+ // not continuing if score too low
+ if (prio_for_in_constr + prio_for_mat_shortage + prio_for_unmanned_nearby <= -1000) {
+ continue;
+ }
+
+ // is the building suitable for the situation?
if (expansion_mode == MilitaryStrategy::kNoNewMilitary) {
continue;
}
@@ -1771,37 +1808,64 @@
} else {
continue;
} // the building is not suitable for situation
- // not to build so many military buildings nearby
- if (!bf->enemy_nearby_ &&
- (bf->military_in_constr_nearby_ + bf->military_unstationed_) > 0) {
- continue;
- }
+
+
+ // calculating other sub scores
+ // for resources (mines, water, stones)
+ int32_t prio_for_resources = 0;
+ prio_for_resources +=
+ 2 * (bf->unowned_mines_pots_nearby_ * resource_necessity_mines_) / 100 +
+ bf->stones_nearby_ + (bf->water_nearby_ * resource_necessity_water_) / 100;
+ // special bonus due to remote water for atlanteans
+ if (resource_necessity_water_needed_) {
+ prio_for_resources += (bf->distant_water_ * resource_necessity_water_) / 100 / 3;
+ }
+ // reducing score if too little unowned land
+ if (bf->unowned_land_nearby_ < 10) {
+ prio_for_resources = prio_for_resources * bf->unowned_land_nearby_ / 10;
+ }
+ if (bf->enemy_nearby_) { // not important when fighting enemies
+ prio_for_resources /= 5;
+ }
+
+ //for unowned land nearby
+ int32_t prio_for_unowned_land = 0;
+ if (expansion_mode == MilitaryStrategy::kExpansion ||
+ expansion_mode == MilitaryStrategy::kPushExpansion) {
+ prio_for_unowned_land +=
+ (bf->unowned_land_nearby_ * resource_necessity_territory_) / 100;
+ }
+
+ //for distance to nearest military sites
+ int32_t prio_for_loneliness = bf->military_loneliness_;
+ if (!bf->enemy_nearby_) {
+ prio_for_loneliness /= 10;
+ }
+
+ //additional score for bigger buildings
+ int32_t prio_for_size = 0;
+ if (bf->enemy_nearby_) {
+ prio_for_size += (bo.desc->get_size() - 1) * 30;
+ } else {
+ prio_for_size += (bo.desc->get_size() - 1) * 15;
+ }
+
+ //additional score if enemy is nearby
+ int32_t prio_for_enemy = 0;
+ if (bf->enemy_nearby_) {
+ prio_for_enemy += 50;
+ }
+
// a boost to prevent an expansion halt
int32_t local_boost = 0;
if (expansion_mode == MilitaryStrategy::kPushExpansion) {
local_boost = 200;
}
- // priority based on basic resources
- prio = ((bf->unowned_mines_pots_nearby_ * resource_necessity_mines_) / 100 +
- bf->stones_nearby_ + bf->military_loneliness_ / 10 - 40 + local_boost +
- (bf->water_nearby_ * resource_necessity_water_) / 100);
-
- // Depending on wheter resource only are considered or no
- if (expansion_mode == MilitaryStrategy::kResourcesOrDefense) {
- prio *= 2;
- prio += bf->unowned_land_nearby_ * resource_necessity_territory_ / 100 / 2;
- } else { // addding score for territory
- prio += (bf->unowned_land_nearby_ * resource_necessity_territory_) / 100 * 3 / 2;
- }
-
- // adding score for distance to other military sites
- prio += bf->military_loneliness_ / 10 - 40;
-
- // special bonus due to remote water for atlanteans
- if (resource_necessity_water_needed_) {
- prio += (bf->distant_water_ * resource_necessity_water_) / 100 / 2;
- }
+ // summing
+ prio += prio_for_mat_shortage + prio_for_in_constr + prio_for_unmanned_nearby +
+ prio_for_resources + prio_for_unowned_land + prio_for_loneliness +
+ prio_for_size + local_boost + prio_for_enemy;
// special bonus if a portspace is close
if (bf->portspace_nearby_ == ExtendedBool::kTrue) {
@@ -1812,28 +1876,78 @@
}
}
- //special bonus for bigger buildings if enemy is nearby
- if (bf->enemy_nearby_) {
- prio += (bo.desc->get_size() - 1) * 25;
- }
-
+ // penalty if we build lesser then possible building
if (bo.desc->get_size() < maxsize) {
prio = prio - 5;
- } // penalty
-
- // we need to prefer military building near to borders
- // with enemy
- // Note: if we dont have enough mines, we cannot afford
- // full-power defense (we need to preserve material and soldiers
- // for expansion)
- const int16_t bottom_treshold =
- 15 - ((virtual_mines <= 4) ? (5 - virtual_mines) * 2 : 0);
- if (bf->enemy_nearby_ && bf->area_military_capacity_ < bottom_treshold) {
- prio += 50 + (bottom_treshold - bf->area_military_capacity_) * 20;
- }
-
- if (bf->enemy_nearby_ && bf->area_military_capacity_ > bottom_treshold + 4) {
- prio -= (bf->area_military_capacity_ - (bottom_treshold + 4)) * 5;
+ }
+
+ // just generally prevent too many buildings
+ prio -= 40;
+
+ } else if (bo.type == BuildingObserver::WAREHOUSE) {
+
+ // exclude spots on border
+ if (bf->near_border_ && !bo.is_port_) {
+ continue;
+ }
+
+ if (!bf->is_portspace_ && bo.is_port_) {
+ continue;
+ }
+
+ if (bo.cnt_under_construction_ > 0) {
+ continue;
+ }
+
+ bool warehouse_needed = false;
+
+ // Build one warehouse for ~every 35 productionsites and mines_.
+ // Militarysites are slightly important as well, to have a bigger
+ // chance for a warehouses (containing waiting soldiers or wares
+ // needed for soldier training) near the frontier.
+ if ((static_cast<int32_t>(productionsites.size() + mines_.size()) + 20) / 35 >
+ static_cast<int32_t>(numof_warehouses_) &&
+ bo.cnt_under_construction_ == 0) {
+ prio = 20;
+ warehouse_needed = true;
+ }
+
+ // but generally we prefer ports
+ if (bo.is_port_) {
+ prio += 10;
+ }
+
+ // special boost for first port
+ if (bo.is_port_ && bo.total_count() == 0 && productionsites.size() > 5 &&
+ !bf->enemy_nearby_ && bf->is_portspace_ && seafaring_economy) {
+ prio += kDefaultPrioBoost + productionsites.size();
+ warehouse_needed = true;
+ }
+
+ if (!warehouse_needed) {
+ continue;
+ }
+
+ // iterating over current warehouses and testing a distance
+ // getting distance to nearest warehouse and adding it to a score
+ uint16_t nearest_distance = std::numeric_limits<uint16_t>::max();
+ for (const WarehouseSiteObserver& wh_obs : warehousesites) {
+ const uint16_t actual_distance =
+ map.calc_distance(bf->coords, wh_obs.site->get_position());
+ nearest_distance = std::min(nearest_distance, actual_distance);
+ }
+ // but limit to 15
+ const uint16_t max_distance_considered = 15;
+ nearest_distance = std::min(nearest_distance, max_distance_considered);
+ prio += nearest_distance;
+
+ // take care about and enemies
+ if (bf->enemy_nearby_) {
+ prio /= 4;
+ }
+
+ if (bf->unowned_land_nearby_ && !bo.is_port_) {
+ prio /= 2;
}
} else if (bo.type == BuildingObserver::WAREHOUSE) {
@@ -1953,7 +2067,9 @@
}
// think of space consuming buildings nearby like farms or vineyards
- prio -= bf->space_consumers_nearby_ * 10;
+ if (bo.type != BuildingObserver::MILITARYSITE) {
+ prio -= bf->space_consumers_nearby_ * 10;
+ }
// Stop here, if priority is 0 or less.
if (prio <= 0) {
@@ -3577,7 +3693,7 @@
int16_t score = 0;
score += (bf.area_military_capacity_ > 6);
- score += (bf.area_military_capacity_ > 18);
+ score += (bf.area_military_capacity_ > 22);
score += (bf.area_military_presence_ > 4);
score += (bf.military_loneliness_ < 180);
score += (bf.military_stationed_ > 2);
=== modified file 'tribes/atlanteans/castle/conf'
--- tribes/atlanteans/castle/conf 2014-07-29 20:48:19 +0000
+++ tribes/atlanteans/castle/conf 2015-04-02 19:22:42 +0000
@@ -13,7 +13,7 @@
expansion=true
fighting=true
mountain_conqueror=true
-prohibited_till=1800
+prohibited_till=1500
[buildcost]
planks=4
=== modified file 'tribes/barbarians/donjon/conf'
--- tribes/barbarians/donjon/conf 2014-07-29 20:48:19 +0000
+++ tribes/barbarians/donjon/conf 2015-04-02 19:22:42 +0000
@@ -14,7 +14,7 @@
expansion=true
fighting=true
mountain_conqueror=true
-prohibited_till=1500
+prohibited_till=1200
[buildcost]
blackwood=7
=== modified file 'tribes/barbarians/fortress/conf'
--- tribes/barbarians/fortress/conf 2014-07-29 20:48:19 +0000
+++ tribes/barbarians/fortress/conf 2015-04-02 19:22:42 +0000
@@ -14,7 +14,7 @@
expansion=true
fighting=true
mountain_conqueror=true
-prohibited_till=1800
+prohibited_till=1500
[buildcost]
blackwood=9
Follow ups
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: TiborB, 2015-05-11
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: GunChleoc, 2015-05-11
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: TiborB, 2015-05-11
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: GunChleoc, 2015-05-11
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: TiborB, 2015-05-09
-
[Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: noreply, 2015-05-09
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: GunChleoc, 2015-05-09
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: TiborB, 2015-05-07
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: TiborB, 2015-05-07
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: GunChleoc, 2015-05-07
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: TiborB, 2015-05-07
-
Re: [Merge] lp:~widelands-dev/widelands/militarysites_tweaks into lp:widelands
From: GunChleoc, 2015-05-07