Complete.Org: Mailing Lists: Archives: freeciv-ai: August 2005:
[freeciv-ai] (PR#9908) Updated AI channels patch
Home

[freeciv-ai] (PR#9908) Updated AI channels patch

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [freeciv-ai] (PR#9908) Updated AI channels patch
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Mon, 22 Aug 2005 15:04:42 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=9908 >

CHANGES:
 - /debug ferries will output channels information during the game
 - updated to most recent cvs

Unless there are any objections, this will go in soon...

  - Per

Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.76
diff -u -r1.76 aidata.c
--- ai/aidata.c 4 Aug 2005 16:26:11 -0000       1.76
+++ ai/aidata.c 22 Aug 2005 21:55:13 -0000
@@ -224,7 +224,8 @@
 void ai_data_phase_init(struct player *pplayer, bool is_new_phase)
 {
   struct ai_data *ai = &aidata[pplayer->player_no];
-  int i, nuke_units = num_role_units(F_NUCLEAR);
+  int i, j, k;
+  int nuke_units = num_role_units(F_NUCLEAR);
   bool danger_of_nukes = FALSE;
 
   /*** Threats ***/
@@ -316,6 +317,53 @@
   /* Increase from fear to terror if opponent actually has nukes */
   if (danger_of_nukes) ai->threats.nuclear++; /* sum of both fears */
 
+  /*** Channels ***/
+
+  /* Ways to cross from one ocean to another through a city. */
+  ai->channels = fc_calloc((ai->num_oceans + 1) * (ai->num_oceans + 1), 
sizeof(int));
+  players_iterate(aplayer) {
+    if (pplayers_allied(pplayer, aplayer)) {
+      city_list_iterate(aplayer->cities, pcity) {
+        adjc_iterate(pcity->tile, tile1) {
+          if (is_ocean(tile1->terrain)) {
+            adjc_iterate(pcity->tile, tile2) {
+              if (is_ocean(tile2->terrain) 
+                  && tile_get_continent(tile1) != tile_get_continent(tile2)) {
+                ai->channels[(-tile1->continent) * ai->num_oceans
+                             + (-tile2->continent)] = TRUE;
+                ai->channels[(-tile2->continent) * ai->num_oceans
+                             + (-tile1->continent)] = TRUE;
+              }
+            } adjc_iterate_end;
+          }
+        } adjc_iterate_end;
+      } city_list_iterate_end;
+    }
+  } players_iterate_end;
+
+  /* If we can go i -> j and j -> k, we can also go i -> k. */
+  for(i = 1; i <= ai->num_oceans; i++) {
+    for(j = 1; j <= ai->num_oceans; j++) {
+      if (ai->channels[i * ai->num_oceans + j]) {
+        for(k = 1; k <= ai->num_oceans; k++) {
+          ai->channels[i * ai->num_oceans + k] |= 
+            ai->channels[j * ai->num_oceans + k];
+        }
+      }
+    }
+  }
+
+  if (game.debug[DEBUG_FERRIES]) {
+    for(i = 1; i <= ai->num_oceans; i++) {
+      for(j = 1; j <= ai->num_oceans; j++) {
+        if (ai->channels[i * ai->num_oceans + j]) {
+          freelog(LOG_NORMAL, "%s: oceans %d and %d are connected",
+                  pplayer->name, i, j);
+       }
+      }
+    }
+  }
+
   /*** Exploration ***/
 
   ai->explore.land_done = TRUE;
@@ -539,6 +587,9 @@
 
   free(ai->stats.cities);
   ai->stats.cities = NULL;
+
+  free(ai->channels);
+  ai->channels = NULL;
 }
 
 /**************************************************************************
@@ -572,6 +623,7 @@
   memset(ai->government_want, 0,
         (game.control.government_count + 1) * sizeof(*ai->government_want));
 
+  ai->channels = NULL;
   ai->wonder_city = 0;
   ai->diplomacy.strategy = WIN_OPEN;
   ai->diplomacy.timer = 0;
@@ -596,3 +648,17 @@
   ai->wants_no_science = FALSE;
   ai->max_num_cities = 10000;
 }
+
+/**************************************************************************
+  Is there a channel going from ocean c1 to ocean c2?
+  Returns FALSE if either is not an ocean.
+**************************************************************************/
+bool ai_channel(struct player *pplayer, Continent_id c1, Continent_id c2)
+{
+  struct ai_data *ai = ai_data_get(pplayer);
+
+  if (c1 >= 0 || c2 >= 0) {
+    return FALSE;
+  }
+  return (c1 == c2 || ai->channels[(-c1) * ai->num_oceans + (-c2)]);
+}
Index: ai/aidata.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.h,v
retrieving revision 1.34
diff -u -r1.34 aidata.h
--- ai/aidata.h 18 Aug 2005 06:44:26 -0000      1.34
+++ ai/aidata.h 22 Aug 2005 21:55:14 -0000
@@ -102,6 +102,9 @@
     bool sea_done;    /* nothing more to explore at sea */
   } explore;
 
+  /* Keep track of available ocean channels */
+  bool *channels;
+
   /* This struct is used for statistical unit building, eg to ensure
    * that we don't build too few or too many units of a given type. */
   struct {
@@ -169,4 +172,6 @@
 
 struct ai_data *ai_data_get(struct player *pplayer);
 
+bool ai_channel(struct player *pplayer, Continent_id c1, Continent_id c2);
+
 #endif
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.236
diff -u -r1.236 game.c
--- common/game.c       18 Aug 2005 06:44:27 -0000      1.236
+++ common/game.c       22 Aug 2005 21:55:26 -0000
@@ -285,7 +285,10 @@
   teams_init();
   idex_init();
   cm_init();
-  
+
+  for (i = 0; i < DEBUG_LAST; i++) {
+    game.debug[i] = FALSE;
+  }
   for(i=0; i<MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++)
     player_init(&game.players[i]);
   for (i=0; i<A_LAST; i++)      /* game.num_tech_types = 0 here */
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.198
diff -u -r1.198 game.h
--- common/game.h       18 Aug 2005 06:44:28 -0000      1.198
+++ common/game.h       22 Aug 2005 21:55:26 -0000
@@ -29,6 +29,11 @@
 #include "packets.h"
 #include "specialist.h"
 
+enum debug_globals {
+  DEBUG_FERRIES,
+  DEBUG_LAST
+};
+
 enum server_states { 
   PRE_GAME_STATE, 
   UNUSED_STATE, /* Have to keep this around for savegame compatibility. */
@@ -55,6 +60,7 @@
   struct government *government_when_anarchy;
 
   struct packet_ruleset_control control;
+  bool debug[DEBUG_LAST];
   int version;
   char id[MAX_ID_LEN];         /* server only */
   int timeoutint;     /* increase timeout every N turns... */
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.196
diff -u -r1.196 gotohand.c
--- server/gotohand.c   22 Jul 2005 16:18:06 -0000      1.196
+++ server/gotohand.c   22 Aug 2005 21:55:54 -0000
@@ -34,6 +34,7 @@
 #include "unithand.h"
 #include "unittools.h"
 
+#include "aidata.h"
 #include "aitools.h"
 
 #include "gotohand.h"
@@ -1234,6 +1235,9 @@
 bool goto_is_sane(struct unit *punit, struct tile *ptile, bool omni)
 {  
   struct player *pplayer = unit_owner(punit);
+  struct city *pcity = tile_get_city(ptile);
+  Continent_id my_cont = tile_get_continent(punit->tile);
+  Continent_id target_cont = tile_get_continent(ptile);
 
   if (same_pos(punit->tile, ptile)) {
     return TRUE;
@@ -1252,20 +1256,21 @@
        * and with a boat */
       if (ground_unit_transporter_capacity(ptile, pplayer) > 0) {
         adjc_iterate(ptile, tmp_tile) {
-          if (tile_get_continent(tmp_tile) == tile_get_continent(punit->tile))
+          if (tile_get_continent(tmp_tile) == my_cont) {
             /* The target is adjacent to our continent! */
             return TRUE;
+          }
         } adjc_iterate_end;
       }
     } else {
       /* Going to a land tile: better be our continent */
-      if (tile_get_continent(punit->tile) == tile_get_continent(ptile)) {
+      if (my_cont == target_cont) {
         return TRUE;
       } else {
         /* Well, it's not our continent, but maybe we are on a boat
          * adjacent to the target continent? */
        adjc_iterate(punit->tile, tmp_tile) {
-         if (tile_get_continent(tmp_tile) == tile_get_continent(ptile)) {
+         if (tile_get_continent(tmp_tile) == target_cont) {
            return TRUE;
           }
        } adjc_iterate_end;
@@ -1275,13 +1280,33 @@
     return FALSE;
 
   case SEA_MOVING:
-    if (is_ocean(tile_get_terrain(ptile))
-        || is_ocean_near_tile(ptile)) {
-      /* The target is sea or is accessible from sea 
-       * (allow for bombardment and visiting ports) */
-      return TRUE;
+    if (!is_ocean(tile_get_terrain(punit->tile))) {
+      /* Oops, we are not in the open waters.  What ocean do we have
+       * access to?  We can assume we are in a city and any oceans adjacent
+       * are connected. */
+      adjc_iterate(punit->tile, tmp_tile) {
+        if (is_ocean(tile_get_terrain(tmp_tile))) {
+          my_cont = tile_get_continent(tmp_tile);
+          break;
+        }
+      } adjc_iterate_end;
     }
-    return FALSE;
+    if (is_ocean(tile_get_terrain(ptile))) {
+      if (ai_channel(pplayer, target_cont, my_cont)) {
+        return TRUE; /* Ocean -> Ocean travel ok. */
+      }
+    } else if ((pcity && pplayers_allied(city_owner(pcity), pplayer))
+               || !unit_flag(punit, F_NO_LAND_ATTACK)) {
+      /* Not ocean, but allied city or can bombard, checking if there is
+       * good ocean adjacent */
+      adjc_iterate(ptile, tmp_tile) {
+        if (is_ocean(tile_get_terrain(tmp_tile))
+            && ai_channel(pplayer, my_cont, tile_get_continent(tmp_tile))) {
+          return TRUE;
+        }
+      } adjc_iterate_end;
+    }
+    return FALSE; /* Not ok. */
 
   default:
     return TRUE;
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.431
diff -u -r1.431 stdinhand.c
--- server/stdinhand.c  18 Aug 2005 06:53:31 -0000      1.431
+++ server/stdinhand.c  22 Aug 2005 21:56:07 -0000
@@ -2179,7 +2179,7 @@
 }
 
 /******************************************************************
-  ...
+  Turn on selective debugging.
 ******************************************************************/
 static bool debug_command(struct connection *caller, char *str, 
                           bool check)
@@ -2327,6 +2327,15 @@
     } unit_list_iterate_end;
   } else if (strcmp(arg[0], "timing") == 0) {
     TIMING_RESULTS();
+  } else if (strcmp(arg[0], "ferries") == 0) {
+    if (game.debug[DEBUG_FERRIES]) {
+      game.debug[DEBUG_FERRIES] = FALSE;
+      cmd_reply(CMD_DEBUG, caller, C_OK, _("Ferry system is no longer "
+                "in debug mode."));
+    } else {
+      game.debug[DEBUG_FERRIES] = TRUE;
+      cmd_reply(CMD_DEBUG, caller, C_OK, _("Ferry system in debug mode."));
+    }
   } else if (strcmp(arg[0], "unit") == 0) {
     int id;
     struct unit *punit;

[Prev in Thread] Current Thread [Next in Thread]
  • [freeciv-ai] (PR#9908) Updated AI channels patch, Per I. Mathisen <=