Author: cazfi
Date: Mon Jan  2 00:20:46 2017
New Revision: 34769

URL: http://svn.gna.org/viewcvs/freeciv?rev=34769&view=rev
Log:
Refactor threaded AI to make it more similar to threxpr.

See patch #7559

Modified:
    trunk/ai/threaded/taicity.c
    trunk/ai/threaded/taicity.h
    trunk/ai/threaded/taiplayer.c

Modified: trunk/ai/threaded/taicity.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/threaded/taicity.c?rev=34769&r1=34768&r2=34769&view=diff
==============================================================================
--- trunk/ai/threaded/taicity.c (original)
+++ trunk/ai/threaded/taicity.c Mon Jan  2 00:20:46 2017
@@ -49,10 +49,12 @@
 };
 
 enum tai_worker_task_limitation {
-  TWTL_CURRENT_UNITS
+  TWTL_CURRENT_UNITS,
+  TWTL_BUILDABLE_UNITS
 };
 
-static bool tai_city_worker_task_select(struct player *pplayer, struct city 
*pcity,
+static bool tai_city_worker_task_select(struct ai_type *ait,
+                                        struct player *pplayer, struct city 
*pcity,
                                         struct worker_task *task,
                                         enum tai_worker_task_limitation limit);
 
@@ -60,11 +62,12 @@
   Create worker request for the city. Only tasks that existing units can
   do are created.
 **************************************************************************/
-void tai_city_worker_requests_create(struct player *pplayer, struct city 
*pcity)
+void tai_city_worker_requests_create(struct ai_type *ait,
+                                     struct player *pplayer, struct city 
*pcity)
 {
   struct worker_task task;
 
-  if (tai_city_worker_task_select(pplayer, pcity, &task, TWTL_CURRENT_UNITS)) {
+  if (tai_city_worker_task_select(ait, pplayer, pcity, &task, 
TWTL_CURRENT_UNITS)) {
     struct tai_worker_task_req *data = fc_malloc(sizeof(*data));
 
     data->city_id = pcity->id;
@@ -83,7 +86,10 @@
   int worst_worked;
   int orig_worst_worked;
   int old_worst_worked;
+  int *wants;
 };
+
+static int dummy_wants[U_LAST];
 
 /**************************************************************************
   Select worker task suitable for the tile.
@@ -93,7 +99,8 @@
                                         int cindex, struct unit_list *units,
                                         struct worker_task *worked,
                                         struct worker_task *unworked,
-                                        struct tai_tile_state *state)
+                                        struct tai_tile_state *state,
+                                        enum tai_worker_task_limitation limit)
 {
   int orig_value;
   bool potential_worst_worked = FALSE;
@@ -114,6 +121,7 @@
   as_transform_activity_iterate(act) {
     bool consider = TRUE;
     bool possible = FALSE;
+    struct extra_type *tgt = NULL;
     enum extra_cause cause;
     enum extra_rmcause rmcause;
 
@@ -135,8 +143,6 @@
     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) {
@@ -154,10 +160,18 @@
 
       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;
+          worked->want       = TWMP * (value - orig_value);
+          worked->ptile      = ptile;
+          worked->act        = act;
+          worked->tgt        = NULL;
+          worked->tgt        = NULL;
+          if (limit == TWTL_BUILDABLE_UNITS) {
+            unit_list_iterate(units, punit) {
+              if (can_unit_do_activity_targeted_at(punit, act, tgt, ptile)) {
+                state->wants[utype_index(unit_type_get(punit))] += 
worked->want;
+              }
+            } unit_list_iterate_end;
+          }         
         }
         if (value > state->old_worst_worked) {
           /* After improvement it would not be the worst */
@@ -167,11 +181,18 @@
         }
       } else {
         if (value > orig_value && value > state->uw_max) {
-          state->uw_max = value;
+          state->uw_max   = value;
           unworked->want  = TWMP * (value - orig_value);
           unworked->ptile = ptile;
           unworked->act   = act;
           unworked->tgt   = NULL;
+          if (limit == TWTL_BUILDABLE_UNITS) {
+            unit_list_iterate(units, punit) {
+              if (can_unit_do_activity_targeted_at(punit, act, tgt, ptile)) {
+                state->wants[utype_index(unit_type_get(punit))] += 
unworked->want;
+              }
+            } unit_list_iterate_end;
+          }
         }
       }
     }
@@ -275,6 +296,13 @@
           worked->ptile = ptile;
           worked->act   = act;
           worked->tgt   = tgt;
+          if (limit == TWTL_BUILDABLE_UNITS) {
+            unit_list_iterate(units, punit) {
+              if (can_unit_do_activity_targeted_at(punit, act, tgt, ptile)) {
+                state->wants[utype_index(unit_type_get(punit))] += 
worked->want;
+              }
+            } unit_list_iterate_end;
+          }
         }
         if (value > state->old_worst_worked) {
           /* After improvement it would not be the worst */
@@ -284,11 +312,18 @@
         }
       } else {
         if (value > orig_value && value > state->uw_max) {
-          state->uw_max = value;
+          state->uw_max   = value;
           unworked->want  = TWMP * (value - orig_value);
           unworked->ptile = ptile;
           unworked->act   = act;
           unworked->tgt   = tgt;
+          if (limit == TWTL_BUILDABLE_UNITS) {
+            unit_list_iterate(units, punit) {
+              if (can_unit_do_activity_targeted_at(punit, act, tgt, ptile)) {
+                state->wants[utype_index(unit_type_get(punit))] += 
unworked->want;
+              }
+            } unit_list_iterate_end;
+          }
         }
       }
     }
