widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #06359
[Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
TiborB has proposed merging lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/ai_upgrading_reworked/+merge/287229
Redesigned logic of upgrading of the productionsites. AI now waits untill all wares are sent away from productionsite and then it upgrades. Also other small changes..
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands.
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h 2016-02-22 08:50:04 +0000
+++ src/ai/ai_help_structs.h 2016-02-25 21:06:10 +0000
@@ -368,6 +368,8 @@
int32_t cnt_target; // number of buildings as target
int32_t cnt_limit_by_aimode; // limit imposed by weak or normal AI mode
+ int32_t cnt_upgrade_pending; //number of buildings that are to be upgraded
+
// used to track amount of wares produced by building
uint32_t stocklevel;
uint32_t stocklevel_time; // time when stocklevel_ was last time recalculated
@@ -388,6 +390,7 @@
uint32_t unoccupied_till;
uint8_t stats_zero;
uint32_t no_resources_since;
+ bool upgrade_pending;
BuildingObserver* bo;
};
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc 2016-02-22 08:50:04 +0000
+++ src/ai/defaultai.cc 2016-02-25 21:06:10 +0000
@@ -477,7 +477,10 @@
tribe_ = &player_->tribe();
const uint32_t gametime = game().get_gametime();
- log("ComputerPlayer(%d): initializing (%u)\n", player_number(), static_cast<unsigned int>(type_));
+ log("ComputerPlayer(%d): initializing as type %u\n", player_number(), static_cast<unsigned int>(type_));
+ if (player_->team_number() > 0) {
+ log (" ... member of team %d\n", player_->team_number());
+ }
wares.resize(game().tribes().nrwares());
for (DescriptionIndex i = 0; i < static_cast<DescriptionIndex>(game().tribes().nrwares()); ++i) {
@@ -508,6 +511,7 @@
bo.cnt_under_construction = 0;
bo.cnt_target = 1; // default for everything
bo.cnt_limit_by_aimode = std::numeric_limits<int32_t>::max();
+ bo.cnt_upgrade_pending = 0;
bo.stocklevel = 0;
bo.stocklevel_time = 0;
bo.last_dismantle_time = 0;
@@ -824,7 +828,7 @@
// Guard by a set - immovables might be on several nodes at once.
if (&imm->owner() == player_ && !found_immovables.count(imm)) {
found_immovables.insert(imm);
- gain_immovable(*imm);
+ gain_immovable(*imm, true);
}
}
}
@@ -3114,74 +3118,130 @@
Map& map = game().map();
- // first we try to upgrade
- // Upgrading policy
- // a) if there are two buildings and none enhanced and there are workers
- // available, one is to be enhanced
- // b) if there are two buildings
- // statistics percents are decisive
- // c) yet there are buildings that might be upgraded, even when
- // there is no second buiding of the kind (flag upgrade_substitutes)
+ // The code here is bit complicated
+ // a) Either this site is pending for upgrade, if ready, order the upgrade
+ // b) other site of type is pending for upgrade
+ // c) if none of above, we can consider upgrade of this one
const DescriptionIndex enhancement = site.site->descr().enhancement();
- if (connected_to_wh && enhancement != INVALID_INDEX &&
- // if upgrade does not subsitute, we need to have two buildings at least
- ((site.bo->cnt_built - site.bo->unoccupied_count > 1 && site.bo->upgrade_extends)
- ||
- site.bo->upgrade_substitutes) &&
- gametime > 45 * 60 * 1000 &&
- gametime > site.built_time + 20 * 60 * 1000) {
-
- // Only enhance buildings that are allowed (scenario mode)
- // do not do decisions too fast
- if (player_->is_building_type_allowed(enhancement)) {
-
- const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
- BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
- bool doing_upgrade = false;
-
- if (gametime - en_bo.construction_decision_time >= 10 * 60 * 1000 &&
- (en_bo.cnt_under_construction + en_bo.unoccupied_count) == 0) {
-
- // don't upgrade without workers
- if (site.site->has_workers(enhancement, game())) {
-
- // forcing first upgrade
- if (en_bo.total_count() == 0) {
+
+ bool considering_upgrade = enhancement != INVALID_INDEX;
+
+ // First we check for rare case when input wares are set to 0 but AI is not aware that
+ // the site is pending for upgrade - one possible cause is this is a fresly loaded game
+ if (!site.upgrade_pending) {
+ bool resseting_wares = false;
+ for (auto& queue : site.site->warequeues()) {
+ if (queue->get_max_fill() == 0) {
+ resseting_wares = true;
+ game().send_player_set_ware_max_fill(*site.site, queue->get_ware(), queue->get_max_size());
+ }
+ }
+ if (resseting_wares) {
+ log(" %d: AI: input queues resettted to max for %s (game just loaded?)\n",
+ player_number(),
+ site.bo->name);
+ return true;
+ }
+ }
+
+ if (site.upgrade_pending) {
+ // The site is in process of emptying its input queues
+ // Counting remaining wares in the site now
+ int32_t left_wares = 0;
+ for (auto& queue : site.site->warequeues()) {
+ left_wares += queue->get_filled();
+ }
+ //do nothing when some wares are left, but do not wait more then 4 minutes
+ if (site.bo->construction_decision_time + 4 * 60 * 1000 > gametime && left_wares > 0) {
+ return false;
+ }
+ assert (site.bo->cnt_upgrade_pending == 1);
+ assert(enhancement != INVALID_INDEX);
+ game().send_player_enhance_building(*site.site, enhancement);
+ considering_upgrade = false;
+ return true;
+ } else if (site.bo->cnt_upgrade_pending > 0) {
+ // some other site of this type is in pending for upgrade
+ assert (site.bo->cnt_upgrade_pending == 1);
+ return false;
+ }
+ assert (site.bo->cnt_upgrade_pending == 0);
+
+ // Of course type of productionsite must be allowed
+ if (considering_upgrade && !player_->is_building_type_allowed(enhancement)) {
+ considering_upgrade = false;
+ }
+
+ // Site must be connected to warehouse
+ if (considering_upgrade && !connected_to_wh) {
+ considering_upgrade = false;
+ }
+
+ // if upgraded building produces another wares we are willing to upgrade it sooner
+ if (considering_upgrade) {
+ if (site.bo->upgrade_extends) {
+ // if upgrade produces new outputs, we force first upgrade
+ if (gametime < site.built_time + 10 * 60 * 1000) {
+ considering_upgrade = false;
+ }
+ } else {
+ if (gametime < 45 * 60 * 1000 || gametime < site.built_time + 20 * 60 * 1000) {
+ considering_upgrade = false;
+ }
+ }
+ }
+
+ // No upgrade without proper workers
+ if (considering_upgrade && !site.site->has_workers(enhancement, game())) {
+ considering_upgrade = false;
+ }
+
+ if (considering_upgrade) {
+
+ const BuildingDescr& bld = *tribe_->get_building_descr(enhancement);
+ BuildingObserver& en_bo = get_building_observer(bld.name().c_str());
+ bool doing_upgrade = false;
+
+ // 10 minutes is a time to productions statics to settle
+ if ((en_bo.last_building_built == kNever || gametime - en_bo.last_building_built >= 10 * 60 * 1000) &&
+ (en_bo.cnt_under_construction + en_bo.unoccupied_count) == 0) {
+
+ // forcing first upgrade
+ if (en_bo.total_count() == 0) {
+ doing_upgrade = true;
+ }
+
+ if (en_bo.total_count() == 1) {
+ if (en_bo.current_stats > 55) {
+ doing_upgrade = true;
+ }
+ }
+
+ if (en_bo.total_count() > 1) {
+ if (en_bo.current_stats > 75) {
doing_upgrade = true;
- }
-
- if (en_bo.total_count() == 1) {
- //if the upgrade itself can be upgraded futher, we are more willing to upgrade 2nd building
- if (en_bo.upgrade_extends || en_bo.upgrade_substitutes) {
- if (en_bo.current_stats > 30) {
- doing_upgrade = true;
- }
- } else if (en_bo.current_stats > 50) {
- doing_upgrade = true;
- }
- }
-
- if (en_bo.total_count() > 1) {
- if (en_bo.current_stats > 80) {
- doing_upgrade = true;
- }
- }
-
- // Dont forget about limitation of number of buildings
- if (en_bo.cnt_limit_by_aimode <= en_bo.total_count() - en_bo.unconnected_count) {
- doing_upgrade = false;
- }
}
}
- // Enhance if enhanced building is useful
- // additional: we dont want to lose the old building
- if (doing_upgrade) {
- game().send_player_enhance_building(*site.site, enhancement);
- en_bo.construction_decision_time = gametime;
- return true;
- }
+ // Dont forget about limitation of number of buildings
+ if (en_bo.aimode_limit_status() != AiModeBuildings::kAnotherAllowed) {
+ doing_upgrade = false;
+ }
+ }
+
+ // Here we just restrict input wares to 0 and set flag 'upgrade_pending' to true
+ if (doing_upgrade) {
+
+ // reducing input queues
+ for (auto& queue : site.site->warequeues()) {
+ game().send_player_set_ware_max_fill(*site.site, queue->get_ware(), 0);
+ }
+ site.bo->construction_decision_time = gametime;
+ en_bo.construction_decision_time = gametime;
+ site.upgrade_pending = true;
+ site.bo->cnt_upgrade_pending += 1;
+ return true;
}
}
@@ -4656,9 +4716,9 @@
}
// this is called whenever we gain ownership of a PlayerImmovable
-void DefaultAI::gain_immovable(PlayerImmovable& pi) {
+void DefaultAI::gain_immovable(PlayerImmovable& pi, const bool found_on_load) {
if (upcast(Building, building, &pi)) {
- gain_building(*building);
+ gain_building(*building, found_on_load);
} else if (upcast(Flag const, flag, &pi)) {
new_flags.push_back(flag);
} else if (upcast(Road const, road, &pi)) {
@@ -5012,7 +5072,7 @@
}
// this is called whenever we gain a new building
-void DefaultAI::gain_building(Building& b) {
+void DefaultAI::gain_building(Building& b, const bool found_on_load) {
BuildingObserver& bo = get_building_observer(b.descr().name().c_str());
@@ -5050,10 +5110,15 @@
productionsites.back().site = &dynamic_cast<ProductionSite&>(b);
productionsites.back().bo = &bo;
productionsites.back().bo->new_building_overdue = 0;
- productionsites.back().built_time = gametime;
+ if (found_on_load && gametime > 5 * 60 * 1000) {
+ productionsites.back().built_time = gametime - 5 * 60 * 1000;
+ } else {
+ productionsites.back().built_time = gametime;
+ }
productionsites.back().unoccupied_till = gametime;
productionsites.back().stats_zero = 0;
productionsites.back().no_resources_since = kNever;
+ productionsites.back().upgrade_pending = false;
productionsites.back().bo->unoccupied_count += 1;
if (bo.is_shipyard) {
marine_task_queue.push_back(kStopShipyard);
@@ -5175,6 +5240,10 @@
i != productionsites.end();
++i)
if (i->site == &b) {
+ if (i->upgrade_pending) {
+ bo.cnt_upgrade_pending -= 1;
+ }
+ assert (bo.cnt_upgrade_pending == 0 || bo.cnt_upgrade_pending == 1);
productionsites.erase(i);
break;
}
=== modified file 'src/ai/defaultai.h'
--- src/ai/defaultai.h 2016-02-18 17:58:54 +0000
+++ src/ai/defaultai.h 2016-02-25 21:06:10 +0000
@@ -213,9 +213,9 @@
Widelands::EconomyObserver* get_economy_observer(Widelands::Economy&);
Widelands::BuildingObserver& get_building_observer(char const*);
- void gain_immovable(Widelands::PlayerImmovable&);
+ void gain_immovable(Widelands::PlayerImmovable&, bool found_on_load = false);
void lose_immovable(const Widelands::PlayerImmovable&);
- void gain_building(Widelands::Building&);
+ void gain_building(Widelands::Building&, bool found_on_load);
void lose_building(const Widelands::Building&);
void gain_ship(Widelands::Ship&, NewShip);
void check_ship_in_expedition(Widelands::ShipObserver&, uint32_t);
Follow ups
-
[Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: noreply, 2016-02-28
-
Re: [Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: GunChleoc, 2016-02-28
-
[Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: bunnybot, 2016-02-27
-
Re: [Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: TiborB, 2016-02-27
-
Re: [Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: GunChleoc, 2016-02-27
-
[Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: bunnybot, 2016-02-27
-
Re: [Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: GunChleoc, 2016-02-27
-
Re: [Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: TiborB, 2016-02-26
-
Re: [Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: GunChleoc, 2016-02-26
-
[Merge] lp:~widelands-dev/widelands/ai_upgrading_reworked into lp:widelands
From: bunnybot, 2016-02-26