Freeciv-3.3
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/**********************************************************************/
47
48/**********************************************************************/
52{
54
56
58
59 switch (level) {
60 case AI_LEVEL_AWAY:
68#ifdef FREECIV_WEB
70#endif
72 break;
73 case AI_LEVEL_NOVICE:
88#ifdef FREECIV_WEB
90#endif
92 break;
93 case AI_LEVEL_EASY:
105#ifdef FREECIV_WEB
107#endif
109 break;
110 case AI_LEVEL_NORMAL:
117 break;
118
119#ifdef FREECIV_DEBUG
121 /* H_EXPERIMENTAL + whatever Hard has */
123 fc__fallthrough; /* Falling through to hard */
124#endif /* FREECIV_DEBUG */
125
127 case AI_LEVEL_HARD:
128 /* No actual handicaps */
130 break;
131 case AI_LEVEL_COUNT:
133 break;
134 }
135
136 return handicap;
137}
138
139/**********************************************************************/
143static int fuzzy_of_skill_level(enum ai_level level)
144{
146
147 switch (level) {
148 case AI_LEVEL_AWAY:
149 return 0;
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:
158#ifdef FREECIV_DEBUG
160#endif /* FREECIV_DEBUG */
161 return 0;
162 case AI_LEVEL_COUNT:
164 return 0;
165 }
166
167 return 0;
168}
169
170/**********************************************************************/
177static int science_cost_of_skill_level(enum ai_level level)
178{
180
181 switch (level) {
182 case AI_LEVEL_AWAY:
183 return 100;
185 case AI_LEVEL_NOVICE:
186 return 250;
187 case AI_LEVEL_EASY:
188 case AI_LEVEL_NORMAL:
189 case AI_LEVEL_HARD:
191#ifdef FREECIV_DEBUG
193#endif /* FREECIV_DEBUG */
194 return 100;
195 case AI_LEVEL_COUNT:
197 return 100;
198 }
199
200 return 100;
201}
202
203/**********************************************************************/
208static int expansionism_of_skill_level(enum ai_level level)
209{
211
212 switch (level) {
213 case AI_LEVEL_AWAY:
214 return 0;
216 case AI_LEVEL_NOVICE:
217 case AI_LEVEL_EASY:
218 return 10;
219 case AI_LEVEL_NORMAL:
220 case AI_LEVEL_HARD:
222#ifdef FREECIV_DEBUG
224#endif /* FREECIV_DEBUG */
225 return 100;
226 case AI_LEVEL_COUNT:
228 return 100;
229 }
230
231 return 100;
232}
233
234/**********************************************************************/
239char *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
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."),
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) {
283 _("Research takes %d%% as long as usual."), science);
284 }
285 }
287 astr_add_line(&features, _("Has reduced appetite for expansion."));
288 } /* no level currently has >100, so no string yet */
289
290 switch (level) {
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;
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 */
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
320 return astr_to_str(&help);
321}
322
323/**********************************************************************/
339bool 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}
void astr_free(struct astring *astr)
Definition astring.c:148
void astr_add_line(struct astring *astr, const char *format,...)
Definition astring.c:283
char * astr_to_str(struct astring *astr)
Definition astring.c:163
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
static bool astr_empty(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:125
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
char * incite_cost
Definition comments.c:76
static int fuzzy_of_skill_level(enum ai_level level)
Definition difficulty.c:143
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Definition difficulty.c:39
static int expansionism_of_skill_level(enum ai_level level)
Definition difficulty.c:208
static int science_cost_of_skill_level(enum ai_level level)
Definition difficulty.c:177
char * ai_level_help(const char *cmdname)
Definition difficulty.c:239
static bv_handicap handicap_of_skill_level(enum ai_level level)
Definition difficulty.c:51
bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
Definition difficulty.c:339
#define _(String)
Definition fcintl.h:67
const char * handicap_desc(enum handicap_type htype, bool *inverted)
Definition handicaps.c:80
void handicaps_set(struct player *pplayer, bv_handicap handicaps)
Definition handicaps.c:55
handicap_type
Definition handicaps.h:17
@ H_LAST
Definition handicaps.h:37
@ H_MAP
Definition handicaps.h:28
@ H_REVOLUTION
Definition handicaps.h:30
@ H_DIPLOMACY
Definition handicaps.h:29
@ H_DIPLOMAT
Definition handicaps.h:18
@ H_TARGETS
Definition handicaps.h:24
@ H_LIMITEDHUTS
Definition handicaps.h:20
@ H_RATES
Definition handicaps.h:23
@ H_AWAY
Definition handicaps.h:19
@ H_HUTS
Definition handicaps.h:25
@ H_EXPERIMENTAL
Definition handicaps.h:22
@ H_DEFENSIVE
Definition handicaps.h:21
@ H_DANGER
Definition handicaps.h:32
@ H_NOBRIBE_WF
Definition handicaps.h:34
@ H_NOPLANES
Definition handicaps.h:27
@ H_FOG
Definition handicaps.h:26
@ H_PRODCHGPEN
Definition handicaps.h:35
@ H_EXPANSION
Definition handicaps.h:31
@ H_CEASEFIRE
Definition handicaps.h:33
@ H_ASSESS_DANGER_LIMITED
Definition handicaps.h:36
#define fc_assert(condition)
Definition log.h:177
#define is_ai(plr)
Definition player.h:232
#define fc_rand(_size)
Definition rand.h:56
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
enum ai_level skill_level
Definition player.h:116
int science_cost
Definition player.h:119
int expand
Definition player.h:118
int fuzzy
Definition player.h:117
struct player_ai ai_common
Definition player.h:288
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
#define fc__fallthrough
Definition support.h:119