Auto help: free list of quoted action blockers.
[freeciv.git] / ai / difficulty.c
blob0e2d14cb169bce61886e67734ffee45ca77e70a5
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "bitvector.h"
20 #include "rand.h"
22 /* common */
23 #include "player.h"
25 /* ai */
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)
52 bv_handicap handicap;
54 fc_assert(ai_level_is_valid(level));
56 BV_CLR_ALL(handicap);
58 switch (level) {
59 case AI_LEVEL_AWAY:
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);
67 BV_SET(handicap, H_PRODCHGPEN);
68 break;
69 case AI_LEVEL_NOVICE:
70 case AI_LEVEL_HANDICAPPED:
71 BV_SET(handicap, H_RATES);
72 BV_SET(handicap, H_TARGETS);
73 BV_SET(handicap, H_HUTS);
74 BV_SET(handicap, H_NOPLANES);
75 BV_SET(handicap, H_DIPLOMAT);
76 BV_SET(handicap, H_LIMITEDHUTS);
77 BV_SET(handicap, H_DEFENSIVE);
78 BV_SET(handicap, H_DIPLOMACY);
79 BV_SET(handicap, H_REVOLUTION);
80 BV_SET(handicap, H_EXPANSION);
81 BV_SET(handicap, H_DANGER);
82 BV_SET(handicap, H_CEASEFIRE);
83 BV_SET(handicap, H_NOBRIBE_WF);
84 BV_SET(handicap, H_PRODCHGPEN);
85 break;
86 case AI_LEVEL_EASY:
87 BV_SET(handicap, H_RATES);
88 BV_SET(handicap, H_TARGETS);
89 BV_SET(handicap, H_HUTS);
90 BV_SET(handicap, H_NOPLANES);
91 BV_SET(handicap, H_DIPLOMAT);
92 BV_SET(handicap, H_LIMITEDHUTS);
93 BV_SET(handicap, H_DEFENSIVE);
94 BV_SET(handicap, H_DIPLOMACY);
95 BV_SET(handicap, H_REVOLUTION);
96 BV_SET(handicap, H_EXPANSION);
97 BV_SET(handicap, H_CEASEFIRE);
98 BV_SET(handicap, H_NOBRIBE_WF);
99 break;
100 case AI_LEVEL_NORMAL:
101 BV_SET(handicap, H_RATES);
102 BV_SET(handicap, H_TARGETS);
103 BV_SET(handicap, H_HUTS);
104 BV_SET(handicap, H_DIPLOMAT);
105 BV_SET(handicap, H_CEASEFIRE);
106 BV_SET(handicap, H_NOBRIBE_WF);
107 break;
109 #ifdef FREECIV_DEBUG
110 case AI_LEVEL_EXPERIMENTAL:
111 BV_SET(handicap, H_EXPERIMENTAL);
112 break;
113 #endif /* FREECIV_DEBUG */
115 case AI_LEVEL_CHEATING:
116 BV_SET(handicap, H_RATES);
117 break;
118 case AI_LEVEL_HARD:
119 /* No handicaps */
120 break;
121 case AI_LEVEL_COUNT:
122 fc_assert(level != AI_LEVEL_COUNT);
123 break;
126 return handicap;
129 /**************************************************************************
130 Return the AI fuzziness (0 to 1000) corresponding to a given skill
131 level (1 to 10). See ai_fuzzy() in common/player.c
132 **************************************************************************/
133 static int fuzzy_of_skill_level(enum ai_level level)
135 fc_assert(ai_level_is_valid(level));
137 switch(level) {
138 case AI_LEVEL_AWAY:
139 return 0;
140 case AI_LEVEL_HANDICAPPED:
141 case AI_LEVEL_NOVICE:
142 return 400;
143 case AI_LEVEL_EASY:
144 return 300;
145 case AI_LEVEL_NORMAL:
146 case AI_LEVEL_HARD:
147 case AI_LEVEL_CHEATING:
148 #ifdef FREECIV_DEBUG
149 case AI_LEVEL_EXPERIMENTAL:
150 #endif /* FREECIV_DEBUG */
151 return 0;
152 case AI_LEVEL_COUNT:
153 fc_assert(level != AI_LEVEL_COUNT);
154 return 0;
157 return 0;
160 /**************************************************************************
161 Return the AI's science development cost; a science development cost of 100
162 means that the AI develops science at the same speed as a human; a science
163 development cost of 200 means that the AI develops science at half the speed
164 of a human, and a sceence development cost of 50 means that the AI develops
165 science twice as fast as the human.
166 **************************************************************************/
167 static int science_cost_of_skill_level(enum ai_level level)
169 fc_assert(ai_level_is_valid(level));
171 switch(level) {
172 case AI_LEVEL_AWAY:
173 return 100;
174 case AI_LEVEL_HANDICAPPED:
175 case AI_LEVEL_NOVICE:
176 return 250;
177 case AI_LEVEL_EASY:
178 case AI_LEVEL_NORMAL:
179 case AI_LEVEL_HARD:
180 case AI_LEVEL_CHEATING:
181 #ifdef FREECIV_DEBUG
182 case AI_LEVEL_EXPERIMENTAL:
183 #endif /* FREECIV_DEBUG */
184 return 100;
185 case AI_LEVEL_COUNT:
186 fc_assert(level != AI_LEVEL_COUNT);
187 return 100;
190 return 100;
193 /**************************************************************************
194 Return the AI expansion tendency, a percentage factor to value new cities,
195 compared to defaults. 0 means _never_ build new cities, > 100 means to
196 (over?)value them even more than the default (already expansionistic) AI.
197 **************************************************************************/
198 static int expansionism_of_skill_level(enum ai_level level)
200 fc_assert(ai_level_is_valid(level));
202 switch(level) {
203 case AI_LEVEL_AWAY:
204 return 0;
205 case AI_LEVEL_HANDICAPPED:
206 case AI_LEVEL_NOVICE:
207 case AI_LEVEL_EASY:
208 return 10;
209 case AI_LEVEL_NORMAL:
210 case AI_LEVEL_HARD:
211 case AI_LEVEL_CHEATING:
212 #ifdef FREECIV_DEBUG
213 case AI_LEVEL_EXPERIMENTAL:
214 #endif /* FREECIV_DEBUG */
215 return 100;
216 case AI_LEVEL_COUNT:
217 fc_assert(level != AI_LEVEL_COUNT);
218 return 100;
221 return 100;
224 /**************************************************************************
225 Return the value normal_decision (a boolean), except if the AI is fuzzy,
226 then sometimes flip the value. The intention of this is that instead of
227 if (condition) { action }
228 you can use
229 if (ai_fuzzy(pplayer, condition)) { action }
230 to sometimes flip a decision, to simulate an AI with some confusion,
231 indecisiveness, forgetfulness etc. In practice its often safer to use
232 if (condition && ai_fuzzy(pplayer,1)) { action }
233 for an action which only makes sense if condition holds, but which a
234 fuzzy AI can safely "forget". Note that for a non-fuzzy AI, or for a
235 human player being helped by the AI (eg, autosettlers), you can ignore
236 the "ai_fuzzy(pplayer," part, and read the previous example as:
237 if (condition && 1) { action }
238 --dwp
239 **************************************************************************/
240 bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
242 if (!is_ai(pplayer) || pplayer->ai_common.fuzzy == 0) {
243 return normal_decision;
245 if (fc_rand(1000) >= pplayer->ai_common.fuzzy) {
246 return normal_decision;
248 return !normal_decision;