Author: cazfi
Date: Fri Apr 24 17:34:48 2015
New Revision: 28857

URL: http://svn.gna.org/viewcvs/freeciv?rev=28857&view=rev
Log:
Turned inner part of tai_city_worker_task_select(), checking single tile, to a 
separate function

See patch #6025

Modified:
    trunk/ai/threaded/taicity.c

Modified: trunk/ai/threaded/taicity.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/threaded/taicity.c?rev=28857&r1=28856&r2=28857&view=diff
==============================================================================
--- trunk/ai/threaded/taicity.c (original)
+++ trunk/ai/threaded/taicity.c Fri Apr 24 17:34:48 2015
@@ -77,57 +77,135 @@
   }
 }
 
+struct tai_tile_state
+{
+  int uw_max;
+  int worst_worked;
+  int orig_worst_worked;
+  int old_worst_worked;
+};
+
 /**************************************************************************
-  Select worker task suitable for the city.
-
-  TODO: This largely duplicates settler_evaluate_improvements(). Should
-        maybe find a way to reuse parts in some common function. OTOH
-        though this has started as almost-copy of
-        settler_evaluate_improvements(), this is likely to turn very different
-        function as part of threaded ai with more CPU to burn.
+  Select worker task suitable for the tile.
 **************************************************************************/
