Freeciv-3.1: /fast/freeciv/nightly/S3_1/ai/difficulty.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
difficulty.c
Go to the documentation of this file.
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)
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/* utility */
19#include "astring.h"
20#include "bitvector.h"
21#include "rand.h"
22
23/* common */
24#include "player.h"
25
26/* ai */
27#include "handicaps.h"
28
29#include "difficulty.h"
30
31static bv_handicap handicap_of_skill_level(enum ai_level level);
32static int fuzzy_of_skill_level(enum ai_level level);
33static int science_cost_of_skill_level(enum ai_level level);
34static int expansionism_of_skill_level(enum ai_level level);
35
36/**********************************************************************/
39 void set_ai_level_directer(struct player *pplayer, enum ai_level level)
40{
41 handicaps_set(pplayer, handicap_of_skill_level(level));
42 pplayer->ai_common.fuzzy = fuzzy_of_skill_level(level);
43 pplayer->ai_common.expand = expansionism_of_skill_level(level);
44 pplayer->ai_common.science_cost = science_cost_of_skill_level(level);
45 pplayer->ai_common.skill_level = level;
46}
47
48/**********************************************************************/
51 static bv_handicap handicap_of_skill_level(enum ai_level level)
52{
53 bv_handicap handicap;
54
55 fc_assert(ai_level_is_valid(level));
56
57 BV_CLR_ALL(handicap);
58
59 switch (level) {
60 case AI_LEVEL_AWAY:
61 BV_SET(handicap, H_AWAY);
62 BV_SET(handicap, H_FOG);
63 BV_SET(handicap, H_MAP);
64 BV_SET(handicap, H_RATES);
65 BV_SET(handicap, H_TARGETS);
66 BV_SET(handicap, H_HUTS);
67 BV_SET(handicap, H_REVOLUTION);
68#ifdef FREECIV_WEB
69 BV_SET(handicap, H_ASSESS_DANGER_LIMITED);
70#endif
71 BV_SET(handicap, H_PRODCHGPEN);
72 break;
73 case AI_LEVEL_NOVICE:
74 case AI_LEVEL_RESTRICTED:
75 BV_SET(handicap, H_RATES);
76 BV_SET(handicap, H_TARGETS);
77 BV_SET(handicap, H_HUTS);
78 BV_SET(handicap, H_NOPLANES);
79 BV_SET(handicap, H_DIPLOMAT);
80 BV_SET(handicap, H_LIMITEDHUTS);
81 BV_SET(handicap, H_DEFENSIVE);
82 BV_SET(handicap, H_DIPLOMACY);
83 BV_SET(handicap, H_REVOLUTION);
84 BV_SET(handicap, H_EXPANSION);
85 BV_SET(handicap, H_DANGER);
86 BV_SET(handicap, H_CEASEFIRE);
87 BV_SET(handicap, H_NOBRIBE_WF);
88#ifdef FREECIV_WEB
89 BV_SET(handicap, H_ASSESS_DANGER_LIMITED);
90#endif
91 BV_SET(handicap, H_PRODCHGPEN);
92 break;
93 case AI_LEVEL_EASY:
94 BV_SET(handicap, H_RATES);
95 BV_SET(handicap, H_TARGETS);
96 BV_SET(handicap, H_HUTS);
97 BV_SET(handicap, H_NOPLANES);
98 BV_SET(handicap, H_DIPLOMAT);
99 BV_SET(handicap, H_LIMITEDHUTS);
100 BV_SET(handicap, H_DEFENSIVE);
101 BV_SET(handicap, H_DIPLOMACY);
102 BV_SET(handicap, H_REVOLUTION);
103 BV_SET(handicap, H_EXPANSION);
104 BV_SET(handicap, H_CEASEFIRE);
105#ifdef FREECIV_WEB
106 BV_SET(handicap, H_ASSESS_DANGER_LIMITED);
107#endif
108 BV_SET(handicap, H_NOBRIBE_WF);
109 break;
110 case AI_LEVEL_NORMAL:
111 BV_SET(handicap, H_RATES);
112 BV_SET(handicap, H_TARGETS);
113 BV_SET(handicap, H_HUTS);
114 BV_SET(handicap, H_DIPLOMAT);
115 BV_SET(handicap, H_CEASEFIRE);
116 BV_SET(handicap, H_NOBRIBE_WF);
117 break;
118
119#ifdef FREECIV_DEBUG
120 case AI_LEVEL_EXPERIMENTAL:
121 /* H_EXPERIMENTAL + whatever Hard has */
122 BV_SET(handicap, H_EXPERIMENTAL);
123 fc__fallthrough; /* Falling through to hard */
124#endif /* FREECIV_DEBUG */
125
126 case AI_LEVEL_CHEATING:
127 case AI_LEVEL_HARD:
128 /* No actual handicaps */
129 BV_SET(handicap, H_RATES);
130 break;
131 case AI_LEVEL_COUNT:
132 fc_assert(level != AI_LEVEL_COUNT);
133 break;
134 }
135
136 return handicap;
137}
138
139/**********************************************************************/
143 static int fuzzy_of_skill_level(enum ai_level level)
144{
145 fc_assert(ai_level_is_valid(level));
146
147 switch (level) {
148 case AI_LEVEL_AWAY:
149 return 0;
150 case AI_LEVEL_RESTRICTED:
151 case AI_LEVEL_NOVICE:
152 return 400;
153 case AI_LEVEL_EASY:
154 return 300;
155 case AI_LEVEL_NORMAL:
156 case AI_LEVEL_HARD:
157 case AI_LEVEL_CHEATING:
158#ifdef FREECIV_DEBUG
159 case AI_LEVEL_EXPERIMENTAL:
160#endif /* FREECIV_DEBUG */
161 return 0;
162 case AI_LEVEL_COUNT:
163 fc_assert(level != AI_LEVEL_COUNT);
164 return 0;
165 }
166
167 return 0;
168}
169
170/**********************************************************************/
177 static int science_cost_of_skill_level(enum ai_level level)
178{
179 fc_assert(ai_level_is_valid(level));
180
181 switch (level) {
182 case AI_LEVEL_AWAY:
183 return 100;
184 case AI_LEVEL_RESTRICTED:
185 case AI_LEVEL_NOVICE:
186 return 250;
187 case AI_LEVEL_EASY:
188 case AI_LEVEL_NORMAL:
189 case AI_LEVEL_HARD:
190 case AI_LEVEL_CHEATING:
191#ifdef FREECIV_DEBUG
192 case AI_LEVEL_EXPERIMENTAL:
193#endif /* FREECIV_DEBUG */
194 return 100;
195 case AI_LEVEL_COUNT:
196 fc_assert(level != AI_LEVEL_COUNT);
197 return 100;
198 }
199
200 return 100;
201}
202
203/**********************************************************************/
208 static int expansionism_of_skill_level(enum ai_level level)
209{
210 fc_assert(ai_level_is_valid(level));
211
212 switch (level) {
213 case AI_LEVEL_AWAY:
214 return 0;
215 case AI_LEVEL_RESTRICTED:
216 case AI_LEVEL_NOVICE:
217 case AI_LEVEL_EASY:
218 return 10;
219 case AI_LEVEL_NORMAL:
220 case AI_LEVEL_HARD:
221 case AI_LEVEL_CHEATING:
222#ifdef FREECIV_DEBUG
223 case AI_LEVEL_EXPERIMENTAL:
224#endif /* FREECIV_DEBUG */
225 return 100;
226 case AI_LEVEL_COUNT:
227 fc_assert(level != AI_LEVEL_COUNT);
228 return 100;
229 }
230
231 return 100;
232}
233
234/**********************************************************************/
239 char *ai_level_help(const char *cmdname)
240{
241 /* Translate cmdname to AI level. */
242 enum ai_level level = ai_level_by_name(cmdname, fc_strcasecmp);
243 struct astring help = ASTRING_INIT, features = ASTRING_INIT;
244 bv_handicap handicaps;
245 enum handicap_type h;
246
247 fc_assert(ai_level_is_valid(level));
248
249 if (level == AI_LEVEL_AWAY) {
250 /* Special case */
251 astr_add_line(&help,
252 _("Toggles 'away' mode for your nation. In away mode, "
253 "the AI will govern your nation but make only minimal "
254 "changes."));
255 } else {
256 /* TRANS: %s is a (translated) skill level ('Novice', 'Hard', etc) */
257 astr_add_line(&help,
258 _("With no arguments, sets all AI players to skill level "
259 "'%s', and sets the default level for any new AI "
260 "players to '%s'. With an argument, sets the skill "
261 "level for the specified player only."),
262 _(ai_level_name(level)), _(ai_level_name(level)));
263 }
264
265 handicaps = handicap_of_skill_level(level);
266 for (h = 0; h < H_LAST; h++) {
267 bool inverted;
268 const char *desc = handicap_desc(h, &inverted);
269
270 if (desc && BV_ISSET(handicaps, h) != inverted) {
271 astr_add_line(&features, "%s", desc);
272 }
273 }
274
275 if (fuzzy_of_skill_level(level) > 0) {
276 astr_add_line(&features, _("Has erratic decision-making."));
277 }
278 {
279 int science = science_cost_of_skill_level(level);
280
281 if (science != 100) {
282 astr_add_line(&features,
283 _("Research takes %d%% as long as usual."), science);
284 }
285 }
286 if (expansionism_of_skill_level(level) < 100) {
287 astr_add_line(&features, _("Has reduced appetite for expansion."));
288 } /* no level currently has >100, so no string yet */
289
290 switch (level) {
291 case AI_LEVEL_RESTRICTED:
292 /* TRANS: describing an AI skill level */
293 astr_add_line(&help,
294 _("\nThis skill level has the same features as 'Novice', "
295 "but may suffer additional ruleset-defined penalties."));
296 break;
297 case AI_LEVEL_CHEATING:
298 /* TRANS: describing an AI skill level */
299 astr_add_line(&help,
300 _("\nThis skill level has the same features as 'Hard', "
301 "but may enjoy additional ruleset-defined bonuses."));
302 break;
303 default:
304 /* In principle this text should vary, but all current skill levels
305 * have _some_ feature text */
306 fc_assert(!astr_empty(&features));
307 /* TRANS: describing an AI skill level */
308 astr_add_line(&help,
309 _("\nThis skill level's features include the following. "
310 "(Some rulesets may define extra level-specific "
311 "behavior.)"));
312 break;
313 }
314
315 if (!astr_empty(&features)) {
316 astr_add_line(&help, "\n%s", astr_str(&features));
317 }
318
319 astr_free(&features);
320 return astr_to_str(&help);
321}
322
323/**********************************************************************/
339 bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
340{
341 if (!is_ai(pplayer) || pplayer->ai_common.fuzzy == 0) {
342 return normal_decision;
343 }
344 if (fc_rand(1000) >= pplayer->ai_common.fuzzy) {
345 return normal_decision;
346 }
347 return !normal_decision;
348}
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astr_add_line
void astr_add_line(struct astring *astr, const char *format,...)
Definition astring.c:299
astr_to_str
char * astr_to_str(struct astring *astr)
Definition astring.c:167
astring.h
astr_str
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
ASTRING_INIT
#define ASTRING_INIT
Definition astring.h:44
astr_empty
static bool astr_empty(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:125
bitvector.h
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
fuzzy_of_skill_level
static int fuzzy_of_skill_level(enum ai_level level)
Definition difficulty.c:143
set_ai_level_directer
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Definition difficulty.c:39
expansionism_of_skill_level
static int expansionism_of_skill_level(enum ai_level level)
Definition difficulty.c:208
science_cost_of_skill_level
static int science_cost_of_skill_level(enum ai_level level)
Definition difficulty.c:177
ai_level_help
char * ai_level_help(const char *cmdname)
Definition difficulty.c:239
handicap_of_skill_level
static bv_handicap handicap_of_skill_level(enum ai_level level)
Definition difficulty.c:51
ai_fuzzy
bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
Definition difficulty.c:339
difficulty.h
_
#define _(String)
Definition fcintl.h:67
handicap_desc
const char * handicap_desc(enum handicap_type htype, bool *inverted)
Definition handicaps.c:80
handicaps_set
void handicaps_set(struct player *pplayer, bv_handicap handicaps)
Definition handicaps.c:55
handicaps.h
handicap_type
handicap_type
Definition handicaps.h:17
H_LAST
@ H_LAST
Definition handicaps.h:37
H_MAP
@ H_MAP
Definition handicaps.h:28
H_REVOLUTION
@ H_REVOLUTION
Definition handicaps.h:30
H_DIPLOMACY
@ H_DIPLOMACY
Definition handicaps.h:29
H_DIPLOMAT
@ H_DIPLOMAT
Definition handicaps.h:18
H_TARGETS
@ H_TARGETS
Definition handicaps.h:24
H_LIMITEDHUTS
@ H_LIMITEDHUTS
Definition handicaps.h:20
H_RATES
@ H_RATES
Definition handicaps.h:23
H_AWAY
@ H_AWAY
Definition handicaps.h:19
H_HUTS
@ H_HUTS
Definition handicaps.h:25
H_EXPERIMENTAL
@ H_EXPERIMENTAL
Definition handicaps.h:22
H_DEFENSIVE
@ H_DEFENSIVE
Definition handicaps.h:21
H_DANGER
@ H_DANGER
Definition handicaps.h:32
H_NOBRIBE_WF
@ H_NOBRIBE_WF
Definition handicaps.h:34
H_NOPLANES
@ H_NOPLANES
Definition handicaps.h:27
H_FOG
@ H_FOG
Definition handicaps.h:26
H_PRODCHGPEN
@ H_PRODCHGPEN
Definition handicaps.h:35
H_EXPANSION
@ H_EXPANSION
Definition handicaps.h:31
H_CEASEFIRE
@ H_CEASEFIRE
Definition handicaps.h:33
H_ASSESS_DANGER_LIMITED
@ H_ASSESS_DANGER_LIMITED
Definition handicaps.h:36
fc_assert
#define fc_assert(condition)
Definition log.h:176
player.h
is_ai
#define is_ai(plr)
Definition player.h:234
rand.h
fc_rand
#define fc_rand(_size)
Definition rand.h:34
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
astring
Definition astring.h:36
player_ai::skill_level
enum ai_level skill_level
Definition player.h:122
player_ai::science_cost
int science_cost
Definition player.h:125
player_ai::expand
int expand
Definition player.h:124
player_ai::fuzzy
int fuzzy
Definition player.h:123
player
Definition player.h:249
player::ai_common
struct player_ai ai_common
Definition player.h:288
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc__fallthrough
#define fc__fallthrough
Definition support.h:109