Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/agents/cma_fec.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
cma_fec.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2001 - R. Falke
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/***********************************************************************
15 This is the common file for all front-end (Front End Common) for the
16 citizen management agent (CMA).
17***********************************************************************/
18
19#ifdef HAVE_CONFIG_H
20#include <fc_config.h>
21#endif
22
23#include <string.h>
24
25/* utility */
26#include "fciconv.h"
27#include "fcintl.h"
28#include "log.h"
29#include "mem.h"
30#include "support.h"
31
32/* common */
33#include "game.h"
34#include "specialist.h"
35
36/* client */
37#include "attribute.h"
38
39/* client/agents */
40#include "agents.h"
41
42#include "cma_fec.h"
43
44
45#define RESULT_COLUMNS 10
46#define BUFFER_SIZE 100
47#define MAX_LEN_PRESET_NAME 80
48
49 struct cma_preset {
50 char *descr;
51 struct cm_parameter parameter;
52};
53
54#define SPECLIST_TAG preset
55#define SPECLIST_TYPE struct cma_preset
56#include "speclist.h"
57
58#define preset_list_iterate(presetlist, ppreset) \
59 TYPED_LIST_ITERATE(struct cma_preset, presetlist, ppreset)
60#define preset_list_iterate_end LIST_ITERATE_END
61
62 static struct preset_list *preset_list = NULL;
63
64/**********************************************************************/
68 static void city_remove(int city_id)
69{
70 attr_city_set(ATTR_CITY_CMAFE_PARAMETER, city_id, 0, NULL);
71}
72
73/**********************************************************************/
76 void cmafec_init(void)
77{
78 struct agent self;
79
80 if (preset_list == NULL) {
81 preset_list = preset_list_new();
82 }
83
84 memset(&self, 0, sizeof(self));
85 strcpy(self.name, "CMA");
86 self.level = 1;
87 self.city_callbacks[CB_REMOVE] = city_remove;
88 register_agent(&self);
89}
90
91/**********************************************************************/
94 void cmafec_free(void)
95{
96 while (cmafec_preset_num() > 0) {
97 cmafec_preset_remove(0);
98 }
99 preset_list_destroy(preset_list);
100}
101
102/**********************************************************************/
105 void cmafec_set_fe_parameter(struct city *pcity,
106 const struct cm_parameter *const parameter)
107{
108 cma_set_parameter(ATTR_CITY_CMAFE_PARAMETER, pcity->id, parameter);
109}
110
111/**********************************************************************/
115 void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
116{
117 struct cm_parameter parameter;
118
119 /* our fe_parameter could be stale. our agents parameter is up to date */
120 if (cma_is_city_under_agent(pcity, &parameter)) {
121 cm_copy_parameter(dest, &parameter);
122 cmafec_set_fe_parameter(pcity, dest);
123 } else {
124 /* Create a dummy parameter to return. */
125 cm_init_parameter(dest);
126 if (!cma_get_parameter(ATTR_CITY_CMAFE_PARAMETER, pcity->id, dest)) {
127 /* We haven't seen this city before; store the dummy. */
128 cmafec_set_fe_parameter(pcity, dest);
129 }
130 }
131}
132
133/**********************************************************************/
136 void cmafec_preset_add(const char *descr_name, struct cm_parameter *pparam)
137{
138 struct cma_preset *ppreset = fc_malloc(sizeof(struct cma_preset));
139
140 if (preset_list == NULL) {
141 preset_list = preset_list_new();
142 }
143
144 cm_copy_parameter(&ppreset->parameter, pparam);
145 ppreset->descr = fc_malloc(MAX_LEN_PRESET_NAME);
146 (void) fc_strlcpy(ppreset->descr, descr_name, MAX_LEN_PRESET_NAME);
147 preset_list_prepend(preset_list, ppreset);
148}
149
150/**********************************************************************/
153 void cmafec_preset_remove(int idx)
154{
155 struct cma_preset *ppreset;
156
157 fc_assert_ret(idx >= 0 && idx < cmafec_preset_num());
158
159 ppreset = preset_list_get(preset_list, idx);
160 preset_list_remove(preset_list, ppreset);
161
162 free(ppreset->descr);
163 free(ppreset);
164}
165
166/**********************************************************************/
169 char *cmafec_preset_get_descr(int idx)
170{
171 struct cma_preset *ppreset;
172
173 fc_assert_ret_val(idx >= 0 && idx < cmafec_preset_num(), NULL);
174
175 ppreset = preset_list_get(preset_list, idx);
176 return ppreset->descr;
177}
178
179/**********************************************************************/
182 const struct cm_parameter *cmafec_preset_get_parameter(int idx)
183{
184 struct cma_preset *ppreset;
185
186 fc_assert_ret_val(idx >= 0 && idx < cmafec_preset_num(), NULL);
187
188 ppreset = preset_list_get(preset_list, idx);
189 return &ppreset->parameter;
190}
191
192/**********************************************************************/
196 int cmafec_preset_get_index_of_parameter(const struct cm_parameter
197 *const parameter)
198{
199 int i;
200
201 for (i = 0; i < preset_list_size(preset_list); i++) {
202 struct cma_preset *ppreset = preset_list_get(preset_list, i);
203 if (cm_are_parameter_equal(&ppreset->parameter, parameter)) {
204 return i;
205 }
206 }
207 return -1;
208}
209
210/**********************************************************************/
213 int cmafec_preset_num(void)
214{
215 return preset_list_size(preset_list);
216}
217
218/**********************************************************************/
221 const char *cmafec_get_short_descr_of_city(const struct city *pcity)
222{
223 struct cm_parameter parameter;
224
225 if (!cma_is_city_under_agent(pcity, &parameter)) {
226 return Q_("?cma:none");
227 } else {
228 return cmafec_get_short_descr(&parameter);
229 }
230}
231
232/**********************************************************************/
236 const char *cmafec_get_short_descr(const struct cm_parameter *const
237 parameter)
238{
239 int idx = cmafec_preset_get_index_of_parameter(parameter);
240
241 if (idx == -1) {
242 return Q_("?cma:custom");
243 } else {
244 return cmafec_preset_get_descr(idx);
245 }
246}
247
248/**********************************************************************/
251 static const char *get_city_growth_string(struct city *pcity, int surplus)
252{
253 int stock, cost, turns;
254 static char buffer[50];
255
256 if (surplus == 0) {
257 fc_snprintf(buffer, sizeof(buffer), _("never"));
258 return buffer;
259 }
260
261 stock = pcity->food_stock;
262 cost = city_granary_size(city_size_get(pcity));
263
264 stock += surplus;
265
266 if (stock >= cost) {
267 turns = 1;
268 } else if (surplus > 0) {
269 turns = ((cost - stock - 1) / surplus) + 1 + 1;
270 } else {
271 if (stock < 0) {
272 turns = -1;
273 } else {
274 turns = (stock / surplus);
275 }
276 }
277 fc_snprintf(buffer, sizeof(buffer), PL_("%d turn", "%d turns", turns),
278 turns);
279 return buffer;
280}
281
282/**********************************************************************/
285 static const char *get_prod_complete_string(struct city *pcity, int surplus)
286{
287 int stock, cost, turns;
288 static char buffer[50];
289
290 if (surplus <= 0) {
291 fc_snprintf(buffer, sizeof(buffer), _("never"));
292 return buffer;
293 }
294
295 if (city_production_has_flag(pcity, IF_GOLD)) {
296 fc_strlcpy(buffer, improvement_name_translation
297 (pcity->production.value.building), sizeof(buffer));
298 return buffer;
299 }
300 stock = pcity->shield_stock + surplus;
301 cost = city_production_build_shield_cost(pcity);
302
303 if (stock >= cost) {
304 turns = 1;
305 } else if (surplus > 0) {
306 turns = ((cost - stock - 1) / surplus) + 1 + 1;
307 } else {
308 if (stock < 0) {
309 turns = -1;
310 } else {
311 turns = (stock / surplus);
312 }
313 }
314 fc_snprintf(buffer, sizeof(buffer), PL_("%d turn", "%d turns", turns),
315 turns);
316 return buffer;
317}
318
319/**********************************************************************/
322 const char *cmafec_get_result_descr(struct city *pcity,
323 const struct cm_result *result,
324 const struct cm_parameter *const
325 parameter)
326{
327 int j;
328 char buf[RESULT_COLUMNS][BUFFER_SIZE];
329 char citizen_types[BUFFER_SIZE];
330 static char buffer[600];
331 int slen;
332
333 /* TRANS: "W" is worker citizens, as opposed to specialists;
334 * %s will represent the specialist types, for instance "E/S/T" */
335 fc_snprintf(citizen_types, BUFFER_SIZE, _("People (W/%s)"),
336 specialists_abbreviation_string());
337
338 if (!result->found_a_valid) {
339 for (j = 0; j < RESULT_COLUMNS; j++)
340 fc_snprintf(buf[j], BUFFER_SIZE, "---");
341 } else {
342 output_type_iterate(o) {
343 fc_snprintf(buf[o], BUFFER_SIZE, "%+3d", result->surplus[o]);
344 } output_type_iterate_end;
345
346 fc_snprintf(buf[6], BUFFER_SIZE, "%d/%s%s",
347 city_size_get(pcity) - cm_result_specialists(result),
348 specialists_string(result->specialists),
349 /* TRANS: preserve leading space */
350 result->happy ? _(" happy") : "");
351
352 fc_snprintf(buf[7], BUFFER_SIZE, "%s",
353 get_city_growth_string(pcity, result->surplus[O_FOOD]));
354 fc_snprintf(buf[8], BUFFER_SIZE, "%s",
355 get_prod_complete_string(pcity, result->surplus[O_SHIELD]));
356 fc_snprintf(buf[9], BUFFER_SIZE, "%s",
357 cmafec_get_short_descr(parameter));
358 }
359
360 slen = 20 - (int)get_internal_string_length(citizen_types);
361 fc_snprintf(buffer, sizeof(buffer),
362 _("Name: %s\n"
363 "Food: %10s Gold: %10s\n"
364 "Production: %10s Luxury: %10s\n"
365 "Trade: %10s Science: %10s\n"
366 "\n"
367 "%*s%s: %s\n"
368 " City grows: %s\n"
369 "Production completed: %s"),
370 buf[9], buf[O_FOOD], buf[O_GOLD], buf[O_SHIELD], buf[O_LUXURY],
371 buf[O_TRADE], buf[O_SCIENCE],
372 MAX(0, slen), "",
373 citizen_types,
374 buf[6], buf[7], buf[8]);
375
376 log_debug("\n%s", buffer);
377
378 return buffer;
379}
380
381/**********************************************************************/
384 void create_default_cma_presets(void)
385{
386 int i;
387 struct cm_parameter parameters[] = {
388 { /* very happy */
389 .minimal_surplus = {0, 0, 0, -20, 0, 0},
390 .require_happy = FALSE,
391 .allow_disorder = FALSE,
392 .allow_specialists = TRUE,
393 .factor = {10, 5, 0, 4, 0, 4},
394 .happy_factor = 25
395 },
396 { /* prefer food */
397 .minimal_surplus = {-20, 0, 0, -20, 0, 0},
398 .require_happy = FALSE,
399 .allow_disorder = FALSE,
400 .allow_specialists = TRUE,
401 .factor = {25, 5, 0, 4, 0, 4},
402 .happy_factor = 0
403 },
404 { /* prefer prod */
405 .minimal_surplus = {0, -20, 0, -20, 0, 0},
406 .require_happy = FALSE,
407 .allow_disorder = FALSE,
408 .allow_specialists = TRUE,
409 .factor = {10, 25, 0, 4, 0, 4},
410 .happy_factor = 0
411 },
412 { /* prefer gold */
413 .minimal_surplus = {0, 0, 0, -20, 0, 0},
414 .require_happy = FALSE,
415 .allow_disorder = FALSE,
416 .allow_specialists = TRUE,
417 .factor = {10, 5, 0, 25, 0, 4},
418 .happy_factor = 0
419 },
420 { /* prefer science */
421 .minimal_surplus = {0, 0, 0, -20, 0, 0},
422 .require_happy = FALSE,
423 .allow_disorder = FALSE,
424 .allow_specialists = TRUE,
425 .factor = {10, 5, 0, 4, 0, 25},
426 .happy_factor = 0
427 }
428 };
429 const char *names[ARRAY_SIZE(parameters)] = {
430 N_("?cma:Very happy"),
431 N_("?cma:Prefer food"),
432 N_("?cma:Prefer production"),
433 N_("?cma:Prefer gold"),
434 N_("?cma:Prefer science")
435 };
436
437 for (i = ARRAY_SIZE(parameters) - 1; i >= 0; i--) {
438 cmafec_preset_add(Q_(names[i]), &parameters[i]);
439 }
440}
register_agent
void register_agent(const struct agent *agent)
Definition agents.c:378
agents.h
CB_REMOVE
@ CB_REMOVE
Definition agents.h:37
attr_city_set
void attr_city_set(enum attr_city what, int city_id, size_t data_length, const void *const data)
Definition attribute.c:482
attribute.h
ATTR_CITY_CMAFE_PARAMETER
@ ATTR_CITY_CMAFE_PARAMETER
Definition attribute.h:39
city_production_build_shield_cost
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:722
city_granary_size
int city_granary_size(int city_size)
Definition city.c:2101
city_production_has_flag
bool city_production_has_flag(const struct city *pcity, enum impr_flag_id flag)
Definition city.c:712
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
output_type_iterate
#define output_type_iterate(output)
Definition city.h:812
output_type_iterate_end
#define output_type_iterate_end
Definition city.h:818
self
static struct ai_type * self
Definition classicai.c:46
cm_copy_parameter
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2169
cm_init_parameter
void cm_init_parameter(struct cm_parameter *dest)
Definition cm.c:2178
cm_result_specialists
int cm_result_specialists(const struct cm_result *result)
Definition cm.c:2233
cm_are_parameter_equal
bool cm_are_parameter_equal(const struct cm_parameter *const p1, const struct cm_parameter *const p2)
Definition cm.c:2136
cma_is_city_under_agent
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:550
cma_get_parameter
bool cma_get_parameter(enum attr_city attr, int city_id, struct cm_parameter *parameter)
Definition cma_core.c:573
cma_set_parameter
void cma_set_parameter(enum attr_city attr, int city_id, const struct cm_parameter *parameter)
Definition cma_core.c:621
cmafec_get_short_descr
const char * cmafec_get_short_descr(const struct cm_parameter *const parameter)
Definition cma_fec.c:236
cmafec_set_fe_parameter
void cmafec_set_fe_parameter(struct city *pcity, const struct cm_parameter *const parameter)
Definition cma_fec.c:105
cmafec_free
void cmafec_free(void)
Definition cma_fec.c:94
preset_list
static struct preset_list * preset_list
Definition cma_fec.c:62
RESULT_COLUMNS
#define RESULT_COLUMNS
Definition cma_fec.c:45
cmafec_preset_get_descr
char * cmafec_preset_get_descr(int idx)
Definition cma_fec.c:169
cmafec_get_result_descr
const char * cmafec_get_result_descr(struct city *pcity, const struct cm_result *result, const struct cm_parameter *const parameter)
Definition cma_fec.c:322
BUFFER_SIZE
#define BUFFER_SIZE
Definition cma_fec.c:46
cmafec_get_short_descr_of_city
const char * cmafec_get_short_descr_of_city(const struct city *pcity)
Definition cma_fec.c:221
get_city_growth_string
static const char * get_city_growth_string(struct city *pcity, int surplus)
Definition cma_fec.c:251
cmafec_preset_get_parameter
const struct cm_parameter * cmafec_preset_get_parameter(int idx)
Definition cma_fec.c:182
cmafec_preset_add
void cmafec_preset_add(const char *descr_name, struct cm_parameter *pparam)
Definition cma_fec.c:136
cmafec_preset_get_index_of_parameter
int cmafec_preset_get_index_of_parameter(const struct cm_parameter *const parameter)
Definition cma_fec.c:196
city_remove
static void city_remove(int city_id)
Definition cma_fec.c:68
get_prod_complete_string
static const char * get_prod_complete_string(struct city *pcity, int surplus)
Definition cma_fec.c:285
cmafec_preset_remove
void cmafec_preset_remove(int idx)
Definition cma_fec.c:153
cmafec_init
void cmafec_init(void)
Definition cma_fec.c:76
MAX_LEN_PRESET_NAME
#define MAX_LEN_PRESET_NAME
Definition cma_fec.c:47
cmafec_preset_num
int cmafec_preset_num(void)
Definition cma_fec.c:213
create_default_cma_presets
void create_default_cma_presets(void)
Definition cma_fec.c:384
cmafec_get_fe_parameter
void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
Definition cma_fec.c:115
cma_fec.h
cost
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
O_SHIELD
@ O_SHIELD
Definition fc_types.h:91
O_FOOD
@ O_FOOD
Definition fc_types.h:91
O_TRADE
@ O_TRADE
Definition fc_types.h:91
O_SCIENCE
@ O_SCIENCE
Definition fc_types.h:91
O_LUXURY
@ O_LUXURY
Definition fc_types.h:91
O_GOLD
@ O_GOLD
Definition fc_types.h:91
get_internal_string_length
size_t get_internal_string_length(const char *text)
Definition fciconv.c:395
fciconv.h
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
PL_
#define PL_(String1, String2, n)
Definition fcintl.h:71
_
#define _(String)
Definition fcintl.h:67
N_
#define N_(String)
Definition fcintl.h:69
game.h
improvement_name_translation
const char * improvement_name_translation(const struct impr_type *pimprove)
Definition improvement.c:241
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
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
mem.h
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MAX
#define MAX(x, y)
Definition shared.h:54
specialists_abbreviation_string
const char * specialists_abbreviation_string(void)
Definition specialist.c:174
specialists_string
const char * specialists_string(const citizens *specialist_list)
Definition specialist.c:199
specialist.h
speclist.h
agent
Definition agents.h:40
ai_type::name
char name[MAX_LEN_NAME]
Definition ai.h:51
city
Definition city.h:309
city::food_stock
int food_stock
Definition city.h:354
city::id
int id
Definition city.h:315
city::production
struct universal production
Definition city.h:382
city::shield_stock
int shield_stock
Definition city.h:355
cm_parameter
Definition cm.h:40
cm_parameter::minimal_surplus
int minimal_surplus[O_LAST]
Definition cm.h:41
cm_result
Definition cm.h:52
cm_result::found_a_valid
bool found_a_valid
Definition cm.h:54
cm_result::surplus
int surplus[O_LAST]
Definition cm.h:56
cm_result::happy
bool happy
Definition cm.h:54
cm_result::specialists
citizens specialists[SP_MAX]
Definition cm.h:60
cma_preset
Definition cma_fec.c:49
cma_preset::parameter
struct cm_parameter parameter
Definition cma_fec.c:51
cma_preset::descr
char * descr
Definition cma_fec.c:50
universal::value
universals_u value
Definition fc_types.h:757
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:787
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
universals_u::building
const struct impr_type * building
Definition fc_types.h:598