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 ***********************************************************************/
15 #include <fc_config.h>
19 #include "bitvector.h"
26 #include "handicaps.h"
28 #include "difficulty.h"
30 static bv_handicap
handicap_of_skill_level(enum ai_level level
);
31 static int fuzzy_of_skill_level(enum ai_level level
);
32 static int science_cost_of_skill_level(enum ai_level level
);
33 static int expansionism_of_skill_level(enum ai_level level
);
35 /**************************************************************************
36 Set an AI level and related quantities, with no feedback.
37 **************************************************************************/
38 void set_ai_level_directer(struct player
*pplayer
, enum ai_level level
)
40 handicaps_set(pplayer
, handicap_of_skill_level(level
));
41 pplayer
->ai_common
.fuzzy
= fuzzy_of_skill_level(level
);
42 pplayer
->ai_common
.expand
= expansionism_of_skill_level(level
);
43 pplayer
->ai_common
.science_cost
= science_cost_of_skill_level(level
);
44 pplayer
->ai_common
.skill_level
= level
;
47 /**************************************************************************
48 Returns handicap bitvector for given AI skill level
49 **************************************************************************/
50 static bv_handicap
handicap_of_skill_level(enum ai_level level
)
54 fc_assert(ai_level_is_valid(level
));
60 BV_SET(handicap
, H_AWAY
);
61 BV_SET(handicap
, H_FOG
);
62 BV_SET(handicap
, H_MAP
);
63 BV_SET(handicap
, H_RATES
);
64 BV_SET(handicap
, H_TARGETS
);
65 BV_SET(handicap
, H_HUTS
);
66 BV_SET(handicap
, H_REVOLUTION
);
69 case AI_LEVEL_HANDICAPPED
:
70 BV_SET(handicap
, H_RATES
);
71 BV_SET(handicap
, H_TARGETS
);
72 BV_SET(handicap
, H_HUTS
);
73 BV_SET(handicap
, H_NOPLANES
);
74 BV_SET(handicap
, H_DIPLOMAT
);
75 BV_SET(handicap
, H_LIMITEDHUTS
);
76 BV_SET(handicap
, H_DEFENSIVE
);
77 BV_SET(handicap
, H_DIPLOMACY
);
78 BV_SET(handicap
, H_REVOLUTION
);
79 BV_SET(handicap
, H_EXPANSION
);
80 BV_SET(handicap
, H_DANGER
);
81 BV_SET(handicap
, H_CEASEFIRE
);
84 BV_SET(handicap
, H_RATES
);
85 BV_SET(handicap
, H_TARGETS
);
86 BV_SET(handicap
, H_HUTS
);
87 BV_SET(handicap
, H_NOPLANES
);
88 BV_SET(handicap
, H_DIPLOMAT
);
89 BV_SET(handicap
, H_LIMITEDHUTS
);
90 BV_SET(handicap
, H_DEFENSIVE
);
91 BV_SET(handicap
, H_DIPLOMACY
);
92 BV_SET(handicap
, H_REVOLUTION
);
93 BV_SET(handicap
, H_EXPANSION
);
94 BV_SET(handicap
, H_CEASEFIRE
);
97 BV_SET(handicap
, H_RATES
);
98 BV_SET(handicap
, H_TARGETS
);
99 BV_SET(handicap
, H_HUTS
);
100 BV_SET(handicap
, H_DIPLOMAT
);
101 BV_SET(handicap
, H_CEASEFIRE
);
105 case AI_LEVEL_EXPERIMENTAL
:
106 BV_SET(handicap
, H_EXPERIMENTAL
);
110 case AI_LEVEL_CHEATING
:
111 BV_SET(handicap
, H_RATES
);
117 fc_assert(level
!= AI_LEVEL_COUNT
);
124 /**************************************************************************
125 Return the AI fuzziness (0 to 1000) corresponding to a given skill
126 level (1 to 10). See ai_fuzzy() in common/player.c
127 **************************************************************************/
128 static int fuzzy_of_skill_level(enum ai_level level
)
130 fc_assert(ai_level_is_valid(level
));
135 case AI_LEVEL_HANDICAPPED
:
136 case AI_LEVEL_NOVICE
:
140 case AI_LEVEL_NORMAL
:
142 case AI_LEVEL_CHEATING
:
144 case AI_LEVEL_EXPERIMENTAL
:
148 fc_assert(level
!= AI_LEVEL_COUNT
);
155 /**************************************************************************
156 Return the AI's science development cost; a science development cost of 100
157 means that the AI develops science at the same speed as a human; a science
158 development cost of 200 means that the AI develops science at half the speed
159 of a human, and a sceence development cost of 50 means that the AI develops
160 science twice as fast as the human.
161 **************************************************************************/
162 static int science_cost_of_skill_level(enum ai_level level
)
164 fc_assert(ai_level_is_valid(level
));
169 case AI_LEVEL_HANDICAPPED
:
170 case AI_LEVEL_NOVICE
:
173 case AI_LEVEL_NORMAL
:
175 case AI_LEVEL_CHEATING
:
177 case AI_LEVEL_EXPERIMENTAL
:
181 fc_assert(level
!= AI_LEVEL_COUNT
);
188 /**************************************************************************
189 Return the AI expansion tendency, a percentage factor to value new cities,
190 compared to defaults. 0 means _never_ build new cities, > 100 means to
191 (over?)value them even more than the default (already expansionistic) AI.
192 **************************************************************************/
193 static int expansionism_of_skill_level(enum ai_level level
)
195 fc_assert(ai_level_is_valid(level
));
200 case AI_LEVEL_HANDICAPPED
:
201 case AI_LEVEL_NOVICE
:
204 case AI_LEVEL_NORMAL
:
206 case AI_LEVEL_CHEATING
:
208 case AI_LEVEL_EXPERIMENTAL
:
212 fc_assert(level
!= AI_LEVEL_COUNT
);
219 /**************************************************************************
220 Return the value normal_decision (a boolean), except if the AI is fuzzy,
221 then sometimes flip the value. The intention of this is that instead of
222 if (condition) { action }
224 if (ai_fuzzy(pplayer, condition)) { action }
225 to sometimes flip a decision, to simulate an AI with some confusion,
226 indecisiveness, forgetfulness etc. In practice its often safer to use
227 if (condition && ai_fuzzy(pplayer,1)) { action }
228 for an action which only makes sense if condition holds, but which a
229 fuzzy AI can safely "forget". Note that for a non-fuzzy AI, or for a
230 human player being helped by the AI (eg, autosettlers), you can ignore
231 the "ai_fuzzy(pplayer," part, and read the previous example as:
232 if (condition && 1) { action }
234 **************************************************************************/
235 bool ai_fuzzy(const struct player
*pplayer
, bool normal_decision
)
237 if (!pplayer
->ai_controlled
|| pplayer
->ai_common
.fuzzy
== 0) {
238 return normal_decision
;
240 if (fc_rand(1000) >= pplayer
->ai_common
.fuzzy
) {
241 return normal_decision
;
243 return !normal_decision
;