1
/**********************************************************************
2
Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; either version 2, or (at your option)
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
12
***********************************************************************/
42
#include "defaultai.h"
46
static struct timer *aitimer[AIT_LAST][2];
47
static int recursion[AIT_LAST];
49
/* General AI logging functions */
51
/**************************************************************************
52
Log player tech messages.
53
**************************************************************************/
54
void real_tech_log(const char *file, const char *function, int line,
55
enum log_level level, bool notify,
56
const struct player *pplayer, struct advance *padvance,
63
if (!valid_advance(padvance) || advance_by_number(A_NONE) == padvance) {
67
fc_snprintf(buffer, sizeof(buffer), "%s::%s (want %d, dist %d) ",
69
advance_name_by_player(pplayer, advance_number(padvance)),
70
pplayer->ai_common.tech_want[advance_index(padvance)],
71
num_unknown_techs_for_goal(pplayer, advance_number(padvance)));
74
fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
77
cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
79
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
81
do_log(file, function, line, FALSE, level, "%s", buffer);
84
/**************************************************************************
85
Log player messages, they will appear like this
87
where ti is timer, co countdown and lo love for target, who is e.
88
**************************************************************************/
89
void real_diplo_log(const char *file, const char *function, int line,
90
enum log_level level, bool notify,
91
const struct player *pplayer,
92
const struct player *aplayer, const char *msg, ...)
97
const struct ai_dip_intel *adip;
99
/* Don't use ai_data_get since it can have side effects. */
100
adip = ai_diplomacy_get(pplayer, aplayer);
102
fc_snprintf(buffer, sizeof(buffer), "%s->%s(l%d,c%d,d%d%s): ",
103
player_name(pplayer),
104
player_name(aplayer),
105
pplayer->ai_common.love[player_index(aplayer)],
108
adip->is_allied_with_enemy ? "?" :
109
(adip->at_war_with_ally ? "!" : ""));
112
fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
115
cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
117
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
119
do_log(file, function, line, FALSE, level, "%s", buffer);
122
/**************************************************************************
123
Log city messages, they will appear like this
124
2: Polish Romenna(5,35) [s1 d106 u11 g1] must have Archers ...
125
**************************************************************************/
126
void real_city_log(const char *file, const char *function, int line,
127
enum log_level level, bool notify,
128
const struct city *pcity, const char *msg, ...)
133
struct ai_city *city_data = def_ai_city_data(pcity);
135
fc_snprintf(buffer, sizeof(buffer), "%s %s(%d,%d) [s%d d%d u%d g%d] ",
136
nation_rule_name(nation_of_city(pcity)),
138
TILE_XY(pcity->tile), pcity->size,
139
city_data->danger, city_data->urgency,
140
city_data->grave_danger);
143
fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
146
cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
148
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
150
do_log(file, function, line, FALSE, level, "%s", buffer);
153
/**************************************************************************
154
Log unit messages, they will appear like this
155
2: Polish Archers[139] (5,35)->(0,0){0,0} stays to defend city
156
where [] is unit id, ()->() are coordinates present and goto, and
157
{,} contains bodyguard and ferryboat ids.
158
**************************************************************************/
159
void real_unit_log(const char *file, const char *function, int line,
160
enum log_level level, bool notify,
161
const struct unit *punit, const char *msg, ...)
167
struct unit_ai *unit_data = def_ai_unit_data(punit);
169
if (punit->goto_tile) {
170
gx = punit->goto_tile->x;
171
gy = punit->goto_tile->y;
176
fc_snprintf(buffer, sizeof(buffer),
177
"%s %s[%d] %s (%d,%d)->(%d,%d){%d,%d} ",
178
nation_rule_name(nation_of_unit(punit)),
179
unit_rule_name(punit),
181
get_activity_text(punit->activity),
182
TILE_XY(punit->tile),
184
unit_data->bodyguard, unit_data->ferryboat);
187
fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
190
cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
192
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
194
do_log(file, function, line, FALSE, level, "%s", buffer);
197
/**************************************************************************
198
Log message for bodyguards. They will appear like this
199
2: Polish Mech. Inf.[485] bodyguard (38,22){Riflemen:574@37,23} was ...
200
note that these messages are likely to wrap if long.
201
**************************************************************************/
202
void real_bodyguard_log(const char *file, const char *function, int line,
203
enum log_level level, bool notify,
204
const struct unit *punit, const char *msg, ...)
209
const struct unit *pcharge;
210
const struct city *pcity;
214
const char *type = "guard";
215
const char *s = "none";
216
struct unit_ai *unit_data = def_ai_unit_data(punit);
218
pcity = game_city_by_number(unit_data->charge);
219
pcharge = game_unit_by_number(unit_data->charge);
221
charge_x = pcharge->tile->x;
222
charge_y = pcharge->tile->y;
225
s = unit_rule_name(pcharge);
227
charge_x = pcity->tile->x;
228
charge_y = pcity->tile->y;
231
s = city_name(pcity);
233
/* else perhaps the charge died */
235
fc_snprintf(buffer, sizeof(buffer),
236
"%s %s[%d] %s (%d,%d){%s:%d@%d,%d} ",
237
nation_rule_name(nation_of_unit(punit)),
238
unit_rule_name(punit),
241
TILE_XY(punit->tile),
242
s, id, charge_x, charge_y);
245
fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
248
cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
250
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
252
do_log(file, function, line, FALSE, level, "%s", buffer);
255
/**************************************************************************
256
Measure the time between the calls. Used to see where in the AI too
257
much CPU is being used.
258
**************************************************************************/
259
void TIMING_LOG(enum ai_timer timer, enum ai_timer_activity activity)
261
static int turn = -1;
265
for (i = 0; i < AIT_LAST; i++) {
266
aitimer[i][0] = new_timer(TIMER_CPU, TIMER_ACTIVE);
267
aitimer[i][1] = new_timer(TIMER_CPU, TIMER_ACTIVE);
272
if (game.info.turn != turn) {
273
turn = game.info.turn;
274
for (i = 0; i < AIT_LAST; i++) {
275
clear_timer(aitimer[i][0]);
277
fc_assert(activity == TIMER_START);
280
if (activity == TIMER_START && recursion[timer] == 0) {
281
start_timer(aitimer[timer][0]);
282
start_timer(aitimer[timer][1]);
284
} else if (activity == TIMER_STOP && recursion[timer] == 1) {
285
stop_timer(aitimer[timer][0]);
286
stop_timer(aitimer[timer][1]);
291
/**************************************************************************
293
**************************************************************************/
294
void TIMING_RESULTS(void)
298
#define AILOG_OUT(text, which) \
299
fc_snprintf(buf, sizeof(buf), " %s: %g sec turn, %g sec game", text, \
300
read_timer_seconds(aitimer[which][0]), \
301
read_timer_seconds(aitimer[which][1])); \
302
log_test("%s", buf); \
303
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buf);
305
log_test(" --- AI timing results ---");
306
notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log,
307
" --- AI timing results ---");
308
AILOG_OUT("Total AI time", AIT_ALL);
309
AILOG_OUT("Movemap", AIT_MOVEMAP);
310
AILOG_OUT("Units", AIT_UNITS);
311
AILOG_OUT(" - Military", AIT_MILITARY);
312
AILOG_OUT(" - Attack", AIT_ATTACK);
313
AILOG_OUT(" - Defense", AIT_DEFENDERS);
314
AILOG_OUT(" - Ferry", AIT_FERRY);
315
AILOG_OUT(" - Rampage", AIT_RAMPAGE);
316
AILOG_OUT(" - Bodyguard", AIT_BODYGUARD);
317
AILOG_OUT(" - Recover", AIT_RECOVER);
318
AILOG_OUT(" - Caravan", AIT_CARAVAN);
319
AILOG_OUT(" - Hunter", AIT_HUNTER);
320
AILOG_OUT(" - Airlift", AIT_AIRLIFT);
321
AILOG_OUT(" - Diplomat", AIT_DIPLOMAT);
322
AILOG_OUT(" - Air", AIT_AIRUNIT);
323
AILOG_OUT(" - Explore", AIT_EXPLORER);
324
AILOG_OUT("fstk", AIT_FSTK);
325
AILOG_OUT("Settlers", AIT_SETTLERS);
326
AILOG_OUT("Workers", AIT_WORKERS);
327
AILOG_OUT("Government", AIT_GOVERNMENT);
328
AILOG_OUT("Taxes", AIT_TAXES);
329
AILOG_OUT("Cities", AIT_CITIES);
330
AILOG_OUT(" - Buildings", AIT_BUILDINGS);
331
AILOG_OUT(" - Danger", AIT_DANGER);
332
AILOG_OUT(" - Worker want", AIT_CITY_TERRAIN);
333
AILOG_OUT(" - Military want", AIT_CITY_MILITARY);
334
AILOG_OUT(" - Settler want", AIT_CITY_SETTLERS);
335
AILOG_OUT("Citizen arrange", AIT_CITIZEN_ARRANGE);
336
AILOG_OUT("Tech", AIT_TECH);