[Freeciv-Dev] (PR#9908) Make AI understand channels
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] (PR#9908) Make AI understand channels |
From: |
"Per I. Mathisen" <per@xxxxxxxxxxx> |
Date: |
Thu, 2 Sep 2004 07:41:32 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9908 >
On Sat, 21 Aug 2004, Gregory Berkolaiko wrote:
> On Mon, 16 Aug 2004, Per Inge Mathisen wrote:
> > I thought about adding ocean check to goto_is_sane(), but problem is we
> > might have a canal in a city. So I thought about making an aidata matrix
> > of canals that exist, but then I wondered if that was really worth the
> > trouble...
>
> Yes, it is worth the trouble, I need it for ferry building, so someone has
> to do it.
Done. Patch attached.
- Per
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.36
diff -u -r1.36 aidata.c
--- ai/aidata.c 30 Aug 2004 21:20:33 -0000 1.36
+++ ai/aidata.c 2 Sep 2004 14:39:12 -0000
@@ -143,6 +143,35 @@
/* 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->x, pcity->y, x2, y2) {
+ struct tile *ptile = map_get_tile(x2, y2);
+
+ if (is_ocean(ptile->terrain)) {
+ adjc_iterate(pcity->x, pcity->y, x3, y3) {
+ struct tile *ptile2 = map_get_tile(x3, y3);
+
+ if (is_ocean(ptile2->terrain)
+ && ptile->continent != ptile2->continent) {
+ ai->channels[(-ptile->continent) * ai->num_oceans
+ + (-ptile2->continent)] = TRUE;
+ ai->channels[(-ptile2->continent) * ai->num_oceans
+ + (-ptile->continent)] = TRUE;
+ }
+ } adjc_iterate_end;
+ }
+ } adjc_iterate_end;
+ } city_list_iterate_end;
+ }
+ } players_iterate_end;
+
/*** Exploration ***/
ai->explore.land_done = TRUE;
@@ -326,6 +355,7 @@
free(ai->threats.continent); ai->threats.continent = NULL;
free(ai->stats.workers); ai->stats.workers = NULL;
free(ai->stats.cities); ai->stats.cities = NULL;
+ free(ai->channels); ai->channels = NULL;
}
/**************************************************************************
@@ -354,6 +384,7 @@
ai->govt_reeval = 0;
ai->government_want = fc_calloc(game.government_count + 1, sizeof(int));
+ ai->channels = NULL;
ai->diplomacy.target = NULL;
ai->diplomacy.strategy = WIN_OPEN;
@@ -387,3 +418,13 @@
free(ai->government_want);
}
+
+/**************************************************************************
+ Is there a channel going from ocean c1 to ocean c2?
+**************************************************************************/
+bool ai_channel(struct player *pplayer, Continent_id c1, Continent_id c2)
+{
+ struct ai_data *ai = ai_data_get(pplayer);
+
+ return (c1 == c2 || ai->channels[ai->num_oceans * c1 + c2]);
+}
Index: ai/aidata.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.h,v
retrieving revision 1.15
diff -u -r1.15 aidata.h
--- ai/aidata.h 29 Aug 2004 19:43:37 -0000 1.15
+++ ai/aidata.h 2 Sep 2004 14:39:12 -0000
@@ -86,6 +86,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 {
@@ -136,5 +139,6 @@
struct ai_data *ai_data_get(struct player *pplayer);
+bool ai_channel(struct player *pplayer, Continent_id c1, Continent_id c2);
#endif
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.181
diff -u -r1.181 gotohand.c
--- server/gotohand.c 9 Aug 2004 05:24:35 -0000 1.181
+++ server/gotohand.c 2 Sep 2004 14:39:13 -0000
@@ -33,6 +33,7 @@
#include "unithand.h"
#include "unittools.h"
+#include "aidata.h"
#include "aitools.h"
#include "gotohand.h"
@@ -1231,6 +1232,9 @@
bool goto_is_sane(struct unit *punit, int x, int y, bool omni)
{
struct player *pplayer = unit_owner(punit);
+ struct city *pcity = map_get_city(x, y);
+ Continent_id my_continent = map_get_continent(punit->x, punit->y);
+ Continent_id xy_continent = map_get_continent(x, y);
if (same_pos(punit->x, punit->y, x, y)) {
return TRUE;
@@ -1249,37 +1253,39 @@
* and with a boat */
if (ground_unit_transporter_capacity(x, y, pplayer) > 0) {
adjc_iterate(x, y, tmp_x, tmp_y) {
- if (map_get_continent(tmp_x, tmp_y) ==
- map_get_continent(punit->x, punit->y))
+ if (map_get_continent(tmp_x, tmp_y) == my_continent) {
/* The target is adjacent to our continent! */
return TRUE;
+ }
} adjc_iterate_end;
}
} else {
/* Going to a land tile: better be our continent */
- if (map_get_continent(punit->x, punit->y) == map_get_continent(x, y)) {
+ if (my_continent == xy_continent) {
return TRUE;
} else {
/* Well, it's not our continent, but maybe we are on a boat
* adjacent to the target continent? */
adjc_iterate(punit->x, punit->y, tmp_x, tmp_y) {
- if (map_get_continent(tmp_x, tmp_y) == map_get_continent(x, y)) {
+ if (map_get_continent(tmp_x, tmp_y) == xy_continent) {
return TRUE;
}
} adjc_iterate_end;
}
- }
-
+ }
return FALSE;
case SEA_MOVING:
- if (is_ocean(map_get_terrain(x, y))
- || is_ocean_near_tile(x, y)) {
- /* The target is sea or is accessible from sea
- * (allow for bombardment and visiting ports) */
- return TRUE;
+ if (is_ocean(map_get_terrain(x, y))) {
+ if (ai_channel(pplayer, xy_continent, my_continent)) {
+ return TRUE; /* Ocean -> Ocean travel ok. */
+ }
+ } else if (is_ocean_near_tile(x, y)
+ && ((pcity && pplayers_allied(city_owner(pcity), pplayer))
+ || !unit_flag(punit, F_NO_LAND_ATTACK))) {
+ return TRUE; /* Not ocean, but allied city or bombardment, so ok. */
}
- return FALSE;
+ return FALSE; /* Not ok. */
default:
return TRUE;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#9908) Make AI understand channels,
Per I. Mathisen <=
|
|