GunChleoc has proposed merging 
lp:~widelands-dev/widelands/bug-1716166-ai-strength-assert into lp:widelands.

Commit message:
Fixed hard-coded values in DefaultAI::calculate_strength

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1716166 in widelands: "DefaultAI::calculate_strength assert fails"
  https://bugs.launchpad.net/widelands/+bug/1716166

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1716166-ai-strength-assert/+merge/333227
-- 
Your team Widelands Developers is requested to review the proposed merge of 
lp:~widelands-dev/widelands/bug-1716166-ai-strength-assert into lp:widelands.
=== modified file 'src/ai/defaultai_warfare.cc'
--- src/ai/defaultai_warfare.cc	2017-09-29 16:10:25 +0000
+++ src/ai/defaultai_warfare.cc	2017-11-03 19:57:51 +0000
@@ -166,19 +166,19 @@
 				owner_number = bld->owner().player_number();
 			}
 		}
-		if (upcast(Warehouse, Wh, f.field->get_immovable())) {
-			if (player_->is_hostile(Wh->owner())) {
+		if (upcast(Warehouse, wh, f.field->get_immovable())) {
+			if (player_->is_hostile(wh->owner())) {
 
 				std::vector<Soldier*> defenders;
-				defenders = Wh->soldier_control()->present_soldiers();
+				defenders = wh->soldier_control()->present_soldiers();
 				defenders_strength = calculate_strength(defenders);
 
-				flag = &Wh->base_flag();
+				flag = &wh->base_flag();
 				is_warehouse = true;
-				if (is_visible && Wh->attack_target()->can_be_attacked()) {
+				if (is_visible && wh->attack_target()->can_be_attacked()) {
 					is_attackable = true;
 				}
-				owner_number = Wh->owner().player_number();
+				owner_number = wh->owner().player_number();
 			}
 		}
 
@@ -888,7 +888,6 @@
 // This calculates strength of vector of soldiers, f.e. soldiers in a building or
 // ones ready to attack
 int32_t DefaultAI::calculate_strength(const std::vector<Widelands::Soldier*>& soldiers) {
-
 	if (soldiers.empty()) {
 		return 0;
 	}
@@ -899,21 +898,31 @@
 	float evade = 0;
 	float final = 0;
 
+	const SoldierDescr& descr = soldiers.front()->descr();
+
 	for (Soldier* soldier : soldiers) {
-		const SoldierDescr& descr = soldier->descr();
 		health = soldier->get_current_health();
 		attack = (descr.get_base_max_attack() - descr.get_base_min_attack()) / 2.f +
 		         descr.get_base_min_attack() +
 		         descr.get_attack_incr_per_level() * soldier->get_attack_level();
-		defense = 100 - descr.get_base_defense() - 8 * soldier->get_defense_level();
+		defense = 100 - descr.get_base_defense() - descr.get_defense_incr_per_level() * soldier->get_defense_level();
 		evade = 100 - descr.get_base_evade() -
 		        descr.get_evade_incr_per_level() / 100.f * soldier->get_evade_level();
 		final += (attack * health) / (defense * evade);
 	}
+
 	assert(final >= 0);
-	assert(final <= 25000 * soldiers.size());
-	// 2500 is aproximate strength of one unpromoted soldier
-	return static_cast<int32_t>(final / 2500);
+	assert(final <= soldiers.size() * (descr.get_base_max_attack() * descr.get_base_health()
+												  + descr.get_max_attack_level() * descr.get_attack_incr_per_level()
+												  + descr.get_max_health_level() * descr.get_health_incr_per_level()));
+
+	// We divide the result by the aproximate strength of one unpromoted soldier
+	const int average_unpromoted_strength =
+			(descr.get_base_min_attack() + (descr.get_base_max_attack()
+																 - descr.get_base_min_attack()) / 2)
+			* descr.get_base_health() / (descr.get_base_defense() * descr.get_base_evade());
+
+	return static_cast<int32_t>(final / average_unpromoted_strength);
 }
 
 // Now we can prohibit some militarysites, based on size, the goal is not to

_______________________________________________
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