Author: cazfi
Date: Thu Nov 19 22:08:45 2015
New Revision: 30697

URL: http://svn.gna.org/viewcvs/freeciv?rev=30697&view=rev
Log:
Cache unit type vs unit type defense multiplier combat bonuses, and use those 
cached
values instead of recalculating them every time they are needed.

See patch #6546

Modified:
    trunk/ai/default/advmilitary.c
    trunk/ai/default/aitech.c
    trunk/client/packhand.c
    trunk/common/combat.c
    trunk/common/unittype.c
    trunk/common/unittype.h
    trunk/server/ruleset.c

Modified: trunk/ai/default/advmilitary.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/advmilitary.c?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/ai/default/advmilitary.c      (original)
+++ trunk/ai/default/advmilitary.c      Thu Nov 19 22:08:45 2015
@@ -496,36 +496,24 @@
   } unit_type_iterate_end;
 
   unit_list_iterate(ptile->units, punit) {
-    bool bonuses_exist = FALSE;
     struct unit_type *def = unit_type_get(punit);
 
     if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
       city_data->has_diplomat = TRUE;
     }
     if (!defender_type_handled[utype_index(def)]) {
-      /* This is first defender of this type. Calculate defender type
+      /* This is first defender of this type. Check defender type
        * specific bonuses. */
 
-      /* Vast majority of units have no Defense Multiplier bonus.
-       * Do not waste time on iterating through all unit types in the
-       * typical case by first checking if such bonuses exist against
-       * any units. */
-      combat_bonus_list_iterate(def->bonuses, pbonus) {
-        if (pbonus->type == CBONUS_DEFENSE_MULTIPLIER) {
-          bonuses_exist = TRUE;
-          break;
-        }
-      } combat_bonus_list_iterate_end;
-
-      if (bonuses_exist) {
+      /* Skip defenders that have no bonuses at all. Acceptable
+       * side-effect is that we can't consider negative bonuses at
+       * all ("No bonuses" should be better than "negative bonus") */
+      if (def->cache.max_defense_mp > 0) {
         unit_type_iterate(utype) {
-          int bonus;
           int idx = utype_index(utype);
 
-          bonus = combat_bonus_against(def->bonuses, utype,
-                                       CBONUS_DEFENSE_MULTIPLIER);
-          if (bonus > defense_bonuses[idx]) {
-            defense_bonuses[idx] = bonus;
+          if (def->cache.defense_mp_bonuses[idx] > defense_bonuses[idx]) {
+            defense_bonuses[idx] = def->cache.defense_mp_bonuses[idx];
           }
         } unit_type_iterate_end;
       }
@@ -691,12 +679,7 @@
   desire += punittype->move_rate / SINGLE_MOVE;
   desire += attack;
 
-  combat_bonus_list_iterate(punittype->bonuses, pbonus) {
-    if (pbonus->type == CBONUS_DEFENSE_MULTIPLIER
-        && pbonus->value > maxbonus) {
-      maxbonus = pbonus->value;
-    }
-  } combat_bonus_list_iterate_end;
+  maxbonus = punittype->cache.max_defense_mp;
   if (maxbonus > 1) {
     maxbonus = (maxbonus + 1) / 2;
   }
@@ -704,6 +687,7 @@
   if (utype_has_flag(punittype, UTYF_GAMELOSS)) {
     desire /= 10; /* but might actually be worth it */
   }
+
   return desire;
 }
 

Modified: trunk/ai/default/aitech.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/aitech.c?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/ai/default/aitech.c   (original)
+++ trunk/ai/default/aitech.c   Thu Nov 19 22:08:45 2015
@@ -373,9 +373,10 @@
   struct advance *best_tech = A_NEVER;
   struct unit_type *best_unit = NULL;
   int def_values[U_LAST];
+  int att_idx = utype_index(att);
 
   unit_type_iterate(deftype) {
-    int mp = combat_bonus_against(deftype->bonuses, att, 
CBONUS_DEFENSE_MULTIPLIER) + 1;
+    int mp = deftype->cache.defense_mp_bonuses[att_idx] + 1;
     int div = combat_bonus_against(att->bonuses, deftype, 
CBONUS_DEFENSE_DIVIDER) + 1;
     int def = deftype->defense_strength * mp / div;
 

Modified: trunk/client/packhand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/packhand.c?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/client/packhand.c     (original)
+++ trunk/client/packhand.c     Thu Nov 19 22:08:45 2015
@@ -3077,9 +3077,10 @@
   road_integrators_cache_init();
 
   /* Setup unit unknown move cost caches */
-  unit_type_iterate(u) {
-    u->unknown_move_cost = utype_unknown_move_cost(u);
-    unit_type_action_cache_set(u);
+  unit_type_iterate(ptype) {
+    ptype->unknown_move_cost = utype_unknown_move_cost(ptype);
+    set_unit_type_caches(ptype);
+    unit_type_action_cache_set(ptype);
   } unit_type_iterate_end;
 
   /* Cache what city production can receive help from caravans. */

Modified: trunk/common/combat.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/combat.c?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/common/combat.c       (original)
+++ trunk/common/combat.c       Thu Nov 19 22:08:45 2015
@@ -515,8 +515,7 @@
 
   if (NULL != att_type) {
     int defense_divider;
-    int defense_multiplier = 1 + combat_bonus_against(def_type->bonuses, 
att_type,
-                                                      
CBONUS_DEFENSE_MULTIPLIER);
+    int defense_multiplier = 1 + 
def_type->cache.defense_mp_bonuses[utype_index(att_type)];
 
     defensepower *= defense_multiplier;
 
@@ -747,6 +746,9 @@
 
 /**************************************************************************
   Get bonus value against given unit type from bonus list.
+
+  Consider using cached values instead of calling this recalculation
+  directly.
 **************************************************************************/
 int combat_bonus_against(const struct combat_bonus_list *list,
                          const struct unit_type *enemy,

Modified: trunk/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.c?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/common/unittype.c     (original)
+++ trunk/common/unittype.c     Thu Nov 19 22:08:45 2015
@@ -29,6 +29,7 @@
 
 /* common */
 #include "ai.h"
+#include "combat.h"
 #include "game.h"
 #include "government.h"
 #include "movement.h"
@@ -1862,6 +1863,24 @@
       unit_class_list_append(pclass->cache.subset_movers, pcharge);
     }
   } unit_class_iterate_end;
+}
+
+/****************************************************************************
+  Set caches for unit types.
+****************************************************************************/
+void set_unit_type_caches(struct unit_type *ptype)
+{
+  ptype->cache.max_defense_mp = -FC_INFINITY;
+
+  unit_type_iterate(utype) {
+    int idx = utype_index(utype);
+
+    ptype->cache.defense_mp_bonuses[idx] = 
combat_bonus_against(ptype->bonuses, utype,
+                                                                
CBONUS_DEFENSE_MULTIPLIER);
+    if (ptype->cache.defense_mp_bonuses[idx] > ptype->cache.max_defense_mp) {
+      ptype->cache.max_defense_mp = ptype->cache.defense_mp_bonuses[idx];
+    }
+  } unit_type_iterate_end;
 }
 
 /**************************************************************************

Modified: trunk/common/unittype.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.h?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/common/unittype.h     (original)
+++ trunk/common/unittype.h     Thu Nov 19 22:08:45 2015
@@ -501,6 +501,13 @@
     bool igwall;
   } adv;
 
+  struct {
+    int max_defense_mp; /* Value 0 here does not guarantee that unit never
+                         * has CBONUS_DEFENSE_MULTIPLIER, it merely means
+                         * that there's no POSITIVE one */
+    int defense_mp_bonuses[U_LAST];
+  } cache;
+
   void *ais[FC_AI_LAST];
 };
 
@@ -700,6 +707,7 @@
 void unit_classes_free(void);
 
 void set_unit_class_caches(struct unit_class *pclass);
+void set_unit_type_caches(struct unit_type *ptype);
 
 struct unit_class *unit_class_array_first(void);
 const struct unit_class *unit_class_array_last(void);

Modified: trunk/server/ruleset.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/ruleset.c?rev=30697&r1=30696&r2=30697&view=diff
==============================================================================
--- trunk/server/ruleset.c      (original)
+++ trunk/server/ruleset.c      Thu Nov 19 22:08:45 2015
@@ -7232,8 +7232,9 @@
     unit_class_iterate(pclass) {
       set_unit_class_caches(pclass);
     } unit_class_iterate_end;
-    unit_type_iterate(u) {
-      u->unknown_move_cost = utype_unknown_move_cost(u);
+    unit_type_iterate(ptype) {
+      ptype->unknown_move_cost = utype_unknown_move_cost(ptype);
+      set_unit_type_caches(ptype);
     } unit_type_iterate_end;
     city_production_caravan_shields_init();
 


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to