-static bool tai_city_worker_task_select(struct player *pplayer, struct city 
*pcity,
-                                        struct worker_task *task,
-                                        enum tai_worker_task_limitation limit)
-{
-  struct worker_task *selected;
-  struct worker_task worked = { .ptile = NULL, .want = 0, .act = 
ACTIVITY_IDLE, .tgt = NULL };
-  struct worker_task unworked = { .ptile = NULL, .want = 0, .act = 
ACTIVITY_IDLE, .tgt = NULL };
-  int uw_max = 0;
-  int worst_worked = FC_INFINITY;
-  int old_worst_worked = FC_INFINITY;
-  int orig_worst_worked = 0;
-  struct unit_list *units = NULL;
-
-  switch (limit) {
-  case TWTL_CURRENT_UNITS:
-    units = pplayer->units;
-    break;
-  }
-
-  city_tile_iterate_index(city_map_radius_sq_get(pcity), city_tile(pcity),
-                          ptile, cindex) {
-    int orig_value;
-    bool potential_worst_worked = FALSE;
-
-    if (!city_can_work_tile(pcity, ptile)) {
+static void tai_tile_worker_task_select(struct player *pplayer,
+                                        struct city *pcity, struct tile *ptile,
+                                        int cindex, struct unit_list *units,
+                                        struct worker_task *worked,
+                                        struct worker_task *unworked,
+                                        struct tai_tile_state *state)
+{
+  int orig_value;
+  bool potential_worst_worked = FALSE;
+
+  if (!city_can_work_tile(pcity, ptile)) {
+    return;
+  }
+
+  orig_value = city_tile_value(pcity, ptile, 0, 0);
+
+  if (tile_worked(ptile) == pcity
+      && orig_value < state->worst_worked) {
+    state->worst_worked = orig_value;
+    state->orig_worst_worked = orig_value;
+    potential_worst_worked = TRUE;
+  }
+
+  as_transform_activity_iterate(act) {
+    bool consider = TRUE;
+    bool possible = FALSE;
+    enum extra_cause cause;
+    enum extra_rmcause rmcause;
+
+    /* Do not request activities that already are under way. */
+    unit_list_iterate(ptile->units, punit) {
+      if (unit_owner(punit) == pplayer
+          && unit_has_type_flag(punit, UTYF_SETTLERS)
+          && punit->activity == act) {
+        consider = FALSE;
+        break;
+      }
+    } unit_list_iterate_end;
+
+    if (!consider) {
       continue;
     }
 
-    orig_value = city_tile_value(pcity, ptile, 0, 0);
-
-    if (tile_worked(ptile) == pcity
-        && orig_value < worst_worked) {
-      worst_worked = orig_value;
-      orig_worst_worked = orig_value;
-      potential_worst_worked = TRUE;
+    cause = activity_to_extra_cause(act);
+    rmcause = activity_to_extra_rmcause(act);
+
+    unit_list_iterate(units, punit) {
+      struct extra_type *tgt = NULL;
+
+      if (cause != EC_NONE) {
+        tgt = next_extra_for_tile(ptile, cause, pplayer, punit);
+      } else if (rmcause != ERM_NONE) {
+        tgt = prev_extra_in_tile(ptile, rmcause, pplayer, punit);
+      }
+
+      if (can_unit_do_activity_targeted_at(punit, act, tgt, ptile)) {
+        possible = TRUE;
+        break;
+      }
+    } unit_list_iterate_end;
+
+    if (possible) {
+      int value = adv_city_worker_act_get(pcity, cindex, act);
+
+      if (tile_worked(ptile) == pcity) {
+        if ((value - orig_value) * TWMP > worked->want) {
+          worked->want  = TWMP * (value - orig_value);
+          worked->ptile = ptile;
+          worked->act   = act;
+          worked->tgt   = NULL;
+        }
+        if (value > state->old_worst_worked) {
+          /* After improvement it would not be the worst */
+          potential_worst_worked = FALSE;
+        } else {
+          state->worst_worked = value;
+        }
+      } else {
+        if (value > orig_value && value > state->uw_max) {
+          state->uw_max = value;
+          unworked->want  = TWMP * (value - orig_value);
+          unworked->ptile = ptile;
+          unworked->act   = act;
+          unworked->tgt   = NULL;
+        }
+      }
     }
-
-    as_transform_activity_iterate(act) {
+  } as_transform_activity_iterate_end;
+
+  extra_type_iterate(tgt) {
+    enum unit_activity act = ACTIVITY_LAST;
+    bool removing = tile_has_extra(ptile, tgt);
+
+    unit_list_iterate(units, punit) {
+      if (removing) {
+        as_rmextra_activity_iterate(try_act) {
+          if (is_extra_removed_by_action(tgt, try_act)
+              && can_unit_do_activity_targeted_at(punit, try_act, tgt, ptile)) 
{
+            act = try_act;
+            break;
+          }
+        } as_rmextra_activity_iterate_end;
+      } else {
+        as_extra_activity_iterate(try_act) {
+          if (is_extra_caused_by_action(tgt, try_act)
+              && can_unit_do_activity_targeted_at(punit, try_act, tgt, ptile)) 
{
+            act = try_act;
+            break;
+          }
+        } as_extra_activity_iterate_end;
+      }
+    } unit_list_iterate_end;
+
+    if (act != ACTIVITY_LAST) {
+      int value;
+      int extra;
       bool consider = TRUE;
-      bool possible = FALSE;
-      enum extra_cause cause;
-      enum extra_rmcause rmcause;
+      struct road_type *proad;
 
       /* Do not request activities that already are under way. */
       unit_list_iterate(ptile->units, punit) {
@@ -143,175 +221,112 @@
         continue;
       }
 
-      cause = activity_to_extra_cause(act);
-      rmcause = activity_to_extra_rmcause(act);
-
-      unit_list_iterate(units, punit) {
-        struct extra_type *tgt = NULL;
-
-        if (cause != EC_NONE) {
-          tgt = next_extra_for_tile(ptile, cause, pplayer, punit);
-        } else if (rmcause != ERM_NONE) {
-          tgt = prev_extra_in_tile(ptile, rmcause, pplayer, punit);
-        }
-
-        if (can_unit_do_activity_targeted_at(punit, act, tgt, ptile)) {
-          possible = TRUE;
-          break;
-        }
-      } unit_list_iterate_end;
-
-      if (possible) {
-        int value = adv_city_worker_act_get(pcity, cindex, act);
-
-        if (tile_worked(ptile) == pcity) {
-          if ((value - orig_value) * TWMP > worked.want) {
-            worked.want  = TWMP * (value - orig_value);
-            worked.ptile = ptile;
-            worked.act   = act;
-            worked.tgt   = NULL;
-          }
-          if (value > old_worst_worked) {
-            /* After improvement it would not be the worst */
-            potential_worst_worked = FALSE;
-          } else {
-            worst_worked = value;
-          }
-        } else {
-          if (value > orig_value && value > uw_max) {
-            uw_max = value;
-            unworked.want  = TWMP * (value - orig_value);
-            unworked.ptile = ptile;
-            unworked.act   = act;
-            unworked.tgt   = NULL;
-          }
-        }
-      }
-    } as_transform_activity_iterate_end;
-
-    extra_type_iterate(tgt) {
-      enum unit_activity act = ACTIVITY_LAST;
-      bool removing = tile_has_extra(ptile, tgt);
-
-      unit_list_iterate(units, punit) {
-        if (removing) {
-          as_rmextra_activity_iterate(try_act) {
-            if (is_extra_removed_by_action(tgt, try_act)
-                && can_unit_do_activity_targeted_at(punit, try_act, tgt, 
ptile)) {
-              act = try_act;
-              break;
-            }
-          } as_rmextra_activity_iterate_end;
-        } else {
-          as_extra_activity_iterate(try_act) {
-            if (is_extra_caused_by_action(tgt, try_act)
-                && can_unit_do_activity_targeted_at(punit, try_act, tgt, 
ptile)) {
-              act = try_act;
-              break;
-            }
-          } as_extra_activity_iterate_end;
-        }
-      } unit_list_iterate_end;
-
-      if (act != ACTIVITY_LAST) {
-        int value;
-        int extra;
-        bool consider = TRUE;
-        struct road_type *proad;
-
-        /* Do not request activities that already are under way. */
-        unit_list_iterate(ptile->units, punit) {
-          if (unit_owner(punit) == pplayer
-              && unit_has_type_flag(punit, UTYF_SETTLERS)
-              && punit->activity == act) {
-            consider = FALSE;
-            break;
-          }
-        } unit_list_iterate_end;
-
-        if (!consider) {
-          continue;
-        }
-
-        proad = extra_road_get(tgt);
-
-        value = adv_city_worker_extra_get(pcity, cindex, tgt);
-
-        if (proad != NULL && road_provides_move_bonus(proad)) {
-          int old_move_cost;
-          int mc_multiplier = 1;
-          int mc_divisor = 1;
-
-          /* Here 'old' means actually 'without the evaluated': In case of
-           * removal activity it's the value after the removal. */
-          old_move_cost = tile_terrain(ptile)->movement_cost * SINGLE_MOVE;
-
-          road_type_iterate(pold) {
-            if (tile_has_road(ptile, pold) && pold != proad) {
-              if (road_provides_move_bonus(pold)
-                  && pold->move_cost < old_move_cost) {
-                old_move_cost = pold->move_cost;
-              }
-            }
-          } road_type_iterate_end;
-
-          if (proad->move_cost < old_move_cost) {
-            if (proad->move_cost >= terrain_control.move_fragments) {
-              mc_divisor = proad->move_cost / terrain_control.move_fragments;
-            } else {
-              if (proad->move_cost == 0) {
-                mc_multiplier = 2;
-              } else {
-                mc_multiplier = 1 - proad->move_cost;
-              }
-              mc_multiplier += old_move_cost;
+      proad = extra_road_get(tgt);
+
+      value = adv_city_worker_extra_get(pcity, cindex, tgt);
+
+      if (proad != NULL && road_provides_move_bonus(proad)) {
+        int old_move_cost;
+        int mc_multiplier = 1;
+        int mc_divisor = 1;
+
+        /* Here 'old' means actually 'without the evaluated': In case of
+         * removal activity it's the value after the removal. */
+        old_move_cost = tile_terrain(ptile)->movement_cost * SINGLE_MOVE;
+
+        road_type_iterate(pold) {
+          if (tile_has_road(ptile, pold) && pold != proad) {
+            if (road_provides_move_bonus(pold)
+                && pold->move_cost < old_move_cost) {
+              old_move_cost = pold->move_cost;
             }
           }
-
-          extra = adv_settlers_road_bonus(ptile, proad) * mc_multiplier / 
mc_divisor;
-
-          if (removing) {
-            extra = -extra;
+        } road_type_iterate_end;
+
+        if (proad->move_cost < old_move_cost) {
+          if (proad->move_cost >= terrain_control.move_fragments) {
+            mc_divisor = proad->move_cost / terrain_control.move_fragments;
+          } else {
+            if (proad->move_cost == 0) {
+              mc_multiplier = 2;
+            } else {
+              mc_multiplier = 1 - proad->move_cost;
+            }
+            mc_multiplier += old_move_cost;
           }
+        }
+
+        extra = adv_settlers_road_bonus(ptile, proad) * mc_multiplier / 
mc_divisor;
+
+        if (removing) {
+          extra = -extra;
+        }
+      } else {
+        extra = 0;
+      }
+
+      value += extra;
+
+      if (tile_worked(ptile) == pcity) {
+        if ((value - orig_value) * TWMP > worked->want) {
+          worked->want  = TWMP * (value - orig_value);
+          worked->ptile = ptile;
+          worked->act   = act;
+          worked->tgt   = tgt;
+        }
+        if (value > state->old_worst_worked) {
+          /* After improvement it would not be the worst */
+          potential_worst_worked = FALSE;
         } else {
-          extra = 0;
-        }
-
-        value += extra;
-
-        if (tile_worked(ptile) == pcity) {
-          if ((value - orig_value) * TWMP > worked.want) {
-            worked.want  = TWMP * (value - orig_value);
-            worked.ptile = ptile;
-            worked.act   = act;
-            worked.tgt   = tgt;
-          }
-          if (value > old_worst_worked) {
-            /* After improvement it would not be the worst */
-            potential_worst_worked = FALSE;
-          } else {
-            worst_worked = value;
-          }
-        } else {
-          if (value > orig_value && value > uw_max) {
-            uw_max = value;
-            unworked.want  = TWMP * (value - orig_value);
-            unworked.ptile = ptile;
-            unworked.act   = act;
-            unworked.tgt   = tgt;
-          }
-        }
-      }
-    } extra_type_iterate_end;
-
-    if (potential_worst_worked) {
-      /* Would still be worst worked even if we improved *it*. */
-      old_worst_worked = worst_worked;
+          state->worst_worked = value;
+        }
+      } else {
+        if (value > orig_value && value > state->uw_max) {
+          state->uw_max = value;
+          unworked->want  = TWMP * (value - orig_value);
+          unworked->ptile = ptile;
+          unworked->act   = act;
+          unworked->tgt   = tgt;
+        }
+      }
     }
+  } extra_type_iterate_end;
+
+  if (potential_worst_worked) {
+    /* Would still be worst worked even if we improved *it*. */
+    state->old_worst_worked = state->worst_worked;
+  }
+}
+
+/**************************************************************************
+  Select worker task suitable for the city.
+**************************************************************************/
+static bool tai_city_worker_task_select(struct player *pplayer, struct city 
*pcity,
+                                        struct worker_task *task,
+                                        enum tai_worker_task_limitation limit)
+{
+  struct worker_task *selected;
+  struct worker_task worked = { .ptile = NULL, .want = 0, .act = 
ACTIVITY_IDLE, .tgt = NULL };
+  struct worker_task unworked = { .ptile = NULL, .want = 0, .act = 
ACTIVITY_IDLE, .tgt = NULL };
+  struct tai_tile_state state = { .uw_max = 0, .worst_worked = FC_INFINITY,
+                                  .orig_worst_worked = 0, .old_worst_worked = 
FC_INFINITY };
+  struct unit_list *units = NULL;
+
+  switch (limit) {
+  case TWTL_CURRENT_UNITS:
+    units = pplayer->units;
+    break;
+  }
+
+  city_tile_iterate_index(city_map_radius_sq_get(pcity), city_tile(pcity),
+                          ptile, cindex) {
+    tai_tile_worker_task_select(pplayer, pcity, ptile, cindex, units, &worked, 
&unworked,
+                                &state);
   } city_tile_iterate_end;
 
   if (worked.ptile == NULL
-      || (old_worst_worked < uw_max && (uw_max - orig_worst_worked) * TWMP > 
worked.want)) {
+      || (state.old_worst_worked < state.uw_max
+          && (state.uw_max - state.orig_worst_worked) * TWMP > worked.want)) {
     /* It's better to improve best yet unworked tile and take it to use after 
that,
        than to improve already worked tile. */
     selected = &unworked;


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

Reply via email to