1 | <html>
|
---|
2 | <head>
|
---|
3 | <title>AI Development Manual</title>
|
---|
4 |
|
---|
5 | <style type="text/css">
|
---|
6 | <!--
|
---|
7 | h1 {font-size:20pt;font-family:Arial,Helvetica;color:#C00000;}
|
---|
8 | h2 {font-size:14pt;font-family:Arial,Helvetica;color:#C00000;}
|
---|
9 | h3 {font-size:11pt;font-family:Arial,Helvetica;font-weight:bold;color:#000000;}
|
---|
10 | p {font-size:11pt;font-family:Arial,Helvetica;color:#000000;}
|
---|
11 | p.question {font-size:11pt;font-family:Arial,Helvetica;font-weight:bold;color:#000000;}
|
---|
12 | li {font-size:11pt;font-family:Arial,Helvetica;color:#000000;}
|
---|
13 | td {font-size:11pt;font-family:Arial,Helvetica;color:#000000;vertical-align:top;}
|
---|
14 | td.header {font-size:11pt;font-family:Arial,Helvetica;color:#000000;background-color:#CCCCCC;vertical-align:top;}
|
---|
15 | td.turntime {font-size:11pt;font-family:Arial,Helvetica;color:#000000;background-color:#CCCCFF;vertical-align:top;}
|
---|
16 | //-->
|
---|
17 | </style>
|
---|
18 | </head>
|
---|
19 | <body bgcolor="#FFFFFF" link="#0000FF" vlink="#000080" alink="#FF0000">
|
---|
20 |
|
---|
21 | <h1>AI Development Manual</h1>
|
---|
22 |
|
---|
23 | <p>This is the documentation of the AI development kit that comes with the
|
---|
24 | C-evo standard package. The kit is meant to be a starting point for
|
---|
25 | developing your own AI module for C-evo. Please, always consider that the whole
|
---|
26 | C-evo project is
|
---|
27 | still in the course of development, which counts for this text as well. If you
|
---|
28 | have ideas how to improve the content or the structure of this
|
---|
29 | document, or in case you notice any problem or have a question,
|
---|
30 | <a href="http://c-evo.org/_sg/contact">contact me</a>!
|
---|
31 | There's also a <a href="http://c-evo.org/bb/viewforum.php?f=5">web forum</a> for
|
---|
32 | C-evo AI developers.
|
---|
33 |
|
---|
34 | <p>The programming language of this kit is Pascal. In order to work with it,
|
---|
35 | you need a Pascal compiler capable of generating cross-platform libraries:
|
---|
36 | <ul>
|
---|
37 | <li>Lazarus/FPC, see <a href="https://www.lazarus-ide.org/">lazarus-ide.org</a>.
|
---|
38 | Download latest version for your platform.</li>
|
---|
39 | </ul>
|
---|
40 |
|
---|
41 | <p>Note that using this kit is not the only way to make an AI for C-evo. You can
|
---|
42 | alternatively build an AI DLL from the scratch using your programming
|
---|
43 | language of choice. The DLL interface
|
---|
44 | documentation is to be found <a href="http://c-evo.org/aidev.html">here</a>.
|
---|
45 | There is also another, completely
|
---|
46 | different AI template (using C++) available from the
|
---|
47 | <a href="http://c-evo.org/files">files section</a> of the project homepage.
|
---|
48 |
|
---|
49 | <br><br><h3>Important</h3>
|
---|
50 | <p>Trying to program a C-evo AI makes no sense if you don't have good
|
---|
51 | knowledge in two fields:
|
---|
52 | <ul>
|
---|
53 | <li>C-evo
|
---|
54 | <li>Programming
|
---|
55 | </ul>
|
---|
56 |
|
---|
57 | <br><h3>Files of the Kit</h3>
|
---|
58 | <p><ul>
|
---|
59 | <li><i>AIProject.dpr</i> - The project. When using a command line compiler,
|
---|
60 | compile this file. The code is tailor-made for
|
---|
61 | CustomAI.pas, these two files are the heart of the kit and make sense only
|
---|
62 | together.
|
---|
63 | <li><i>CustomAI.pas</i> - Contains the class TCustomAI, which is the base class of
|
---|
64 | your AI. It encapsulates the server communication. You don't need to
|
---|
65 | change this class, but you have to know its interface well. This
|
---|
66 | interface is the main subject of this manual!
|
---|
67 | <li><i>Protocol.pas</i> - This source file is part of any C-evo related code module,
|
---|
68 | even of the game itself. It defines common values and data structures.
|
---|
69 | Don't change it!
|
---|
70 | <li><i>Switches.pas</i> - Compiler switches which ensure correct and optimized
|
---|
71 | compilation. If you add new files to your AI, I suggest to include this file.
|
---|
72 | <li><i>AIProject.ai.txt</i> - A template for your AI description file, see <a href="#inst">Installing Your AI</a>.
|
---|
73 | </ul>
|
---|
74 |
|
---|
75 |
|
---|
76 | <br><h3>Debug and Release Version</h3>
|
---|
77 |
|
---|
78 | <p>The AI can be compiled in a debug or in a release version. The debug version
|
---|
79 | does no optimization and adds several checks. It should be used during
|
---|
80 | development. The release version of the AI contains only what is necessary for
|
---|
81 | playing with it, thus being smaller and faster. The release version is the one
|
---|
82 | that you should publish.
|
---|
83 |
|
---|
84 | <p>In Lazarus IDE, switch between Debug and Release by the <i>Build mode</i> drop down menu in the project
|
---|
85 | settings.
|
---|
86 |
|
---|
87 | <br><br><h3>Concepts</h3>
|
---|
88 |
|
---|
89 | <p>First, you have to say goodbye to something that you're used to from playing
|
---|
90 | the game: Names. For example, you can't define or even <i>find out</i> the names of your cities.
|
---|
91 | The same counts for the names of your unit classes, not to speak of their
|
---|
92 | pictures. This is because the game core does not support names.
|
---|
93 | All objects are indentified by numbers only. Names and pictures are
|
---|
94 | generated by the user interface in its own estimation, because humans like
|
---|
95 | playing with names and pictures more than with numbers. AI likes numbers more,
|
---|
96 | so be happy that you're spared by the names...
|
---|
97 |
|
---|
98 | <p>The source code files listed above are not meant to be edited.
|
---|
99 | You're doing the
|
---|
100 | AI implementation by creating a new unit <i>AI.pas</i> with a new class
|
---|
101 | <i>TAI</i> derived from
|
---|
102 | <i>TCustomAI</i>. (The names are fixed because AIProject.dpr relies on them.)
|
---|
103 | Your class TAI has nothing to do but to override virtual methods of the
|
---|
104 | base class by own implementations. You can choose which methods to override.
|
---|
105 | Even if your class doesn't implement any
|
---|
106 | method, the compiled AI works. (But, of course, does almost nothing.)
|
---|
107 |
|
---|
108 | <p>Each nation has its own AI object, so inside the TCustomAI and TAI classes
|
---|
109 | it's all about only one nation. The whole AI module is capable of controlling
|
---|
110 | more than one nation, but this is implemented by the kit infrastructure, you
|
---|
111 | don't have to care for it.
|
---|
112 |
|
---|
113 | <p>Apart from that, the code is not object oriented. Units,
|
---|
114 | unit classes (called <i>models</i>), cities and other items are not modelled
|
---|
115 | as Object Pascal classes. Instead, the items of the game are identified by
|
---|
116 | numbers (always zero-based) and managed in arrays of records.
|
---|
117 |
|
---|
118 |
|
---|
119 | <br><br><h2>Playground Coordinates</h2>
|
---|
120 |
|
---|
121 | <p>You have to deal with three types of playground coordinates: location codes,
|
---|
122 | (a,b)-coordinates and vicinity codes. A <i>location code</i> is a unique integer code for a tile.
|
---|
123 | For example, you can use it to find the city that is located at a certain tile,
|
---|
124 | or to find all units which are located inside a certain city (because they have
|
---|
125 | the same location code as the city). All location
|
---|
126 | codes in the range 0..MapSize-1 are valid, all other location
|
---|
127 | codes are invalid. Whenever there is a field or parameter that refers to a single
|
---|
128 | tile resp. location in the communication with the game, it contains a location code.
|
---|
129 |
|
---|
130 | <p>The other coordinate types are <i>relative</i>, they always relate
|
---|
131 | to a base tile. This base tile can be chosen freely.
|
---|
132 | <i>(a,b)-coordinates</i> are universal relative coordinates that are capable of addressing
|
---|
133 | any other tile in relation to the base tile. Such a coordinate is a pair of
|
---|
134 | two components, a and b, which both
|
---|
135 | count the distance to the base tile. The a-component
|
---|
136 | steps south-east and the b-component south-west:
|
---|
137 |
|
---|
138 | <p><img src="_aidev3.gif">
|
---|
139 |
|
---|
140 | <p>The base tile always has the (a,b)-coordinate <i>(0,0)</i>.
|
---|
141 |
|
---|
142 | <p>The other relative coordinates, <i>vicinity codes</i>, can only address the vicinity
|
---|
143 | of the base tile. Vicinity codes are small integers.
|
---|
144 | There are two subtypes: Vicinity-21 and Vicinity-8.
|
---|
145 | Vicinity-21 codes contain the base tile and 20 surrounding tiles, in a shape
|
---|
146 | equal to a city exploitation radius or to an enhanced unit visibility range.
|
---|
147 | The vicinity has 21 tiles, they have codes in the range 1..26. The base tile
|
---|
148 | has the code 13 (= constant <i>CityOwnTile</i>). One application of Vicinity-21
|
---|
149 | is addressing tiles inside a city's exploitation radius - the city own tile is
|
---|
150 | the base tile then. Sometimes, the codes
|
---|
151 | are used as indices for bit arrays. For example, if the exploited tiles
|
---|
152 | of a city are 11000000000010 (binary), this means that the city exploits the
|
---|
153 | tiles with the Vicinity-21 codes 1, 12 and 13:
|
---|
154 |
|
---|
155 | <p><img src="_aidev4.gif">
|
---|
156 |
|
---|
157 | <p>Vicinity-8 codes are the most limited coordinates, they
|
---|
158 | address only the 8 adjacent tiles of the base tile. The base tile
|
---|
159 | itself has <i>no</i> Vicinity-8 code:
|
---|
160 |
|
---|
161 | <p><img src="_aidev5.gif">
|
---|
162 |
|
---|
163 | <p>(a,b)-coordinates and vicinity-8 codes are introduced by this kit in order
|
---|
164 | to make AI programming
|
---|
165 | easier. You must not use them, it's up to you which coordinate types to use in
|
---|
166 | which AI calculation. However, they can be very
|
---|
167 | valuable for AI algorithms that consider
|
---|
168 | geographic neighbourhood and distances. The Sample AI contains several
|
---|
169 | applications that you can take for examples.
|
---|
170 |
|
---|
171 | <p>The unit <i>CustomAI</i> provides some conversion functions between the
|
---|
172 | different coordinate types:
|
---|
173 |
|
---|
174 | <p><i>procedure ab_to_Loc(Loc0,a,b: integer; var Loc: integer);</i>
|
---|
175 | <br>This function calculates the location code of the tile which has the
|
---|
176 | passed (a,b)-coordinates
|
---|
177 | in relation to the base tile with location code Loc0.
|
---|
178 | If there is no such tile because the relative coordinates are beyond the
|
---|
179 | northern resp. southern end of the world, the code returned is less than 0 resp. greater than
|
---|
180 | MapSize-1. The calculation respects the cylindrical world (no left or right end).
|
---|
181 |
|
---|
182 | <p><i>procedure Loc_to_ab(Loc0,Loc: integer; var a,b: integer);</i>
|
---|
183 | <br>This function calculates the (a,b)-coordinates of the tile with
|
---|
184 | location code <i>Loc</i>
|
---|
185 | in relation to the base tile with location code Loc0.
|
---|
186 | Because of the cylindrical world, this calculation is ambiguous. The function
|
---|
187 | always returns the absolutely smallest possible values for a and b, e.g. (-1,1)
|
---|
188 | instead of (lx-1,-lx+1).
|
---|
189 |
|
---|
190 | <p><i>procedure ab_to_V8(a,b: integer; var V8: integer);</i>
|
---|
191 | <br>Converts an (a,b)-coordinate into a Vicinity-8 code.
|
---|
192 |
|
---|
193 | <p><i>procedure V8_to_ab(V8: integer; var a,b: integer);</i>
|
---|
194 | <br>Converts a Vicinity-8 code into an (a,b)-coordinate.
|
---|
195 |
|
---|
196 | <p><i>procedure ab_to_V21(a,b: integer; var V21: integer);</i>
|
---|
197 | <br>Converts an (a,b)-coordinate into a Vicinity-21 code.
|
---|
198 |
|
---|
199 | <p><i>procedure V21_to_ab(V21: integer; var a,b: integer);</i>
|
---|
200 | <br>Converts a Vicinity-21 code into an (a,b)-coordinate.
|
---|
201 |
|
---|
202 | <p><i>procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);</i>
|
---|
203 | <br>Returns the location codes of <i>all</i> tiles adjacent to the base tile
|
---|
204 | at Loc0. The array index in VicinityLoc is the Vicinity-8 code. Tiles beyound
|
---|
205 | a pole are indicated by an invalid location code.
|
---|
206 |
|
---|
207 | <p><i>procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);</i>
|
---|
208 | <br>Returns the location codes of <i>all</i> tiles in the 21-tile vicinity
|
---|
209 | of the base tile at Loc0. The array index in VicinityLoc is the
|
---|
210 | Vicinity-21 code. Array indices which are not a valid Vicinity-21 code are set
|
---|
211 | to an invalid location code. The same counts for tiles beyound a pole.
|
---|
212 |
|
---|
213 |
|
---|
214 | <p><br><h2>The Overridables</h2>
|
---|
215 |
|
---|
216 | <p>There are three ways of control and information flow between the game and
|
---|
217 | your AI: <i>Overridables</i>, <i>Functions</i> and the <i>ReadOnly-block</i>,
|
---|
218 | described within this section and the following ones.
|
---|
219 |
|
---|
220 | <p>A few of the methods of TCustomAI are overridable. By overriding such a
|
---|
221 | method, you can handle a call to your AI, for example the call to make your
|
---|
222 | turn. Each overridable has already a default implementation in TCustomAI
|
---|
223 | that remains
|
---|
224 | effective if you do not override it in TAI. This default implementation
|
---|
225 | does <i>nothing</i>.
|
---|
226 |
|
---|
227 | <p>The overridables <i>WantNegotiation</i> and <i>DoNegotiation</i> are
|
---|
228 | described under <a href="#dip">Diplomacy</a>. Two others,
|
---|
229 | <i>SetDataDefaults</i> and <i>SetDataRandom</i>, will be explained in the section
|
---|
230 | <a href="#save">Saving Data</a>. Apart from those four, the overridables are:
|
---|
231 |
|
---|
232 | <p><table border cellspacing=0 cellpadding=3>
|
---|
233 | <tr><td class="header">Overridable</td><td class="header">Event</td><td class="header">To do</td></tr>
|
---|
234 | <tr><td class="turntime">DoTurn</td><td>It's your turn.</td>
|
---|
235 | <td>Move units, manage cities etc.</td></tr>
|
---|
236 | <tr><td class="turntime">ChooseResearchAdvance</td><td>Research completed.</td>
|
---|
237 | <td>Return next advance to research. Prerequisites must be researched!
|
---|
238 | Return -1 for random choice.
|
---|
239 | If you return <i>adMilitary</i>, you must define the model to develop within this
|
---|
240 | overridable.</td></tr>
|
---|
241 | <tr><td class="turntime">ChooseStealAdvance</td><td>Enemy city captured while owning the Temple of Zeus.</td>
|
---|
242 | <td>Return advance to steal from captured city. Return -1 for random choice.</td></tr>
|
---|
243 | <tr><td class="turntime">ChooseGovernment</td><td>Anarchy is over.</td><td>Return desired new government form.</td></tr>
|
---|
244 | <tr><td class="turntime">OnNegoRejected_CancelTreaty</td><td>Other nation has rejected your contact request. The <i>Opponent</i> field tells which nation that was.</td><td>Return <i>true</i> if you want to cancel the treaty that you have with this nation.</td></tr>
|
---|
245 | <tr><td>OnBeforeEnemyAttack</td><td>Enemy unit will attack you. This unit is not necessarily in your enemy unit list, because it might be covered by a stronger unit at the same tile. Get information about the unit from the UnitInfo parameter of the overridable. Additional parameters also tell the exact outcome of the battle, although it has not yet happened.
|
---|
246 | <br>This overridable is also called when enemies bombard one of your cities or expel a commando.</td><td>Whatever you like, but don't call in-turn functions.</td></tr>
|
---|
247 | <tr><td>OnAfterEnemyAttack</td><td>Always follows to OnBeforeEnemyAttack. Attack has been performed now, either the attacking unit or your defender is destroyed. An attacked city might be destroyed.</td><td>Whatever you like, but don't call in-turn functions.</td></tr>
|
---|
248 | <tr><td>OnBeforeEnemyCapture</td><td>Enemy unit is going to capture one of your cities. Capturing unit is already removed from origin tile, thus not in your enemy unit list, only specified by the UnitInfo parameter of the overridable. The city is still in your city list.</td><td>Whatever you like, but don't call in-turn functions.</td></tr>
|
---|
249 | <tr><td>OnAfterEnemyCapture</td><td>Always follows to OnBeforeEnemyCapture. Capture has been performed now, city is destroyed or in enemy city list, unit is in enemy unit list and located at city tile.</td><td>Whatever you like, but don't call in-turn functions.</td></tr>
|
---|
250 | </table>
|
---|
251 |
|
---|
252 | <p>The overridables marked blue are the <i>in-turn</i> overridables, only they can call in-turn functions.
|
---|
253 |
|
---|
254 |
|
---|
255 | <p><br><h2>The Functions</h2>
|
---|
256 |
|
---|
257 | <p>Functions are the tools to implement the play of the nation,
|
---|
258 | call them in order to give commands like moving a unit etc.
|
---|
259 | Functions are methods declared by the base class TCustomAI.
|
---|
260 |
|
---|
261 | <p>Most of the functions return a server return code as result. These return
|
---|
262 | codes are described in the file Protocol.pas. If this code doesn't have the <i>rExecuted</i> bit set,
|
---|
263 | it's an error code, means the function has not been executed. Common
|
---|
264 | server return codes are:
|
---|
265 | <br><i>eNoTurn</i> - function can not be called from this overridable
|
---|
266 | <br><i>eInvalid</i> - you have called the function with invalid parameters
|
---|
267 | <br><i>eViolation</i> - function can't be executed, because this operation does
|
---|
268 | not comply with the rules of the game
|
---|
269 | <br><i>eNotChanged</i> - function was executed, but didn't change anything
|
---|
270 | <br>Other return codes are function-specific and listed below.
|
---|
271 |
|
---|
272 | <p>All available functions are described in the tables below.
|
---|
273 | Parameters are integers except where stated different.
|
---|
274 | Most functions can only be called from in-turn overridables. These functions are
|
---|
275 | marked blue in the table.
|
---|
276 |
|
---|
277 |
|
---|
278 | <br><br><h3>General Functions</h3>
|
---|
279 | <p><table border cellspacing=0 cellpadding=3>
|
---|
280 | <tr><td class="header">Function</td><td class="header">Parameters</td><td class="header">Usage</td></tr>
|
---|
281 |
|
---|
282 | <tr><td>IsResearched</td><td>Advance</td>
|
---|
283 | <td>Returns whether a specific advance is already
|
---|
284 | researched or not. The function returns <i>false</i> also for advances that are
|
---|
285 | traded from other nations but not researched yet (tsSeen).</td></tr>
|
---|
286 |
|
---|
287 | <tr><td>ResearchCost</td><td>-</td><td>Returns the research points necessary to complete the current research, independent on the points that are already collected (RO.Research).</td></tr>
|
---|
288 |
|
---|
289 | <tr><td>ChangeAttitude</td><td>Nation<br>Attitude</td><td>Change your nation's attitude to another nation.<br>Return code: eOK</td></tr>
|
---|
290 |
|
---|
291 | <tr><td class="turntime">Revolution</td><td>-</td><td>Do the revolution!<br>Return code: eOK</td></tr>
|
---|
292 |
|
---|
293 | <tr><td class="turntime">ChangeRates</td><td>Tax<br>Lux</td><td>Change tax and luxury rate, both must be multiples of 10.<br>Return code: eOK</td></tr>
|
---|
294 |
|
---|
295 | <tr><td class="turntime">PrepareNewModel</td><td>Domain</td><td>Prepares military research. Pass the domain of the new model that you want to develop.
|
---|
296 | <br>Makes only sense from overridable <i>ChooseResearchAdvance</i>!<br>Return Codes: eOK, eNoPreq</td></tr>
|
---|
297 |
|
---|
298 | <tr><td class="turntime">SetNewModelFeature</td><td>Feature<br>Count</td><td>Lets you specify a feature or capacity of the new model that you want to develop. PrepareNewModel must have been called before in this turn! To turn on binary features like Stealth, pass 1 as count. The result of the change, including strength and cost, can be read from RO.DevModel.
|
---|
299 | <br>Makes only sense from overridable <i>ChooseResearchAdvance</i>!<br>Return Codes: eOK, eNoModel, eNoPreq, eDomainMismatch</td></tr>
|
---|
300 |
|
---|
301 | <tr><td class="turntime">AdvanceResearchable</td><td>Advance</td><td>Returns true if the specified advanced can be researched now.<br>Makes only sense from overridable <i>ChooseResearchAdvance</i>!</td></tr>
|
---|
302 |
|
---|
303 | <tr><td class="turntime">AdvanceStealable</td><td>Advance</td><td>Returns true if the specified advanced can be stolen now.<br>Makes only sense from overridable <i>ChooseStealAdvance</i>!</td></tr>
|
---|
304 | </table>
|
---|
305 |
|
---|
306 |
|
---|
307 | <br><br><h3>Unit Functions</h3>
|
---|
308 | <p>Most of these functions have an integer <i>uix</i> as first parameter.
|
---|
309 | These functions can only be applied to one of your units, not to foreign
|
---|
310 | ones. The uix
|
---|
311 | parameter specifies the unit which to apply the function to and is not
|
---|
312 | explicitely listed in the table below.
|
---|
313 | <p><table border cellspacing=0 cellpadding=3>
|
---|
314 | <tr><td class="header">Function (Unit_...)</td><td class="header">Parameters</td><td class="header">Usage</td></tr>
|
---|
315 |
|
---|
316 | <tr><td>FindMyDefender</td><td>Loc<br>var uix</td><td>Determines, which of your units would defend the tile with the specified location, when attacked. The unit index is returned in uix. It's a value <0 when your nation has no units at this location.</td></tr>
|
---|
317 |
|
---|
318 | <tr><td>FindEnemyDefender</td><td>Loc<br>var euix</td><td>Determines, which enemy unit would defend the tile with the specified location, when attacked. The enemy unit index is returned in euix. It's a value <0 when there is no known enemy unit at this location.</td></tr>
|
---|
319 |
|
---|
320 | <tr><td class="turntime">Move</td><td>ToLoc</td><td>Move unit to another tile, as fast as possible. Be aware that the unit can die during this operation due to hostile terrain. This is indicated by the function return code having the <i>rUnitRemoved</i> flag set.
|
---|
321 | Usually, the unit is moved to the specified tile (ToLoc). Only in the following two situations, it's moved to the most convenient adjacent tile:
|
---|
322 | <br>- ToLoc is occupied by a unit of another nation
|
---|
323 | <br>- an undefended foreign city is at ToLoc, but the unit is not able to capture cities
|
---|
324 | <br>So you can also use this function in preparation of attacks, bombardments and covert operations.
|
---|
325 | <br>If it takes more than one turn to reach the destination, the unit starts movement but will not remember the destination in the next turn. You have to call Unit_Move again in each turn, until the unit reaches the destination tile.
|
---|
326 | The return code <i>eNoWay</i> tells that the unit can not at all move there on its own.
|
---|
327 | <br>If formerly unknown foreign units or cities appear along the way, the function stops immediately, even if the destination is not reached yet.
|
---|
328 | <br>Alternatively to a location code, you can pass <i>maNextCity</i> as destination, which causes the unit to move to the nearest of your cities.
|
---|
329 | <br>Return codes (complete move done): eOK+rLocationReached, eOK+rMoreTurns, eEnemySpotted+rLocationReached, eEnemySpotted+rMoreTurns, eLoaded+rLocationReached, eLoaded+rMoreTurns
|
---|
330 | <br>Return codes (move not or not completely done): eNoWay, eEnemySpotted, eDied, eEnemySpotted_Died, eHiddenUnit, eStealthUnit, eZOC_EnemySpotted, eNoCapturer</td></tr>
|
---|
331 |
|
---|
332 | <tr><td class="turntime">Attack</td><td>ToLoc</td><td>Let the unit attack an enemy unit, bombard an enemy city or expel a commando at the specified <i>adjacent</i> tile.
|
---|
333 | <br>Return codes: eLost, eWon, eBloody, eBombarded, eExpelled, eHiddenUnit, eStealthUnit, eNoTime_Attack, eNoTime_Bombard, eNoTime_Expel, eDomainMismatch, eTreaty, eNoBombarder</td></tr>
|
---|
334 |
|
---|
335 | <tr><td class="turntime">DoMission</td><td>MissionType<br>ToLoc</td><td>Let special commando do covert operation in <i>adjacent</i> foreign city at ToLoc.
|
---|
336 | <br>Return codes: eMissionDone, eNoTime_Move, eTreaty</td></tr>
|
---|
337 |
|
---|
338 | <tr><td class="turntime">MoveForecast</td><td>ToLoc<br>var RemainingMovement</td><td>Calculates the movement points the unit would have left for the current turn after moving to ToLoc. Returns false if the unit can't reach this tile within the turn.</td></tr>
|
---|
339 |
|
---|
340 | <tr><td class="turntime">AttackForecast</td><td>ToLoc<br>AttackMovement<br>var RemainingHealth</td><td>Calculates the health that the unit would have left after attacking the enemy unit at ToLoc. The movement points left for the attack must be specified, values <100 reduce the attack power. If the attacker would be lost, the calculated health value is the negative remaining health of the defender.
|
---|
341 | <br>Returning false indicates that this unit can't attack there.</td></tr>
|
---|
342 |
|
---|
343 | <tr><td class="turntime">DefenseForecast</td><td>euix<br>ToLoc<br>var RemainingHealth</td><td>Calculates the health that the defender at ToLoc would have left after an attack of the enemy unit with index <i>euix</i> in the enemy unit list. If the defender would be lost, the calculated health value is the negative remaining health of the attacker.
|
---|
344 | <br>Returning false indicates that this unit can't attack there.</td></tr>
|
---|
345 |
|
---|
346 | <tr><td class="turntime">Disband</td><td>-</td><td>Disband the unit. If it's located in a city with a project it can be utilized for, utilize it.
|
---|
347 | <br>Return codes: eUtilized, eRemoved</td></tr>
|
---|
348 |
|
---|
349 | <tr><td class="turntime">StartJob</td><td>NewJob</td><td>Let settlers start/change terrain improvement job. Pass <i>jNone</i> to cancel the current job only. Be aware that the unit can die during this operation due to hostile terrain. This is indicated by the function return code having the <i>rUnitRemoved</i> flag set.
|
---|
350 | <br>Return Codes: eOK, eDied, eJobDone, eJobDone_Died, eCity, eNoPreq, eTreaty, eDeadLands, eNoCityTerrain, eNoBridgeBuilding</td></tr>
|
---|
351 |
|
---|
352 | <tr><td class="turntime">SetHomeHere</td><td>-</td><td>Change the home city of the unit to the city it's located in.<br>Return code: eOK</td></tr>
|
---|
353 |
|
---|
354 | <tr><td class="turntime">Load</td><td>-</td><td>Load the unit to a transport unit at the same tile.<br>Return codes: eOK, eNoTime_Load, eNoLoadCapacity</td></tr>
|
---|
355 |
|
---|
356 | <tr><td class="turntime">Unload</td><td>-</td><td>Unload the unit from its transport.<br>Return codes: eOK, eNoTime_Load, eDomainMismatch</td></tr>
|
---|
357 |
|
---|
358 | <tr><td class="turntime">SelectTransport</td><td>-</td><td>Prefer this transport when loading units. Voids any former call to this function.<br>Return codes: eOK</td></tr>
|
---|
359 |
|
---|
360 | <tr><td class="turntime">AddToCity</td><td>-</td><td>Add settlers, slaves or conscripts to the city they're located in.<br>Return codes: eOK, eMaxSize</td></tr>
|
---|
361 |
|
---|
362 | </table>
|
---|
363 |
|
---|
364 |
|
---|
365 | <br><br><h3>City Functions</h3>
|
---|
366 | <p>Most of these functions have an integer <i>cix</i> as first parameter.
|
---|
367 | These functions can only be applied to one of your cities, not to foreign
|
---|
368 | ones. The cix parameter specifies the city which to apply the function to
|
---|
369 | and is not explicitely listed in the table below.
|
---|
370 | <p><table border cellspacing=0 cellpadding=3>
|
---|
371 | <tr><td class="header">Function (City_...)</td><td class="header">Parameters</td><td class="header">Usage</td></tr>
|
---|
372 |
|
---|
373 | <tr><td>FindMyCity</td><td>Loc<br>var cix</td><td>Find the city at the specified location. The city index is returned in cix. It's a value <0 when your nation has no city at this location.</td></tr>
|
---|
374 |
|
---|
375 | <tr><td>FindEnemyCity</td><td>Loc<br>var ecix</td><td>Find enemy city at the specified location. The enemy city index is returned in ecix. It's a value <0 when there is no known enemy city at this location.</td></tr>
|
---|
376 |
|
---|
377 | <tr><td>HasProject</td><td>-</td><td>Returns true whenever the city is producing something different from trade goods.</td></tr>
|
---|
378 |
|
---|
379 | <tr><td>CurrentImprovementProject</td><td>-</td><td>Returns the city improvement, national project or wonder that is currently in production. If the city is producing a unit or trade goods, the function returns a value <0.</td></tr>
|
---|
380 |
|
---|
381 | <tr><td>CurrentUnitProject</td><td>-</td><td>Returns the model index of the unit that is currently in production. If the city is not producing a unit, the function returns a value <0.</td></tr>
|
---|
382 |
|
---|
383 | <tr><td class="turntime">GetTileInfo</td><td>TileLoc<br>var TileInfo: TTileInfo</td>
|
---|
384 | <td>Fills the fields of TileInfo with the resource production of this tile when it would be exploited by this city.<br>Return code: eOK</td></tr>
|
---|
385 |
|
---|
386 | <tr><td class="turntime">GetReport</td><td>var Report: TCityReport</td>
|
---|
387 | <td>Get a detailed report of this city. (Similar to what a player sees on the city screen.) The information is returned in the fields of <i>Report</i>:
|
---|
388 | <br><i>Working</i> - number of working citizens
|
---|
389 | <br><i>Happy</i> - number of happy citizens, can be higher than number of working citizens if more working citizens would be happy
|
---|
390 | <br><i>FoodRep, ProdRep, Trade</i> - total per turn collected food, material and trade points after improvement effects
|
---|
391 | <br><i>PollRep</i> - pollution
|
---|
392 | <br><i>Corruption, Tax, Lux, Science</i> - corruption, tax, luxury and science output of city
|
---|
393 | <br><i>Support, Eaten</i> - production and food taken for citizens and unit support
|
---|
394 | <br><i>Storage</i> - size of food storage
|
---|
395 | <br><i>Deployed</i> - number of deployed units
|
---|
396 | <br>Return code: eOK</td></tr>
|
---|
397 |
|
---|
398 | <tr><td class="turntime">GetHypoReport</td><td>HypoTiles<br>HypoTax<br>HypoLux<br>var Report: TCityReport</td>
|
---|
399 | <td>Same as City_GetReport, but hypothecial: Report as if the city would exploit different
|
---|
400 | tiles, and if tax and luxury rates were different.
|
---|
401 | <br>Calling City_GetHypoReport(cix, MyCity[cix].Tiles, RO.TaxRate, RO.LuxRate) results in the same report as City_GetReport.</td></tr>
|
---|
402 |
|
---|
403 | <tr><td class="turntime">GetAreaInfo</td><td>var AreaInfo: TCityAreaInfo</td><td>Fills AreaInfo with availability information about all tiles in the exploitation radius of the city. Index in AreaInfo.Available is the Vicinity-21 code.<br>Return code: eOK</td></tr>
|
---|
404 |
|
---|
405 | <tr><td class="turntime">StartUnitProduction</td><td>mix</td><td>Change city's project to a unit with the specified model index.<br>Return code: eOK</td></tr>
|
---|
406 |
|
---|
407 | <tr><td class="turntime">StartEmigration</td><td>mix<br>AllowDisbandCity: boolean<br>AsConscripts: boolean</td><td>Same as StartUnitProduction, but additionally allows producing conscripts and/or disbanding the city.</td></tr>
|
---|
408 |
|
---|
409 | <tr><td class="turntime">StartImprovement</td><td>iix</td><td>Change city's project to city improvement, national project or wonder.<br>Return codes: eOK, eNoPreq, eObsolete</td></tr>
|
---|
410 |
|
---|
411 | <tr><td class="turntime">Improvable</td><td>iix</td><td>Returns true if this improvement, national project or wonder can be built in this city. This includes the check if this improvement already exists in this city (resp. in the world in case of a wonder).</td></tr>
|
---|
412 |
|
---|
413 | <tr><td class="turntime">StopProduction</td><td>-</td><td>Cancel the city's project, change the collected material to money and let the city produce trade goods instead.<br>Return code: eOK</td></tr>
|
---|
414 |
|
---|
415 | <tr><td class="turntime">BuyProject</td><td>-</td><td>Buy the city's project, so that it's complete the next turn.<br>Return codes: eOK, eOutOfControl</td></tr>
|
---|
416 |
|
---|
417 | <tr><td class="turntime">SellImprovement</td><td>iix</td><td>Sell the specified city improvement or national project.<br>Return codes: eOK, eOutOfControl, eOnlyOnce</td></tr>
|
---|
418 |
|
---|
419 | <tr><td class="turntime">RebuildImprovement</td><td>iix</td><td>Rebuild the specified city improvement or national project for the building currently in production.<br>Return codes: eOK, eOutOfControl, eOnlyOnce</td></tr>
|
---|
420 |
|
---|
421 | <tr><td class="turntime">SetTiles</td><td>NewTiles</td><td>Set tiles to exploit by a city. The parameter <i>NewTiles</i> is a bit array with the Vicinity-21 code as index. Currently unexploited tiles with 1-bits will be exploited, currently exploited tiles with 0-bits will be unexploited.
|
---|
422 | <br>This function does not work partially. If not all tiles can be set as requested, the function does nothing and returns an error.<br>Return codes: eOK, eTileNotAvailable, eNoWorkerAvailable</td></tr>
|
---|
423 |
|
---|
424 | <tr><td class="turntime">OptimizeTiles</td><td>ResourceWeights</td><td>Optimize the exploitation of tiles in the city area. Food supply and unit support are ensured, if possible.
|
---|
425 | Extra food, material, tax and science are maximized according to the parameter, which can be one of the values below "resource weights" in Protocol.pas. The optimization also works in connection with Luxury or Michelangelo's Chapel.</td></tr>
|
---|
426 |
|
---|
427 | </table>
|
---|
428 |
|
---|
429 |
|
---|
430 | <br><br><h3>Negotiation Functions</h3>
|
---|
431 | <p><table border cellspacing=0 cellpadding=3>
|
---|
432 | <tr><td class="header">Function</td><td class="header">Parameters</td><td class="header">Usage</td></tr>
|
---|
433 | <tr><td>Nego_CheckMyAction</td><td>-</td><td>Lets you check whether the currently set MyAction/MyOffer is valid. The return value does not contain the <i>rExecuted</i> flags if not.<br>Only allowed from overridable <i>DoNegotiation</i>!</td></tr>
|
---|
434 | </table>
|
---|
435 |
|
---|
436 |
|
---|
437 | <a name="debug"></a>
|
---|
438 | <br><br><h3>Development Support Functions</h3>
|
---|
439 | <p><table border cellspacing=0 cellpadding=3>
|
---|
440 | <tr><td>DebugMessage</td><td>Level<br>Text: string</td><td>Display an AI debug message. Note that debug messages are turned off by default. Open the debug message popup menu with a right mouse click into the AI debug message window, choose there which message levels to display.</td></tr>
|
---|
441 | <tr><td>SetDebugMap</td><td>var DebugMap</td><td>Set a map of debug numbers, one for each tile. In the game, you can turn the number display on using the menu. The values are directly read from the array (32 bit) passed to this function everytime the map display is updated, means you only have to call this function once.<br>Never set the debug map to a local variable, only to memory that lives as long as your AI, e.g. fields of the AI object.</td></tr>
|
---|
442 | </table>
|
---|
443 |
|
---|
444 |
|
---|
445 | <p><br><h2>The ReadOnly-Block</h2>
|
---|
446 |
|
---|
447 | <p>The TCustomAI class contains a field <i>RO</i>, which is a pointer to a
|
---|
448 | complex data structure. This data structure contains a lot of information
|
---|
449 | about your nation and its view of the world. This is an important source of
|
---|
450 | information for you, but it is read-only! The data is managed by the game,
|
---|
451 | so please never change it directly by writing it. This would
|
---|
452 | mean to cheat! This counts for all structures and fields pointed directly or
|
---|
453 | indirectly by RO, as well as for the fields <i>Map</i>, <i>MyUnit</i>,
|
---|
454 | <i>MyCity</i> and <i>MyModel</i> of
|
---|
455 | the AI class, which are actually nothing but shortcuts for parts of RO.
|
---|
456 | The only exception to the read-only rule are the fields <i>Data</i>
|
---|
457 | and <i>Status</i>, which are described under <a href="#save">Saving Data</a>.
|
---|
458 |
|
---|
459 | <p>The data structure which the RO pointer refers to has the type
|
---|
460 | <i>TPlayerContext</i>, defined in the file <i>Protocol.pas</i>.
|
---|
461 | Please see this file for the definition details of this structure and the
|
---|
462 | structures that are pointed to from it. The fields of these structures are
|
---|
463 | commented inside the Protocol.pas.
|
---|
464 |
|
---|
465 | <br><br><h3>Unit and City Lists: Beware of Gaps!</h3>
|
---|
466 | <p>The unit and city lists (MyUnit/RO.Un, MyCity/RO.City, RO.EnemyUn,
|
---|
467 | RO.EnemyCity) might have gaps, means non-existing objects at an array position
|
---|
468 | between existing objects. Such non-existing objects are indicated by a
|
---|
469 | Location <0. Commands will not work for them. Furthermore, the
|
---|
470 | items in these lists might change their position within the list
|
---|
471 | whenever the server prepares your turn. So you can <i>not</i>
|
---|
472 | identify cities and units of former turns by their array index! (You could
|
---|
473 | use their ID instead.) The enemy units might even
|
---|
474 | change their indices while the enemies are moving. However, indices never
|
---|
475 | change while your AI is processing an overridable.
|
---|
476 |
|
---|
477 |
|
---|
478 | <br><br><h3>The Map</h3>
|
---|
479 | <p>The playground map information (AI.Map or AI.RO.Map) is represented
|
---|
480 | as a list of 32-bit values. The value at array index x provides information
|
---|
481 | about the tile at location x. In order to save memory, several blocks of bits
|
---|
482 | of these 32-bit values are used for different purpose. Means,
|
---|
483 | you can <i>not</i> use the 32-bit value of a tile directly, you always have to
|
---|
484 | extract the bits containing the information that you need. You're doing this
|
---|
485 | by applying an AND operation with the appropriate bit mask or single flag to the value.
|
---|
486 | The table below shows the bit structure of the map values in detail
|
---|
487 | and gives some examples of usage:
|
---|
488 |
|
---|
489 | <p><table border cellspacing=0 cellpadding=3>
|
---|
490 | <tr><td class="header">Bits</td><td class="header">Bit mask/flag</td><td class="header">Content</td><td class="header">Example of usage: test whether tile at location...</td></tr>
|
---|
491 | <tr><td>0..4</td><td>fTerrain</td>
|
---|
492 | <td>terrain type if tile is already discovered,<br>fUNKNOWN if not</td>
|
---|
493 | <td>...is ground tile:<br><i>if (Map[Loc] and fTerrain)>=fGrass</i></td></tr>
|
---|
494 | <tr><td>5..6</td><td>fSpecial</td>
|
---|
495 | <td>1 or 2 if tile has special resource,<br>0 if not</td>
|
---|
496 | <td>...is a wheat tile:
|
---|
497 | <br><i>if ((Map[Loc] and fTerrain)=fPrairie) and ((Map[Loc] and fSpecial)=fSpecial1)</i>
|
---|
498 | <br>or shorter:
|
---|
499 | <br><i>if (Map[Loc] and (fTerrain or fSpecial))=(fPrairie or fSpecial1)</i></td></tr>
|
---|
500 | <tr><td>7</td><td>fRiver</td><td>river</td><td> </td></tr>
|
---|
501 | <tr><td>8</td><td>fRoad</td><td>road</td>
|
---|
502 | <td rowspan=2>...has road or railroad:<br><i>if (Map[Loc] and (fRoad or fRR))<>0</i></td></tr>
|
---|
503 | <tr><td>9</td><td>fRR</td><td>railroad</td></tr>
|
---|
504 | <tr><td>10</td><td>fCanal</td><td>canal</td><td> </td></tr>
|
---|
505 | <tr><td>11</td><td>fPoll</td><td>pollution</td><td> </td></tr>
|
---|
506 | <tr><td>12..15</td><td>fTerImp</td>
|
---|
507 | <td>terrain improvement code if tile has<br>Irrigation, Farm, Mine, Fort or Base,<br>tiNone if not</td>
|
---|
508 | <td>...has fort:<br><i>if (Map[Loc] and fTerImp)=tiFort</i></td></tr>
|
---|
509 | <tr><td>16</td><td>fGrWall</td><td>tile is protected by great wall</td><td> </td></tr>
|
---|
510 | <tr><td>17</td><td>fSpiedOut</td><td>enemy city resp. enemy unit stack has been investigated by a special commando or spy plane</td><td> </td></tr>
|
---|
511 | <tr><td>18</td><td>fStealthUnit</td><td>tile is occupied by enemy stealth plane</td><td> </td></tr>
|
---|
512 | <tr><td>19</td><td>fHiddenUnit</td><td>tile is occupied by enemy submarine</td><td> </td></tr>
|
---|
513 | <tr><td>20</td><td>fObserved</td><td>tile information is from this turn</td><td> </td></tr>
|
---|
514 | <tr><td>21</td><td>fOwned</td><td>unit/city here is own one</td>
|
---|
515 | <td rowspan=3>...has foreign unit:
|
---|
516 | <br><i>if ((Map[Loc] and fUnit)<>0) and ((Map[Loc] and fOwned)=0)</i>
|
---|
517 | <br>or shorter:
|
---|
518 | <br><i>if (Map[Loc] and (fUnit or fOwned))=fUnit</i></td></tr>
|
---|
519 | <tr><td>22</td><td>fUnit</td><td>unit present</td></tr>
|
---|
520 | <tr><td>23</td><td>fCity</td><td>city present</td></tr>
|
---|
521 | <tr><td>24</td><td>fDeadLands</td><td>dead lands</td><td> </td></tr>
|
---|
522 | <tr><td>25..26</td><td>fModern</td>
|
---|
523 | <td>fCobalt, fUranium or fMercury,<br>0 if no modern resource</td>
|
---|
524 | <td>...has a modern resource:<br><i>if (Map[Loc] and fModern)<>0</i></td></tr>
|
---|
525 | <tr><td>28</td><td>fOwnZoCUnit</td><td>own ZoC unit present at this tile</td><td> </td></tr>
|
---|
526 | <tr><td class="turntime">29</td><td class="turntime">fInEnemyZoC</td><td>tile is in zone of control of known unit of foreign nation that you're not allied with
|
---|
527 | <br>this information is only valid during your own turn</td>
|
---|
528 | <td>test whether at least one of two tiles is not in foreign zone of control:
|
---|
529 | <br><i>if ((Map[Loc1] and fEnemyControl)=0) or ((Map[Loc2] and fEnemyControl)=0)</i>
|
---|
530 | <br>or shorter:
|
---|
531 | <br><i>if (Map[Loc1] and Map [Loc2] and fEnemyControl)=0</i></td></tr>
|
---|
532 | <tr><td class="turntime">30</td><td class="turntime">fPeace</td><td>tile belongs to territory of nation that you're in peace with but not allied
|
---|
533 | <br>this information is only valid during your own turn</td><td> </td></tr>
|
---|
534 | </table>
|
---|
535 |
|
---|
536 | <p>Concerning terrain types, note that there are small differences between the
|
---|
537 | software internal and the player view. <i>Jungle</i> and <i>Forest</i> are the same
|
---|
538 | internally, named forest. <i>Plains</i> do not exist as terrain type, they are grassland with a
|
---|
539 | special resource of type 1 (fSpecial1). <i>Dead Lands</i> also not exist as
|
---|
540 | terrain type. They always have the terrain type <i>Desert</i>, also having the same
|
---|
541 | properties as desert in every aspect, except that settlers can't work there.
|
---|
542 | To distinguish dead land tiles from desert, these tiles have the <i>fDeadLands</i>
|
---|
543 | flag set. The special resources of dead lands (modern resources) are specified
|
---|
544 | by the fModern bits, while the fSpecial bits are always 0.
|
---|
545 |
|
---|
546 |
|
---|
547 | <a name="dip"></a>
|
---|
548 | <p><br><h2>Diplomacy</h2>
|
---|
549 |
|
---|
550 | <p>The diplomacy implementation of an AI based on this kit has two parts. One part (overridable
|
---|
551 | <i>WantNegotiation</i>) is the decision whether to contact another nation or
|
---|
552 | not. This overridable is called by the kit framework for each known foreign nation
|
---|
553 | in the beginning of your turn (before DoTurn) and again in the end of your turn
|
---|
554 | (after DoTurn). The <i>NegoTime</i> parameter tells you which case it is.
|
---|
555 | You should return <i>true</i> if you wish to ask this nation for
|
---|
556 | negotiation. For
|
---|
557 | example, if you'd like to contact Enemy <i>p</i> after moving your units, return
|
---|
558 | <i>false</i> from <i>WantNegotiation(p,BeginOfTurn)</i> but <i>true</i> from
|
---|
559 | <i>WantNegotiation(p,EndOfTurn)</i>. The kit does not support negotiations in
|
---|
560 | the middle of your turn. The third possible value of the NegoTime parameter,
|
---|
561 | <i>EnemyCalled</i>, tells that the other nation is asking you for contact,
|
---|
562 | means it's their turn, not yours. With the EnemyCalled parameter, this is not an
|
---|
563 | in-turn overridable, otherwise it is.
|
---|
564 |
|
---|
565 | <p>The second part of your diplomacy implementation is the negotiation
|
---|
566 | (overridable <i>DoNegotiation</i>). Negotiations are built around making and
|
---|
567 | accepting offers. An offer contains
|
---|
568 | prices which will be delivered when the offer gets accepted as well as prices
|
---|
569 | which have to be paid in order to accept the offer. Each price is represented
|
---|
570 | by a 32 bit code, depending on its kind:
|
---|
571 |
|
---|
572 | <p><table border cellspacing=0 cellpadding=3>
|
---|
573 | <tr><td class="header">Price</td><td class="header">Code</td></tr>
|
---|
574 | <tr><td>Your nation's state report</td><td>opCivilReport + me shl 16</td></tr>
|
---|
575 | <tr><td>Opponent's state report</td><td>opCivilReport + Opponent shl 16</td></tr>
|
---|
576 | <tr><td>Your nation's military report</td><td>opMilReport + me shl 16</td></tr>
|
---|
577 | <tr><td>Opponent's military report</td><td>opMilReport + Opponent shl 16</td></tr>
|
---|
578 | <tr><td>World map</td><td>opMap</td></tr>
|
---|
579 | <tr><td>Next closer treaty</td><td>opTreaty + tr+1, tr = current treaty</td></tr>
|
---|
580 | <tr><td>End current treaty</td><td>opTreaty + tr-1, tr = current treaty</td></tr>
|
---|
581 | <tr><td>Colony Ship Parts</td><td>opShipParts + t shl 16 + n, t = part type, n = number</td></tr>
|
---|
582 | <tr><td>Money</td><td>opMoney + v, v = value</td></tr>
|
---|
583 | <tr><td>Tribute</td><td>opTribute + v, v = value</td></tr>
|
---|
584 | <tr><td>Advance</td><td>opTech + ad, ad = advance</td></tr>
|
---|
585 | <tr><td>All advances</td><td>opAllTech</td></tr>
|
---|
586 | <tr><td>Unit design</td><td>opModel + mix, mix = model index</td></tr>
|
---|
587 | <tr><td>All unit designs</td><td>opAllModel</td></tr>
|
---|
588 | <tr><td>Price of choice</td><td>opChoose</td></tr>
|
---|
589 | </table>
|
---|
590 |
|
---|
591 | <p>Offering to deliver things you do not have is not allowed. Also, offers containing
|
---|
592 | more than one treaty price are not possible. But even if an offer is
|
---|
593 | allowed, it is not necessarily useful, for example demanding a price of choice.
|
---|
594 | Please consider that offers the opponent does not understand are wasted, because
|
---|
595 | he will never accept them.
|
---|
596 |
|
---|
597 | <p>Offers are represented by data records of the type <i>TOffer</i>, containing these fields:
|
---|
598 | <br><i>nDeliver</i> - number of prices delivered if offer is accepted
|
---|
599 | <br><i>nCost</i> - number of prices required to pay to accept this offer
|
---|
600 | <br><i>Price</i> - codes of the prices delivered in [0..nDeliver-1],
|
---|
601 | codes of the prices to pay in [nDeliver..nDeliver+nCost-1]
|
---|
602 | <br>An offer can not contain more than 12 prices in total.
|
---|
603 |
|
---|
604 | <p>A special kind of offers are null-offers, containing no prices. Such an offer
|
---|
605 | means the player has no more offers to make for this negotiation. If null-offers
|
---|
606 | of both players immediately follow one another, the negotiation ends in agreement
|
---|
607 | (in contrast to one player breaking it).
|
---|
608 |
|
---|
609 | <p>DoNegotiation has no parameters, you can
|
---|
610 | read the negotiation opponent and his last action from the fields
|
---|
611 | <i>Opponent</i> and <i>OppoAction</i> of the AI. In case his action was an
|
---|
612 | offer, the field <i>OppoOffer</i> is valid additionally. Your DoNegotiation
|
---|
613 | implementation must define your next negotiation action in the field <i>MyAction</i>.
|
---|
614 | If it's an offer, you should fill the field <i>MyOffer</i>, too. After
|
---|
615 | DoNegotiation ended, the game will call the other nation and then, maybe, call
|
---|
616 | DoNegotiation again, with the field OppoAction now filled
|
---|
617 | with the other nation's response. See the Sample AI for an example of usage.
|
---|
618 |
|
---|
619 | <p>The negotiation actions are:
|
---|
620 | <p><table border cellspacing=0 cellpadding=3>
|
---|
621 | <tr><td class="header">Action</td><td class="header">Usage</td><td class="header">Valid as MyAction if OppoAction is...</td></tr>
|
---|
622 | <tr><td>scDipStart</td><td>-</td><td>Never! This is the OppoAction, when the negotiation starts and the opponent didn't have the chance to speak yet.</td></tr>
|
---|
623 | <tr><td>scDipOffer</td><td>Make offer. Always fill the <i>MyOffer</i> field when you set this action.</td><td>scDipStart, scDipOffer, scDipAccept, scDipNotice</td></tr>
|
---|
624 | <tr><td>scDipAccept</td><td>Accept opponent's offer.</td><td>scDipOffer</td></tr>
|
---|
625 | <tr><td>scDipNotice</td><td>Notice latest opponent decision.</td><td>scDipCancelTreaty, scDipBreak</td></tr>
|
---|
626 | <tr><td>scDipCancelTreaty</td><td>Cancel current treaty with opponent.</td><td>any</td></tr>
|
---|
627 | <tr><td>scDipBreak</td><td>Break negotiation (unagreed).</td><td>any except scDipBreak</td></tr>
|
---|
628 | </table>
|
---|
629 |
|
---|
630 |
|
---|
631 | <a name="save"></a>
|
---|
632 | <p><br><h2>Saving Data</h2>
|
---|
633 |
|
---|
634 | <p>Like most other games, C-evo offers the player to break a game, save it and
|
---|
635 | resume it later from the saved file. If your AI has information that it
|
---|
636 | collects in order to use it in later turns, this information would normally be
|
---|
637 | lost after breaking and reloading the game. In particular, all information
|
---|
638 | that you store
|
---|
639 | in local memory, e.g. in fields of the AI object, is <i>undefined</i> in the
|
---|
640 | beginning of a turn, because the game could have been loaded from a file
|
---|
641 | right before. You should check your AI object occasionally whether you're
|
---|
642 | trying to transport information from turn to turn with it. If so, this will
|
---|
643 | probably fail as soon as a game is saved and resumed. (BTW, the same rule counts
|
---|
644 | for base classes like TCustomAI and TToolAI. Just in case you intend to modify
|
---|
645 | them.)
|
---|
646 |
|
---|
647 | <p>There are only a few cases in which data exchange between subsequent
|
---|
648 | overridables using local memory in the AI is safe:
|
---|
649 | <ul>
|
---|
650 | <li>between <i>OnBefore...</i> and <i>OnAfter...</i>
|
---|
651 | <li>between subsequent <i>DoNegotiation</i> calls during negotiation with a single opponent
|
---|
652 | <li>between in-turn overridables during a single turn
|
---|
653 | </ul>
|
---|
654 |
|
---|
655 | <p>The C-evo AI interface offers two ways to make storing long-term information
|
---|
656 | possible: <i>Status</i> fields and the <i>ReadWrite</i>-block.
|
---|
657 |
|
---|
658 | <br><br><h3>Status Fields</h3>
|
---|
659 |
|
---|
660 | <p>Status fields are easy to use. Units, cities and models of your nation have
|
---|
661 | a field <i>Status</i>, enemy cities have it too. It's not used by the game and
|
---|
662 | exists only for the needs of AI programming. You can simply write
|
---|
663 | information to these fields and rely on it any number of turns later. When
|
---|
664 | resuming a saved game,
|
---|
665 | the game infrastructure will automatically restore the values that were
|
---|
666 | actual in the year in which the game is loaded.
|
---|
667 | But it's only 32 bit, so consider carefully what to do with them...
|
---|
668 |
|
---|
669 | <p>The status of newly appearing objects is always initialized with 0. This
|
---|
670 | happens also when a city is captured, means when an enemy city becomes an
|
---|
671 | own city or vice versa. The status content is lost then, it's not copied to the
|
---|
672 | new city object in the other list. (Of course, if this is a problem for your
|
---|
673 | AI, you can implement <i>OnBeforeEnemyCapture / OnAfterEnemyCapture</i>
|
---|
674 | so that it's solved.)
|
---|
675 |
|
---|
676 | <br><br><h3>The ReadWrite-Block</h3>
|
---|
677 |
|
---|
678 | <p>In order to collect information that is not related to units, cities or
|
---|
679 | models, e.g. general information about foreign nations, you should use the
|
---|
680 | ReadWrite block. This is a freely definable collection of information that
|
---|
681 | has to be maintained by the AI and is being restored just like the Status fields
|
---|
682 | whenever a saved game is resumed. Define a record type for the structure of
|
---|
683 | this block, and,
|
---|
684 | in the initialization section of AI.pas, assign the size of this structure
|
---|
685 | (in bytes) to <i>RWDataSize</i>. The game will allocate the memory for this
|
---|
686 | data structure and pass the pointer to it in the <i>Data</i> field of the
|
---|
687 | ReadOnly-block.
|
---|
688 |
|
---|
689 | <p>However, the ReadWrite-block is pretty small: The maximum size is 4096 Bytes.
|
---|
690 | So you should only save there what you can't calculate from other information.
|
---|
691 | (The limitation has to do with the size of saved C-evo books. Since the changes
|
---|
692 | must be saved in each turn, even 4k of information can cause huge book files.)
|
---|
693 |
|
---|
694 | <p>There are two overridables related to the ReadWrite-block.
|
---|
695 |
|
---|
696 | <p><i>SetDataDefaults</i>
|
---|
697 | <br>Initialize the ReadWrite-block here. This initialization must not depend
|
---|
698 | on anything but the map size and the values from the ReadOnly-block.
|
---|
699 | Particularly, you should not generate random values here, because this
|
---|
700 | overridable is also executed
|
---|
701 | when resuming a saved game - random values would not be generated in the same
|
---|
702 | way as before.
|
---|
703 |
|
---|
704 | <p><i>SetDataRandom</i>
|
---|
705 | <br>Well, if you <i>have</i> random values to set in the beginning of a game
|
---|
706 | (e.g. basic orientation of behavior), do this here. This overridable is called
|
---|
707 | after SetDataDefaults, when a new game is started. When loading games, it is
|
---|
708 | <i>not</i> executed - the values generated here before are being restored instead.
|
---|
709 |
|
---|
710 | <p>The kit does not yet support updates of the ReadWrite-block. If you change
|
---|
711 | the structure of the data, loading games that were initially played with an older
|
---|
712 | version of your AI will cause problems.
|
---|
713 |
|
---|
714 |
|
---|
715 | <p><br><h2>Cheating</h2>
|
---|
716 |
|
---|
717 | <p>I don't have the time for any effort to make the AI interface
|
---|
718 | swindler proof. The game's internal memory is wide open for AI DLLs to read and
|
---|
719 | even to write, leaving several ways to cheat. Some of
|
---|
720 | them will lead to corrupted books, e.g. simple writing to RO data. Other
|
---|
721 | tricks work fine, technically. For example, a nation can calculate the
|
---|
722 | addresses of the other nation's RO blocks and read information from there, such
|
---|
723 | as current unit positions. If you'd like to make use of these <i>monster
|
---|
724 | security leaks</i>, I cannot
|
---|
725 | prevent you from that, but please don't call the result a C-evo AI.
|
---|
726 |
|
---|
727 |
|
---|
728 | <a name="inst"></a>
|
---|
729 | <p><br><h2>Installing Your AI</h2>
|
---|
730 |
|
---|
731 | <p>There are some steps necessary in order to make the game recognize and use
|
---|
732 | your AI. First, you should choose a name for your AI - let's take <i>MyAI</i>
|
---|
733 | as example. Modify the file names, project
|
---|
734 | settings or compiler command line options so that the AI DLL has the name
|
---|
735 | <i>MyAI.dll</i> instead of <i>AIProject.dll</i>.
|
---|
736 |
|
---|
737 | <p>Then you need an AI description
|
---|
738 | file, this is a small text file. The kit contains a template, the file
|
---|
739 | <i>AIProject.ai.txt</i>. Rename it to <i>MyAI.ai.txt</i>, move it to the
|
---|
740 | folder where the cevo.exe is located and edit it.
|
---|
741 | An AI description file can contain the following statements, each on the
|
---|
742 | beginning of a separate line (take care for the capitals!):
|
---|
743 | <ul>
|
---|
744 | <li>#NAME s - If the name of your AI is different from the file name.
|
---|
745 | <li>#PATH s - Path of the DLL, relative to the main C-evo directory. If this line
|
---|
746 | does not exist, the path "MyAI.dll" is expected. So you can develop the AI
|
---|
747 | DLL in any folder. However, in case you publish
|
---|
748 | the AI, change the PATH entry so that it expects the DLL in the main C-evo
|
---|
749 | folder, because anything else would make it too difficult for players to
|
---|
750 | install your AI.
|
---|
751 | <li>#GAMEVERSION i.i.i - lowest C-evo version number that this AI works with,
|
---|
752 | should be 1.0.0 when the AI was built with this kit. This line is a MUST.
|
---|
753 | <li>#CREDITS s - A line telling your name or whatever you like.
|
---|
754 | This information will be displayed on the credits screen whenever the AI is in use.
|
---|
755 | </ul>
|
---|
756 |
|
---|
757 | <p>It's also possible (and appreciated) to create a picture for an AI, to represent
|
---|
758 | it on the start screen. This picture must have a size
|
---|
759 | of 64x64 pixels and be present as <i>MyAI.bmp</i> in the main C-evo folder.
|
---|
760 |
|
---|
761 |
|
---|
762 | <p><br><h2>Publishing Your AI</h2>
|
---|
763 |
|
---|
764 | <p>If you'd like to make the AI public, simply upload it to the
|
---|
765 | <a href="http://c-evo.org/files">files section</a> of the project homepage.
|
---|
766 | But please, only do this if you invested a considerable amount of work.
|
---|
767 | Do <i>not</i> publish the Sample AI after you changed three lines of code in
|
---|
768 | it...
|
---|
769 |
|
---|
770 |
|
---|
771 | <p><br><h2>The Sample AI</h2>
|
---|
772 |
|
---|
773 | <p>The kit contains a sample AI demonstrating some unit movement, city management
|
---|
774 | and simple diplomacy. This code is made for demonstration, so in contrast to the
|
---|
775 | kit files, it's no infrastructure for development, means it does not have a settled
|
---|
776 | interface. Be aware of that! Of course, you can use the Sample AI as starting
|
---|
777 | point for AI development, or you can copy parts of it to your AI. But when
|
---|
778 | future versions of C-evo come with an improved version of the Sample
|
---|
779 | AI, your AI does not automatically benefit from this. You only
|
---|
780 | have the option then to merge the changes manually.
|
---|
781 |
|
---|
782 | <p><b>Files of the Sample AI</b>
|
---|
783 | <p><ul><li><i>AI.pas</i> - This is the actual top-level AI code.
|
---|
784 | It is not mainly made to make up a
|
---|
785 | strong AI but to demonstrate the kit system and the usage of the lower level units.
|
---|
786 | <li><i>ToolAI.pas</i> - Contains a few advanced tools for AI programming. Their usage
|
---|
787 | is documented in the unit interface code, you don't need to understand how they
|
---|
788 | are implemented. If you like, this gives you a ready-to-use solution for some common problems.
|
---|
789 | <li><i>Names.pas</i> - String constants for improvements, advances etc. (for easier debugging).
|
---|
790 | <li><i>Pile.pas</i> - A unit with a universal priority queue implementation that
|
---|
791 | is used by the Sample AI.
|
---|
792 | </ul>
|
---|
793 |
|
---|
794 | <p>The Sample AI also shows a possibility to structure AI code built with this kit:
|
---|
795 | By making the TAI class not base directly on TCustomAI but introducing
|
---|
796 | intermediate class layer(s).
|
---|
797 |
|
---|
798 |
|
---|
799 | <p><br><h2>FAQ</h2>
|
---|
800 |
|
---|
801 | <p class="question">Q1. The rules of the game are not exactly specified.
|
---|
802 | I need more information than what is written in the manual.
|
---|
803 | <p>Answer: Sometimes an AI programmer needs very exact information about
|
---|
804 | calculations or about the behavior of the game in special situations. This exact
|
---|
805 | information often is
|
---|
806 | not contained in the in-game manual, because this manual is for <i>players</i>.
|
---|
807 | Players usually don't need and don't want that precision overkill. If you need more
|
---|
808 | information, please ask me or go to the <a href="http://c-evo.org/bb/viewforum.php?f=5">AI forum</a>.
|
---|
809 | (Or maybe try to analyze the sources of the game...)
|
---|
810 |
|
---|
811 | <br><br><p class="question">Q2. How can my AI...
|
---|
812 | <ul>
|
---|
813 | <li>...select a unit?
|
---|
814 | <li>...order the unit command <i>stay here</i> or <i>recover</i>?
|
---|
815 | <li>...recognize free citizens?
|
---|
816 | <li>...mark models to be obsolete?
|
---|
817 | <li>...access the macro management (city types, research focus, terrain enhancement)?
|
---|
818 | </ul>
|
---|
819 | <p>Answer: All of these things are not part of the actual game. The user interface
|
---|
820 | implements these mechanisms in order to make the game better playable by human
|
---|
821 | players. If you think something similar could be helpful in your AI, you must
|
---|
822 | implement it. The means described in this manual are enough for that.
|
---|
823 |
|
---|
824 | <br><br><p class="question">Q3. How can I debug my AI?
|
---|
825 | <p>Answer:
|
---|
826 | <ul>
|
---|
827 | <li>In <i>FreePascal</i>, I cannot help you. Seems to me that there is no way to debug
|
---|
828 | a Windows DLL with the available FreePascal and GNU utilities. (If you know one,
|
---|
829 | please let me know!) I'm afraid, you'll have to use <a href="#debug">debug
|
---|
830 | messages</a> or implement a kind of logfile for debugging.</li>
|
---|
831 | </ul>
|
---|
832 |
|
---|
833 | <p><br>
|
---|
834 |
|
---|
835 | </body>
|
---|
836 | </html>
|
---|
837 |
|
---|