Freeciv-3.3: /fast/freeciv/nightly/main/common/ai.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
ai.c
Go to the documentation of this file.
1/****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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)
6 any later version.
7
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****************************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <string.h>
19
20/* utility */
21#include "fcintl.h"
22#include "log.h" /* fc_assert */
23#include "mem.h"
24#include "timing.h"
25
26/* common */
27#include "player.h"
28
29#include "ai.h"
30
31 static struct ai_type ai_types[FREECIV_AI_MOD_LAST];
32
33 static int ai_type_count = 0;
34
35#ifdef DEBUG_AITIMERS
36struct ai_timer {
37 int count;
38 struct timer *timer;
39};
40
41static struct ai_timer *ai_timer_get(const struct ai_type *ai);
42static struct ai_timer *ai_timer_player_get(const struct player *pplayer);
43
44static struct ai_timer *aitimers = NULL;
45static struct ai_timer *aitimer_plrs = NULL;
46
47/*************************************************************************/
50void ai_timer_init(void)
51{
52 int i;
53
54 fc_assert_ret(aitimers == NULL);
55 fc_assert_ret(aitimer_plrs == NULL);
56
57 aitimers = fc_calloc(FREECIV_AI_MOD_LAST, sizeof(*aitimers));
58 for (i = 0; i < FREECIV_AI_MOD_LAST; i++) {
59 struct ai_timer *aitimer = aitimers + i;
60
61 aitimer->count = 0;
62 aitimer->timer = NULL;
63 }
64
65 aitimer_plrs = fc_calloc(FREECIV_AI_MOD_LAST * MAX_NUM_PLAYER_SLOTS,
66 sizeof(*aitimer_plrs));
67 for (i = 0; i < FREECIV_AI_MOD_LAST * MAX_NUM_PLAYER_SLOTS; i++) {
68 struct ai_timer *aitimer = aitimer_plrs + i;
69
70 aitimer->count = 0;
71 aitimer->timer = NULL;
72 }
73}
74
75/*************************************************************************/
78void ai_timer_free(void)
79{
80 int i,j;
81 struct ai_timer *aitimer;
82
83 for (i = 0; i < FREECIV_AI_MOD_LAST; i++) {
84 struct ai_type *ai = get_ai_type(i);
85
86 aitimer = aitimers + i;
87
88 if (aitimer->timer) {
89 log_normal("AI timer stats: [%15.3f] ---- (AI type: %s)",
90 timer_read_seconds(aitimer->timer), ai_name(ai));
91 timer_destroy(aitimer->timer);
92 }
93
94 for (j = 0; j < MAX_NUM_PLAYER_SLOTS; j++) {
95 aitimer = aitimer_plrs + j * FREECIV_AI_MOD_LAST + i;
96
97 if (aitimer->timer) {
98 log_normal("AI timer stats: [%15.3f] P%03d (AI type: %s)",
99 timer_read_seconds(aitimer->timer), j, ai_name(ai));
100 timer_destroy(aitimer->timer);
101 }
102 }
103 }
104 free(aitimers);
105 aitimers = NULL;
106
107 free(aitimer_plrs);
108 aitimer_plrs = NULL;
109}
110
111/*************************************************************************/
114static struct ai_timer *ai_timer_get(const struct ai_type *ai)
115{
116 struct ai_timer *aitimer;
117
118 fc_assert_ret_val(ai != NULL, NULL);
119 fc_assert_ret_val(aitimers != NULL, NULL);
120
121 aitimer = aitimers + ai_type_number(ai);
122
123 if (!aitimer->timer) {
124 char buf[512];
125
126 fc_snprintf(buf, sizeof(buf), "AI type timer %s", ai_type_name(ai));
127 aitimer->timer = timer_new(TIMER_CPU, TIMER_DEBUG, buf);
128 }
129
130 return aitimer;
131}
132
133/*************************************************************************/
136static struct ai_timer *ai_timer_player_get(const struct player *pplayer)
137{
138 struct ai_timer *aitimer;
139
140 fc_assert_ret_val(pplayer != NULL, NULL);
141 fc_assert_ret_val(pplayer->ai != NULL, NULL);
142 fc_assert_ret_val(aitimer_plrs != NULL, NULL);
143
144 aitimer = aitimer_plrs + (player_index(pplayer) * FREECIV_AI_MOD_LAST
145 + ai_type_number(pplayer->ai));
146
147 if (!aitimer->timer) {
148 char buf[512];
149
150 fc_snprintf(buf, sizeof(buf), "AI plr timer for %s", pplayer_name(pplayer));
151 aitimer->timer = timer_new(TIMER_CPU, TIMER_DEBUG, buf);
152 }
153
154 return aitimer;
155}
156
157/*************************************************************************/
160void ai_timer_start(const struct ai_type *ai)
161{
162 struct ai_timer *aitimer = ai_timer_get(ai);
163
164 fc_assert_ret(aitimer != NULL);
165 fc_assert_ret(aitimer->timer != NULL);
166
167 if (aitimer->count == 0) {
168 log_debug("AI timer start [%15.3f] ---- (AI type: %s)",
169 timer_read_seconds(aitimer->timer), ai_name(ai));
170 timer_start(aitimer->timer);
171 } else {
172 log_debug("AI timer =====> [depth: %3d] ---- (AI type: %s)",
173 aitimer->count, ai_name(ai));
174 }
175 aitimer->count++;
176}
177
178/*************************************************************************/
181void ai_timer_stop(const struct ai_type *ai)
182{
183 struct ai_timer *aitimer = ai_timer_get(ai);
184
185 fc_assert_ret(aitimer != NULL);
186 fc_assert_ret(aitimer->timer != NULL);
187
188 if (aitimer->count > 0) {
189 if (aitimer->count == 1) {
190 timer_stop(aitimer->timer);
191 log_debug("AI timer stop [%15.3f] ---- (AI type: %s)",
192 timer_read_seconds(aitimer->timer), ai_name(ai));
193 } else {
194 log_debug("AI timer =====> [depth: %3d] ---- (AI type: %s)",
195 aitimer->count, ai_name(ai));
196 }
197 aitimer->count--;
198 } else {
199 log_debug("AI timer missing? ---- (AI type: %s)",
200 ai_name(ai));
201 }
202}
203
204/*************************************************************************/
207void ai_timer_player_start(const struct player *pplayer)
208{
209 struct ai_timer *aitimer = ai_timer_player_get(pplayer);
210
211 fc_assert_ret(aitimer != NULL);
212 fc_assert_ret(aitimer->timer != NULL);
213
214 if (aitimer->count == 0) {
215 log_debug("AI timer start [%15.3f] P%03d (AI type: %s) %s",
216 timer_read_seconds(aitimer->timer), player_index(pplayer),
217 ai_name(pplayer->ai), player_name(pplayer));
218 timer_start(aitimer->timer);
219 } else {
220 log_debug("AI timer =====> [depth: %3d] P%03d (AI type: %s) %s",
221 aitimer->count, player_index(pplayer), ai_name(pplayer->ai),
222 player_name(pplayer));
223 }
224 aitimer->count++;
225}
226
227/*************************************************************************/
230void ai_timer_player_stop(const struct player *pplayer)
231{
232 struct ai_timer *aitimer = ai_timer_player_get(pplayer);
233
234 fc_assert_ret(aitimer != NULL);
235 fc_assert_ret(aitimer->timer != NULL);
236
237 if (aitimer->count > 0) {
238 if (aitimer->count == 1) {
239 timer_stop(aitimer->timer);
240 log_debug("AI timer stop [%15.3f] P%03d (AI type: %s) %s",
241 timer_read_seconds(aitimer->timer), player_index(pplayer),
242 ai_name(pplayer->ai), player_name(pplayer));
243 } else {
244 log_debug("AI timer =====> [depth: %3d] P%03d (AI type: %s) %s",
245 aitimer->count, player_index(pplayer), ai_name(pplayer->ai),
246 player_name(pplayer));
247 }
248 aitimer->count--;
249 } else {
250 log_debug("AI timer missing? P%03d (AI type: %s) %s",
251 player_index(pplayer), ai_name(pplayer->ai),
252 player_name(pplayer));
253 }
254}
255#endif /* DEBUG_AITIMERS */
256
257/*************************************************************************/
260 struct ai_type *get_ai_type(int id)
261{
262 fc_assert(id >= 0 && id < FREECIV_AI_MOD_LAST);
263
264 return &ai_types[id];
265}
266
267/*************************************************************************/
270 void init_ai(struct ai_type *ai)
271{
272 memset(ai, 0, sizeof(*ai));
273}
274
275/*************************************************************************/
278 int ai_type_number(const struct ai_type *ai)
279{
280 int ainbr = ai - ai_types;
281
282 fc_assert_ret_val(ainbr >= 0 && ainbr < FREECIV_AI_MOD_LAST, 0);
283
284 return ainbr;
285}
286
287/*************************************************************************/
290 struct ai_type *ai_type_by_name(const char *search)
291{
292 ai_type_iterate(ai) {
293 if (!fc_strcasecmp(ai_name(ai), search)) {
294 return ai;
295 }
296 } ai_type_iterate_end;
297
298 return NULL;
299}
300
301/*************************************************************************/
304 struct ai_type *ai_type_alloc(void)
305{
306 if (ai_type_count >= FREECIV_AI_MOD_LAST) {
307 log_error(_("Too many AI modules. Max is %d."),
308 FREECIV_AI_MOD_LAST);
309
310 return NULL;
311 }
312
313 return get_ai_type(ai_type_count++);
314}
315
316/*************************************************************************/
319 void ai_type_dealloc(void)
320{
321 ai_type_count--;
322}
323
324/*************************************************************************/
327 int ai_type_get_count(void)
328{
329 return ai_type_count;
330}
331
332/*************************************************************************/
335 const char *ai_name(const struct ai_type *ai)
336{
337 fc_assert_ret_val(ai, NULL);
338 return ai->name;
339}
340
341/*************************************************************************/
346 const char *ai_type_name_or_fallback(const char *orig_name)
347{
348 if (orig_name == NULL) {
349 return NULL;
350 }
351
352 if (ai_type_by_name(orig_name) != NULL) {
353 return orig_name;
354 }
355
356 if (!strcmp("tex", orig_name)
357 || !strcmp("threaded", orig_name)) {
358 struct ai_type *fb;
359
360 fb = ai_type_by_name("classic");
361
362 if (fb != NULL) {
363 /* Get pointer to persistent name of the ai_type */
364 return ai_name(fb);
365 }
366 }
367
368 return NULL;
369}
370
371/*************************************************************************/
374 const char *ai_level_name_update_cb(const char *old)
375{
376#ifndef FREECIV_DEBUG
377 /* No experimental level in !FREECIV_DEBUG build */
378 if (!fc_strcasecmp("Experimental", old)) {
379 /* Convert it to hard */
380 return ai_level_name(AI_LEVEL_HARD);
381 }
382#endif /* FREECIV_DEBUG */
383
384 return old;
385}
ai_level_name_update_cb
const char * ai_level_name_update_cb(const char *old)
Definition ai.c:374
init_ai
void init_ai(struct ai_type *ai)
Definition ai.c:270
ai_type_count
static int ai_type_count
Definition ai.c:33
ai_name
const char * ai_name(const struct ai_type *ai)
Definition ai.c:335
ai_type_alloc
struct ai_type * ai_type_alloc(void)
Definition ai.c:304
ai_type_name_or_fallback
const char * ai_type_name_or_fallback(const char *orig_name)
Definition ai.c:346
ai_type_by_name
struct ai_type * ai_type_by_name(const char *search)
Definition ai.c:290
ai_type_get_count
int ai_type_get_count(void)
Definition ai.c:327
ai_type_dealloc
void ai_type_dealloc(void)
Definition ai.c:319
get_ai_type
struct ai_type * get_ai_type(int id)
Definition ai.c:260
ai_types
static struct ai_type ai_types[FREECIV_AI_MOD_LAST]
Definition ai.c:31
ai_type_number
int ai_type_number(const struct ai_type *ai)
Definition ai.c:278
ai.h
ai_timer_start
#define ai_timer_start(...)
Definition ai.h:359
ai_timer_stop
#define ai_timer_stop(...)
Definition ai.h:360
ai_timer_free
#define ai_timer_free(...)
Definition ai.h:358
ai_timer_player_start
#define ai_timer_player_start(...)
Definition ai.h:361
ai_timer_init
#define ai_timer_init(...)
Definition ai.h:357
ai_timer_player_stop
#define ai_timer_player_stop(...)
Definition ai.h:362
ai_type_iterate_end
#define ai_type_iterate_end
Definition ai.h:372
ai_type_iterate
#define ai_type_iterate(NAME_ai)
Definition ai.h:365
incite_cost
char * incite_cost
Definition comments.c:74
id
int int id
Definition editgui_g.h:28
MAX_NUM_PLAYER_SLOTS
#define MAX_NUM_PLAYER_SLOTS
Definition fc_types.h:32
fcintl.h
_
#define _(String)
Definition fcintl.h:67
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
log_normal
#define log_normal(message,...)
Definition log.h:107
log_error
#define log_error(message,...)
Definition log.h:103
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:895
player_index
int player_index(const struct player *pplayer)
Definition player.c:829
player.h
aitimer
static struct timer * aitimer[AIT_LAST][2]
Definition srv_log.c:44
ai_timer
ai_timer
Definition srv_log.h:40
ai_type
Definition ai.h:50
ai_type::name
char name[MAX_LEN_NAME]
Definition ai.h:51
player
Definition player.h:249
player::ai
const struct ai_type * ai
Definition player.h:289
timer
Definition timing.c:81
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
timer_destroy
void timer_destroy(struct timer *t)
Definition timing.c:208
timer_start
void timer_start(struct timer *t)
Definition timing.c:264
timer_stop
void timer_stop(struct timer *t)
Definition timing.c:308
timer_new
struct timer * timer_new(enum timer_timetype type, enum timer_use use, const char *name)
Definition timing.c:160
timer_read_seconds
double timer_read_seconds(struct timer *t)
Definition timing.c:384
timing.h
TIMER_DEBUG
#define TIMER_DEBUG
Definition timing.h:61
TIMER_CPU
@ TIMER_CPU
Definition timing.h:41