TiborB has proposed merging lp:~widelands-dev/widelands/bug-1746481 into 
lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1746481 in widelands: "AI reports basic economy built to soon."
  https://bugs.launchpad.net/widelands/+bug/1746481

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1746481/+merge/337125

AI now considers a building needed for 'basic economy' finished only if fully 
occupied.
I left one DEBUG log in the code for a tester (contains word DEBUG).
There is some short gap between a building gets occupied and AI recognizes it. 
And this can cause inconsistency when a game is saved just during such period. 
But should not be very frequent....
After testing is done, I will remove NOCOM lines.
-- 
Your team Widelands Developers is requested to review the proposed merge of 
lp:~widelands-dev/widelands/bug-1746481 into lp:widelands.
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h	2017-11-17 07:16:12 +0000
+++ src/ai/ai_help_structs.h	2018-02-03 22:34:53 +0000
@@ -436,6 +436,7 @@
 	uint32_t current_stats;
 
 	uint32_t basic_amount;  // basic amount for basic economy as defined in init.lua
+	bool never_occupied;  //this switches
 
 	std::vector<Widelands::DescriptionIndex> inputs;
 	std::vector<Widelands::DescriptionIndex> outputs;

=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc	2018-01-30 11:44:48 +0000
+++ src/ai/defaultai.cc	2018-02-03 22:34:53 +0000
@@ -3702,6 +3702,16 @@
 	// Get link to productionsite that should be checked
 	ProductionSiteObserver& site = productionsites.front();
 
+	if (site.bo->never_occupied && persistent_data->remaining_basic_buildings.count(site.bo->id) > 0) {
+		printf ("DEBUG: %s first time occupied\n", site.bo->name); // NOCOM
+		if (persistent_data->remaining_basic_buildings[site.bo->id] > 1) {
+			--persistent_data->remaining_basic_buildings[site.bo->id];
+		} else {
+			persistent_data->remaining_basic_buildings.erase(site.bo->id);
+		}
+		site.bo->never_occupied = false;
+	}
+
 	// Inform if we are above ai type limit.
 	if (site.bo->total_count() > site.bo->cnt_limit_by_aimode) {
 		log("AI check_productionsites: Too many %s: %d, ai limit: %d\n", site.bo->name,
@@ -4182,6 +4192,16 @@
 	// Get link to productionsite that should be checked
 	ProductionSiteObserver& site = mines_.front();
 
+	if (site.bo->never_occupied && persistent_data->remaining_basic_buildings.count(site.bo->id) > 0) {
+		printf ("DEBUG: %s first time occupied\n", site.bo->name); // NOCOM
+		if (persistent_data->remaining_basic_buildings[site.bo->id] > 1) {
+			--persistent_data->remaining_basic_buildings[site.bo->id];
+		} else {
+			persistent_data->remaining_basic_buildings.erase(site.bo->id);
+		}
+		site.bo->never_occupied = false;
+	}
+
 	const bool connected_to_wh = !site.site->get_economy()->warehouses().empty();
 
 	// First we dismantle mines that are marked as such, generally we wait till all wares all gone
@@ -5748,18 +5768,6 @@
 		++bo.cnt_built;
 		const uint32_t gametime = game().get_gametime();
 		bo.last_building_built = gametime;
-		// erase building from remaining_basic_buildings, unless we are loading a saved game
-		if (!found_on_load && persistent_data->remaining_basic_buildings.count(bo.id) > 0) {
-			if (persistent_data->remaining_basic_buildings[bo.id] > 1) {
-				--persistent_data->remaining_basic_buildings[bo.id];
-			} else {
-				persistent_data->remaining_basic_buildings.erase(bo.id);
-			}
-		}
-		// Remaining basic buildings map contain either no entry for the building, or the number is
-		// nonzero
-		assert(persistent_data->remaining_basic_buildings.count(bo.id) == 0 ||
-		       persistent_data->remaining_basic_buildings[bo.id] > 0);
 
 		if (bo.type == BuildingObserver::Type::kProductionsite) {
 			productionsites.push_back(ProductionSiteObserver());
@@ -5786,6 +5794,14 @@
 
 			for (uint32_t i = 0; i < bo.inputs.size(); ++i)
 				++wares.at(bo.inputs.at(i)).consumers;
+
+			if (!found_on_load) {
+				// If this is brand new building, setting as never occupied
+				bo.never_occupied = true;
+			} else {
+				// otherwise just find out
+				bo.never_occupied = !productionsites.back().site->can_start_working();
+			}
 		} else if (bo.type == BuildingObserver::Type::kMine) {
 			mines_.push_back(ProductionSiteObserver());
 			mines_.back().site = &dynamic_cast<ProductionSite&>(b);
@@ -5810,6 +5826,14 @@
 
 			set_inputs_to_zero(mines_.back());
 
+
+			// If this is brand new building, setting as never occupied
+			if (!found_on_load) {
+				bo.never_occupied = false;
+			} else {
+				// otherwise just find out
+				bo.never_occupied = productionsites.back().site->can_start_working();
+			}
 		} else if (bo.type == BuildingObserver::Type::kMilitarysite) {
 			militarysites.push_back(MilitarySiteObserver());
 			militarysites.back().site = &dynamic_cast<MilitarySite&>(b);
@@ -5829,6 +5853,13 @@
 			trainingsites.push_back(TrainingSiteObserver());
 			trainingsites.back().site = &dynamic_cast<TrainingSite&>(b);
 			trainingsites.back().bo = &bo;
+			// If this is brand new building, setting as never occupied
+			if (!found_on_load) {
+				bo.never_occupied = false;
+			} else {
+				// otherwise just find out
+				bo.never_occupied = productionsites.back().site->can_start_working();
+			}
 
 		} else if (bo.type == BuildingObserver::Type::kWarehouse) {
 			++numof_warehouses_;

=== modified file 'src/ai/defaultai_warfare.cc'
--- src/ai/defaultai_warfare.cc	2017-11-13 09:10:04 +0000
+++ src/ai/defaultai_warfare.cc	2018-02-03 22:34:53 +0000
@@ -575,6 +575,17 @@
 	TrainingSite* ts = trainingsites.front().site;
 	TrainingSiteObserver& tso = trainingsites.front();
 
+	// In case this trainingsite is among basic buildings
+	if (tso.bo->never_occupied && persistent_data->remaining_basic_buildings.count(tso.bo->id) > 0) {
+		printf ("DEBUG: %s first time occupied - erasing from basic economy list\n", tso.bo->name); //NOCOM
+		if (persistent_data->remaining_basic_buildings[tso.bo->id] > 1) {
+			--persistent_data->remaining_basic_buildings[tso.bo->id];
+		} else {
+			persistent_data->remaining_basic_buildings.erase(tso.bo->id);
+		}
+		tso.bo->never_occupied = false;
+	}
+
 	// Inform if we are above ai type limit.
 	if (tso.bo->total_count() > tso.bo->cnt_limit_by_aimode) {
 		log("AI check_trainingsites: AI player %d: count of %s exceeds an AI limit %d: actual count: "

_______________________________________________
Mailing list: https://launchpad.net/~widelands-dev
Post to     : widelands-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~widelands-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to