[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 <=
|
|