@@ -303,7 +338,8 @@
 /**************************************************************************
   Select worker task suitable for the city.
 **************************************************************************/
-static bool tai_city_worker_task_select(struct player *pplayer, struct city 
*pcity,
+static bool tai_city_worker_task_select(struct ai_type *ait,
+                                        struct player *pplayer, struct city 
*pcity,
                                         struct worker_task *task,
                                         enum tai_worker_task_limitation limit)
 {
@@ -317,13 +353,23 @@
   switch (limit) {
   case TWTL_CURRENT_UNITS:
     units = pplayer->units;
+    state.wants = NULL;
+    break;
+  case TWTL_BUILDABLE_UNITS:
+    units = unit_list_new();
+    unit_type_iterate(ptype) {
+      if (can_city_build_unit_now(pcity, ptype)) {
+        unit_list_append(units, unit_virtual_create(pplayer, pcity, ptype, 0));
+      }
+    } unit_type_iterate_end;
+    state.wants = dummy_wants;
     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);
+                                &state, limit);
   } city_tile_iterate_end;
 
   if (worked.ptile == NULL
@@ -336,10 +382,17 @@
     selected = &worked;
   }
 
+  if (limit == TWTL_BUILDABLE_UNITS) {
+    unit_list_iterate(units, punit) {
+      unit_virtual_destroy(punit);
+    } unit_list_iterate_end;
+    unit_list_destroy(units);
+  }
+
   if (selected->ptile != NULL) {
     struct extra_type *target = NULL;
 
-    if (selected->tgt == NULL) {      
+    if (selected->tgt == NULL) {
       enum extra_cause cause = activity_to_extra_cause(selected->act);
 
       if (cause != EC_NONE) {

Modified: trunk/ai/threaded/taicity.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/threaded/taicity.h?rev=34769&r1=34768&r2=34769&view=diff
==============================================================================
--- trunk/ai/threaded/taicity.h (original)
+++ trunk/ai/threaded/taicity.h Mon Jan  2 00:20:46 2017
@@ -16,7 +16,8 @@
 struct city;
 struct tai_req;
 
-void tai_city_worker_requests_create(struct player *pplayer, struct city 
*pcity);
+void tai_city_worker_requests_create(struct ai_type *ait,
+                                     struct player *pplayer, struct city 
*pcity);
 void tai_req_worker_task_rcv(struct tai_req *req);
 
 #endif /* FC__TAICITY_H */

Modified: trunk/ai/threaded/taiplayer.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/threaded/taiplayer.c?rev=34769&r1=34768&r2=34769&view=diff
==============================================================================
--- trunk/ai/threaded/taiplayer.c       (original)
+++ trunk/ai/threaded/taiplayer.c       Mon Jan  2 00:20:46 2017
@@ -46,7 +46,7 @@
   TAI_ABORT_NONE
 };
 
-static enum tai_abort_msg_class tai_check_messages(void);
+static enum tai_abort_msg_class tai_check_messages(struct ai_type *ait);
 
 struct tai_thr
 {
@@ -73,6 +73,7 @@
 static void tai_thread_start(void *arg)
 {
   bool finished = FALSE;
+  struct ai_type *ait = arg;
 
   log_debug("New AI thread launched");
 
@@ -81,7 +82,7 @@
   while (!finished) {
     fc_thread_cond_wait(&thrai.msgs_to.thr_cond, &thrai.msgs_to.mutex);
 
-    if (tai_check_messages() <= TAI_ABORT_EXIT) {
+    if (tai_check_messages(ait) <= TAI_ABORT_EXIT) {
       finished = TRUE;
     }
   }
@@ -93,7 +94,7 @@
 /**************************************************************************
   Handle messages from message queue.
 **************************************************************************/
-static enum tai_abort_msg_class tai_check_messages(void)
+static enum tai_abort_msg_class tai_check_messages(struct ai_type *ait)
 {
   enum tai_abort_msg_class ret_abort= TAI_ABORT_NONE;
 
@@ -117,14 +118,14 @@
       /* Use _safe iterate in case the main thread
        * destroyes cities while we are iterating through these. */
       city_list_iterate_safe(msg->plr->cities, pcity) {
-        tai_city_worker_requests_create(msg->plr, pcity);
+        tai_city_worker_requests_create(ait, msg->plr, pcity);
 
         /* Release mutex for a second in case main thread
          * wants to do something to city list. */
         fc_release_mutex(&game.server.mutexes.city_list);
 
         /* Recursive message check in case phase is finished. */
-        new_abort = tai_check_messages();
+        new_abort = tai_check_messages(ait);
         fc_allocate_mutex(&game.server.mutexes.city_list);
         if (new_abort < TAI_ABORT_NONE) {
           break;
@@ -206,7 +207,7 @@
  
     fc_thread_cond_init(&thrai.msgs_to.thr_cond);
     fc_init_mutex(&thrai.msgs_to.mutex);
-    fc_thread_start(&thrai.ait, tai_thread_start, NULL);
+    fc_thread_start(&thrai.ait, tai_thread_start, ait);
   }
 }
 


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

Reply via email to