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
);
67 BV_SET(handicap
, H_PRODCHGPEN
);
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
);
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
);
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
);
110 case AI_LEVEL_EXPERIMENTAL
:
111 BV_SET(handicap
, H_EXPERIMENTAL
);
113 #endif /* FREECIV_DEBUG */
115 case AI_LEVEL_CHEATING
:
116 BV_SET(handicap
, H_RATES
);
122 fc_assert(level
!= AI_LEVEL_COUNT
);
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
));
140 case AI_LEVEL_HANDICAPPED
:
141 case AI_LEVEL_NOVICE
:
145 case AI_LEVEL_NORMAL
:
147 case AI_LEVEL_CHEATING
:
149 case AI_LEVEL_EXPERIMENTAL
:
150 #endif /* FREECIV_DEBUG */
153 fc_assert(level
!= AI_LEVEL_COUNT
);
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
));
174 case AI_LEVEL_HANDICAPPED
:
175 case AI_LEVEL_NOVICE
:
178 case AI_LEVEL_NORMAL
:
180 case AI_LEVEL_CHEATING
:
182 case AI_LEVEL_EXPERIMENTAL
:
183 #endif /* FREECIV_DEBUG */
186 fc_assert(level
!= AI_LEVEL_COUNT
);
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
));
205 case AI_LEVEL_HANDICAPPED
:
206 case AI_LEVEL_NOVICE
:
209 case AI_LEVEL_NORMAL
:
211 case AI_LEVEL_CHEATING
:
213 case AI_LEVEL_EXPERIMENTAL
:
214 #endif /* FREECIV_DEBUG */
217 fc_assert(level
!= AI_LEVEL_COUNT
);
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 }
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 }
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
;