~ubuntu-branches/ubuntu/hardy/bygfoot/hardy

« back to all changes in this revision

Viewing changes to src/xml_strategy.c

  • Committer: Bazaar Package Importer
  • Author(s): Isaac Clerencia
  • Date: 2006-06-04 17:51:19 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060604175119-0pbfuhr617031qa9
Tags: 2.0.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   xml_strategy.c
 
3
 
 
4
   Bygfoot Football Manager -- a small and simple GTK2-based
 
5
   football management game.
 
6
 
 
7
   http://bygfoot.sourceforge.net
 
8
 
 
9
   Copyright (C) 2005  Gyözö Both (gyboth@bygfoot.com)
 
10
 
 
11
   This program is free software; you can redistribute it and/or
 
12
   modify it under the terms of the GNU General Public License
 
13
   as published by the Free Software Foundation; either version 2
 
14
   of the License, or (at your option) any later version.
 
15
 
 
16
   This program is distributed in the hope that it will be useful,
 
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
   GNU General Public License for more details.
 
20
 
 
21
   You should have received a copy of the GNU General Public License
 
22
   along with this program; if not, write to the Free Software
 
23
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
24
*/
 
25
 
 
26
#include "file.h"
 
27
#include "free.h"
 
28
#include "main.h"
 
29
#include "misc.h"
 
30
#include "strategy_struct.h"
 
31
#include "xml_strategy.h"
 
32
 
 
33
#define TAG_STRATEGY "strategy"
 
34
#define TAG_STRATEGY_SID "sid"
 
35
#define TAG_STRATEGY_DESC "desc"
 
36
#define TAG_STRATEGY_PRIORITY "priority"
 
37
 
 
38
#define TAG_STRATEGY_PREMATCH "prematch"
 
39
#define TAG_STRATEGY_PREMATCH_FORMATION "formation"
 
40
#define TAG_STRATEGY_PREMATCH_LINEUP "lineup"
 
41
#define TAG_STRATEGY_PREMATCH_BOOST "prematch_boost"
 
42
#define TAG_STRATEGY_PREMATCH_STYLE "prematch_style"
 
43
 
 
44
#define TAG_STRATEGY_MATCH_ACTION "match_action"
 
45
#define TAG_STRATEGY_MATCH_ACTION_BOOST "boost"
 
46
#define TAG_STRATEGY_MATCH_ACTION_STYLE "style"
 
47
#define TAG_STRATEGY_MATCH_ACTION_SUB "sub"
 
48
#define TAG_STRATEGY_MATCH_ACTION_SUB_IN_POS "in"
 
49
#define TAG_STRATEGY_MATCH_ACTION_SUB_OUT_POS "out"
 
50
 
 
51
#define ATT_NAME_MIN_FITNESS "min_fitness"
 
52
#define ATT_NAME_COND "cond"
 
53
#define ATT_NAME_SUB_PROPERTY "prop"
 
54
 
 
55
#define LINEUP_NAME_BEST "best"
 
56
#define LINEUP_NAME_WEAKEST "weakest"
 
57
#define LINEUP_NAME_FITTEST "fittest"
 
58
#define LINEUP_NAME_UNFITTEST "unfittest"
 
59
 
 
60
#define BOOST_NAME_ON "on"
 
61
#define BOOST_NAME_OFF "off"
 
62
#define BOOST_NAME_ANTI "anti"
 
63
 
 
64
#define STYLE_NAME_ALL_OUT_DEFEND "all-out-defend"
 
65
#define STYLE_NAME_DEFEND "defend"
 
66
#define STYLE_NAME_BALANCED "balanced"
 
67
#define STYLE_NAME_ATTACK "attack"
 
68
#define STYLE_NAME_ALL_OUT_ATTACK "all-out-attack"
 
69
 
 
70
#define POS_NAME_GOALIE "goalie"
 
71
#define POS_NAME_DEFENDER "defender"
 
72
#define POS_NAME_MIDFIELDER "midfielder"
 
73
#define POS_NAME_FORWARD "forward"
 
74
 
 
75
enum
 
76
{
 
77
    STATE_STRATEGY = 0,
 
78
    STATE_STRATEGY_SID,
 
79
    STATE_STRATEGY_DESC,
 
80
    STATE_STRATEGY_PRIORITY,
 
81
    STATE_STRATEGY_PREMATCH,
 
82
    STATE_STRATEGY_PREMATCH_FORMATION,
 
83
    STATE_STRATEGY_PREMATCH_LINEUP,
 
84
    STATE_STRATEGY_PREMATCH_BOOST,
 
85
    STATE_STRATEGY_PREMATCH_STYLE,
 
86
    STATE_STRATEGY_MATCH_ACTION,
 
87
    STATE_STRATEGY_MATCH_ACTION_BOOST,
 
88
    STATE_STRATEGY_MATCH_ACTION_STYLE,
 
89
    STATE_STRATEGY_MATCH_ACTION_SUB,
 
90
    STATE_STRATEGY_MATCH_ACTION_SUB_IN_POS,
 
91
    STATE_STRATEGY_MATCH_ACTION_SUB_OUT_POS,
 
92
};
 
93
 
 
94
gint state, action_id;
 
95
 
 
96
#define curstrat g_array_index(strategies, Strategy, strategies->len - 1)
 
97
#define curprematch g_array_index(curstrat.prematch, StrategyPrematch, curstrat.prematch->len - 1)
 
98
#define curmatchaction g_array_index(curstrat.match_action, StrategyMatchAction, curstrat.match_action->len - 1)
 
99
 
 
100
void
 
101
xml_strategy_read_start_element (GMarkupParseContext *context,
 
102
                                 const gchar         *element_name,
 
103
                                 const gchar        **attribute_names,
 
104
                                 const gchar        **attribute_values,
 
105
                                 gpointer             user_data,
 
106
                                 GError             **error)
 
107
{
 
108
    gint atidx = 0;
 
109
 
 
110
    if(strcmp(element_name, TAG_STRATEGY) == 0)
 
111
        state = STATE_STRATEGY;
 
112
    else if(strcmp(element_name, TAG_STRATEGY_SID) == 0)
 
113
        state = STATE_STRATEGY_SID;
 
114
    else if(strcmp(element_name, TAG_STRATEGY_DESC) == 0)
 
115
        state = STATE_STRATEGY_DESC;
 
116
    else if(strcmp(element_name, TAG_STRATEGY_PRIORITY) == 0)
 
117
        state = STATE_STRATEGY_PRIORITY;
 
118
    else if(strcmp(element_name, TAG_STRATEGY_PREMATCH) == 0)
 
119
    {
 
120
        StrategyPrematch new_prematch;
 
121
 
 
122
        state = STATE_STRATEGY_PREMATCH;
 
123
        
 
124
        new_prematch.condition = NULL;
 
125
        new_prematch.lineup = new_prematch.boost = 
 
126
            new_prematch.style = -100;
 
127
        new_prematch.min_fitness = 0;
 
128
        new_prematch.formations = g_array_new(FALSE, FALSE, sizeof(gint));
 
129
 
 
130
        while(attribute_names[atidx] != NULL)
 
131
        {
 
132
            if(strcmp(attribute_names[atidx], ATT_NAME_COND) == 0 &&
 
133
                new_prematch.condition == NULL)
 
134
                new_prematch.condition = 
 
135
                    g_strdup(attribute_values[atidx]);
 
136
            else
 
137
                g_warning("xml_strategy_read_start_element: unknown attribute %s\n",
 
138
                          attribute_names[atidx]);
 
139
 
 
140
            atidx++;
 
141
        }
 
142
 
 
143
        g_array_append_val(curstrat.prematch, new_prematch);
 
144
    }
 
145
    else if(strcmp(element_name, TAG_STRATEGY_PREMATCH_FORMATION) == 0)
 
146
        state = STATE_STRATEGY_PREMATCH_FORMATION;
 
147
    else if(strcmp(element_name, TAG_STRATEGY_PREMATCH_LINEUP) == 0)
 
148
    {
 
149
        state = STATE_STRATEGY_PREMATCH_LINEUP;
 
150
 
 
151
        while(attribute_names[atidx] != NULL)
 
152
        {
 
153
            if(strcmp(attribute_names[atidx], ATT_NAME_MIN_FITNESS) == 0)
 
154
                curprematch.min_fitness =
 
155
                    g_ascii_strtod(attribute_values[atidx], NULL) / 100;
 
156
            else
 
157
                g_warning("xml_strategy_read_start_element: unknown attribute %s\n",
 
158
                          attribute_names[atidx]);
 
159
 
 
160
            atidx++;
 
161
        }
 
162
    }
 
163
    else if(strcmp(element_name, TAG_STRATEGY_PREMATCH_BOOST) == 0)
 
164
        state = STATE_STRATEGY_PREMATCH_BOOST;
 
165
    else if(strcmp(element_name, TAG_STRATEGY_PREMATCH_STYLE) == 0)
 
166
        state = STATE_STRATEGY_PREMATCH_STYLE;
 
167
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION) == 0)
 
168
    {
 
169
        StrategyMatchAction new_match_action;
 
170
 
 
171
        state = STATE_STRATEGY_MATCH_ACTION;
 
172
        new_match_action.sub_condition = NULL;
 
173
        
 
174
        new_match_action.condition = NULL;
 
175
        new_match_action.boost = 
 
176
            new_match_action.style = -100;
 
177
        new_match_action.sub_in_pos = -1;
 
178
        new_match_action.id = action_id++;
 
179
 
 
180
        while(attribute_names[atidx] != NULL)
 
181
        {
 
182
            if(strcmp(attribute_names[atidx], ATT_NAME_COND) == 0 &&
 
183
               new_match_action.condition == NULL)
 
184
                new_match_action.condition = 
 
185
                    g_strdup(attribute_values[atidx]);
 
186
            else
 
187
                g_warning("xml_strategy_read_start_element: unknown attribute %s\n",
 
188
                          attribute_names[atidx]);
 
189
 
 
190
            atidx++;
 
191
        }
 
192
 
 
193
        g_array_append_val(curstrat.match_action, new_match_action);
 
194
    }
 
195
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_BOOST) == 0)
 
196
        state = STATE_STRATEGY_MATCH_ACTION_BOOST;
 
197
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_STYLE) == 0)
 
198
        state = STATE_STRATEGY_MATCH_ACTION_STYLE;
 
199
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_SUB) == 0)
 
200
    {
 
201
        state = STATE_STRATEGY_MATCH_ACTION_SUB;
 
202
 
 
203
        while(attribute_names[atidx] != NULL)
 
204
        {
 
205
            if(strcmp(attribute_names[atidx], ATT_NAME_COND) == 0 &&
 
206
               curmatchaction.sub_condition == NULL)
 
207
                curmatchaction.sub_condition = 
 
208
                    g_strdup(attribute_values[atidx]);
 
209
            else
 
210
                g_warning("xml_strategy_read_start_element: unknown attribute %s\n",
 
211
                          attribute_names[atidx]);
 
212
 
 
213
            atidx++;
 
214
        }
 
215
    }
 
216
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_SUB_IN_POS) == 0)
 
217
    {
 
218
        state = STATE_STRATEGY_MATCH_ACTION_SUB_IN_POS;
 
219
 
 
220
        while(attribute_names[atidx] != NULL)
 
221
        {
 
222
            if(strcmp(attribute_names[atidx], ATT_NAME_SUB_PROPERTY) == 0)
 
223
            {
 
224
                if(strcmp(attribute_values[atidx], LINEUP_NAME_BEST) == 0)
 
225
                    curmatchaction.sub_in_prop = STRAT_LINEUP_BEST;
 
226
                else if(strcmp(attribute_values[atidx], LINEUP_NAME_WEAKEST) == 0)
 
227
                    curmatchaction.sub_in_prop = STRAT_LINEUP_WEAKEST;
 
228
                else if(strcmp(attribute_values[atidx], LINEUP_NAME_FITTEST) == 0)
 
229
                    curmatchaction.sub_in_prop = STRAT_LINEUP_FITTEST;
 
230
                else if(strcmp(attribute_values[atidx], LINEUP_NAME_UNFITTEST) == 0)
 
231
                    curmatchaction.sub_in_prop = STRAT_LINEUP_UNFITTEST;
 
232
                else
 
233
                    g_warning("xml_strategy_read_start_element: unknown property value %s\n",
 
234
                              attribute_values[atidx]);
 
235
            }
 
236
            else
 
237
                g_warning("xml_strategy_read_start_element: unknown attribute %s\n",
 
238
                          attribute_names[atidx]);
 
239
 
 
240
            atidx++;
 
241
        }
 
242
    }
 
243
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_SUB_OUT_POS) == 0)
 
244
    {
 
245
        state = STATE_STRATEGY_MATCH_ACTION_SUB_OUT_POS;
 
246
 
 
247
        while(attribute_names[atidx] != NULL)
 
248
        {
 
249
            if(strcmp(attribute_names[atidx], ATT_NAME_SUB_PROPERTY) == 0)
 
250
            {
 
251
                if(strcmp(attribute_values[atidx], LINEUP_NAME_BEST) == 0)
 
252
                    curmatchaction.sub_out_prop = STRAT_LINEUP_BEST;
 
253
                else if(strcmp(attribute_values[atidx], LINEUP_NAME_WEAKEST) == 0)
 
254
                    curmatchaction.sub_out_prop = STRAT_LINEUP_WEAKEST;
 
255
                else if(strcmp(attribute_values[atidx], LINEUP_NAME_FITTEST) == 0)
 
256
                    curmatchaction.sub_out_prop = STRAT_LINEUP_FITTEST;
 
257
                else if(strcmp(attribute_values[atidx], LINEUP_NAME_UNFITTEST) == 0)
 
258
                    curmatchaction.sub_out_prop = STRAT_LINEUP_UNFITTEST;
 
259
                else
 
260
                    g_warning("xml_strategy_read_start_element: unknown property value %s\n",
 
261
                              attribute_values[atidx]);
 
262
            }
 
263
            else
 
264
                g_warning("xml_strategy_read_start_element: unknown attribute %s\n",
 
265
                          attribute_names[atidx]);
 
266
 
 
267
            atidx++;
 
268
        }
 
269
    }
 
270
    else
 
271
        g_warning("xml_strategy_read_start_element: unknown tag: %s; I'm in state %d\n",
 
272
                  element_name, state);
 
273
}
 
274
 
 
275
/**
 
276
 * The function called by the parser when a closing tag is read.
 
277
 * The state variable is changed in this function.
 
278
 * @see The GLib manual (Simple XML parser).
 
279
 */
 
280
void
 
281
xml_strategy_read_end_element    (GMarkupParseContext *context,
 
282
                                  const gchar         *element_name,
 
283
                                  gpointer             user_data,
 
284
                                  GError             **error)
 
285
{
 
286
    if(strcmp(element_name, TAG_STRATEGY_SID) == 0 ||
 
287
       strcmp(element_name, TAG_STRATEGY_DESC) == 0 ||
 
288
       strcmp(element_name, TAG_STRATEGY_PRIORITY) == 0 ||
 
289
       strcmp(element_name, TAG_STRATEGY_MATCH_ACTION) == 0 ||
 
290
       strcmp(element_name, TAG_STRATEGY_PREMATCH) == 0)
 
291
        state = STATE_STRATEGY;
 
292
    else if(strcmp(element_name, TAG_STRATEGY_PREMATCH_FORMATION) == 0 ||
 
293
            strcmp(element_name, TAG_STRATEGY_PREMATCH_LINEUP) == 0 ||
 
294
            strcmp(element_name, TAG_STRATEGY_PREMATCH_BOOST) == 0 ||
 
295
            strcmp(element_name, TAG_STRATEGY_PREMATCH_STYLE) == 0)
 
296
        state = STATE_STRATEGY_PREMATCH;
 
297
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_SUB) == 0 ||
 
298
            strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_STYLE) == 0 ||
 
299
            strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_BOOST) == 0)
 
300
        state = STATE_STRATEGY_MATCH_ACTION;
 
301
    else if(strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_SUB_IN_POS) == 0 ||
 
302
            strcmp(element_name, TAG_STRATEGY_MATCH_ACTION_SUB_OUT_POS) == 0)
 
303
        state = STATE_STRATEGY_MATCH_ACTION_SUB;
 
304
    else if(strcmp(element_name, TAG_STRATEGY) != 0)
 
305
        g_warning("xml_strategy_read_end_element: unknown tag: %s; I'm in state %d\n",
 
306
                  element_name, state);
 
307
}
 
308
 
 
309
/**
 
310
 * The function called by the parser when the text between tags is read.
 
311
 * This function is responsible for filling in the variables (e.g. team names)
 
312
 * when a file gets loaded.
 
313
 * @see The GLib manual (Simple XML parser).
 
314
 */
 
315
void
 
316
xml_strategy_read_text         (GMarkupParseContext *context,
 
317
                                const gchar         *text,
 
318
                                gsize                text_len,  
 
319
                                gpointer             user_data,
 
320
                                GError             **error)
 
321
{
 
322
    gchar buf[text_len + 1];
 
323
    gint int_value;
 
324
 
 
325
    strncpy(buf, text, text_len);
 
326
    buf[text_len] = '\0';
 
327
 
 
328
    int_value = (gint)g_ascii_strtod(buf, NULL);
 
329
 
 
330
    if(state == STATE_STRATEGY_SID)
 
331
        misc_string_assign(&curstrat.sid, buf);
 
332
    else if(state == STATE_STRATEGY_DESC)
 
333
        misc_string_assign(&curstrat.desc, buf);
 
334
    else if(state == STATE_STRATEGY_PRIORITY)
 
335
    {
 
336
        if(strategies->len == 1)
 
337
            curstrat.priority = int_value;
 
338
        else
 
339
            curstrat.priority = 
 
340
                g_array_index(strategies, Strategy, strategies->len - 2).priority + 
 
341
                int_value;
 
342
    }
 
343
    else if(state == STATE_STRATEGY_PREMATCH_FORMATION)
 
344
        g_array_append_val(curprematch.formations, int_value);
 
345
    else if(state == STATE_STRATEGY_PREMATCH_LINEUP)
 
346
    {
 
347
        if(strcmp(buf, LINEUP_NAME_BEST) == 0)
 
348
            curprematch.lineup = STRAT_LINEUP_BEST;
 
349
        else if(strcmp(buf, LINEUP_NAME_WEAKEST) == 0)
 
350
            curprematch.lineup = STRAT_LINEUP_WEAKEST;
 
351
        else if(strcmp(buf, LINEUP_NAME_FITTEST) == 0)
 
352
            curprematch.lineup = STRAT_LINEUP_FITTEST;
 
353
        else
 
354
            g_warning(
 
355
                "xml_strategy_read_text: unknown lineup type %s\n", buf);
 
356
    }
 
357
    else if(state == STATE_STRATEGY_PREMATCH_BOOST)
 
358
    {
 
359
        if(strcmp(buf, BOOST_NAME_ON) == 0)
 
360
            curprematch.boost = 1;
 
361
        else if(strcmp(buf, BOOST_NAME_OFF) == 0)
 
362
            curprematch.boost = 0;
 
363
        else if(strcmp(buf, BOOST_NAME_ANTI) == 0)
 
364
            curprematch.boost = -1;
 
365
        else
 
366
            g_warning(
 
367
                "xml_strategy_read_text: unknown boost type %s\n", buf);
 
368
    }
 
369
    else if(state == STATE_STRATEGY_PREMATCH_STYLE)
 
370
    {
 
371
        if(strcmp(buf, STYLE_NAME_ALL_OUT_DEFEND) == 0)
 
372
            curprematch.style = -2;
 
373
        else if(strcmp(buf, STYLE_NAME_DEFEND) == 0)
 
374
            curprematch.style = -1;
 
375
        else if(strcmp(buf, STYLE_NAME_BALANCED) == 0)
 
376
            curprematch.style = 0;
 
377
        else if(strcmp(buf, STYLE_NAME_ATTACK) == 0)
 
378
            curprematch.style = 1;
 
379
        else if(strcmp(buf, STYLE_NAME_ALL_OUT_ATTACK) == 0)
 
380
            curprematch.style = 2;
 
381
        else
 
382
            g_warning(
 
383
                "xml_strategy_read_text: unknown style type %s\n", buf);
 
384
    }
 
385
    else if(state == STATE_STRATEGY_MATCH_ACTION_STYLE)
 
386
    {
 
387
        if(strcmp(buf, STYLE_NAME_ALL_OUT_DEFEND) == 0)
 
388
            curmatchaction.style = -2;
 
389
        else if(strcmp(buf, STYLE_NAME_DEFEND) == 0)
 
390
            curmatchaction.style = -1;
 
391
        else if(strcmp(buf, STYLE_NAME_BALANCED) == 0)
 
392
            curmatchaction.style = 0;
 
393
        else if(strcmp(buf, STYLE_NAME_ATTACK) == 0)
 
394
            curmatchaction.style = 1;
 
395
        else if(strcmp(buf, STYLE_NAME_ALL_OUT_ATTACK) == 0)
 
396
            curmatchaction.style = 2;
 
397
        else
 
398
            g_warning(
 
399
                "xml_strategy_read_text: unknown style type %s\n", buf);
 
400
    }
 
401
    else if(state == STATE_STRATEGY_MATCH_ACTION_BOOST)
 
402
    {
 
403
        if(strcmp(buf, BOOST_NAME_ON) == 0)
 
404
            curmatchaction.boost = 1;
 
405
        else if(strcmp(buf, BOOST_NAME_OFF) == 0)
 
406
            curmatchaction.boost = 0;
 
407
        else if(strcmp(buf, BOOST_NAME_ANTI) == 0)
 
408
            curmatchaction.boost = -1;
 
409
        else
 
410
            g_warning(
 
411
                "xml_strategy_read_text: unknown boost type %s\n", buf);
 
412
    }
 
413
    else if(state == STATE_STRATEGY_MATCH_ACTION_SUB_IN_POS ||
 
414
            state == STATE_STRATEGY_MATCH_ACTION_SUB_OUT_POS)
 
415
    {
 
416
        GPtrArray *positions = misc_separate_strings(buf);
 
417
        gint i, *pos;
 
418
 
 
419
        if(state == STATE_STRATEGY_MATCH_ACTION_SUB_IN_POS)
 
420
        {
 
421
            if(positions->len > 1)
 
422
            {
 
423
                free_gchar_array(&positions);
 
424
                main_exit_program(EXIT_STRATEGY_ERROR, 
 
425
                                  "xml_strategy_read_text: too many sub_in positions: %s\n",
 
426
                                  buf);
 
427
            }
 
428
 
 
429
            pos = &curmatchaction.sub_in_pos;
 
430
        }
 
431
        else
 
432
            pos = &curmatchaction.sub_out_pos;
 
433
 
 
434
        *pos = 9;
 
435
        
 
436
        for(i=0;i<positions->len;i++)
 
437
            if(strcmp((gchar*)g_ptr_array_index(positions, i), 
 
438
                      POS_NAME_GOALIE) == 0)
 
439
                *pos *= 10;
 
440
            else if(strcmp((gchar*)g_ptr_array_index(positions, i), 
 
441
                           POS_NAME_DEFENDER) == 0)
 
442
                *pos = (*pos * 10) + 1;
 
443
            else if(strcmp((gchar*)g_ptr_array_index(positions, i),
 
444
                           POS_NAME_MIDFIELDER) == 0)
 
445
                *pos = (*pos * 10) + 2;
 
446
            else if(strcmp((gchar*)g_ptr_array_index(positions, i), 
 
447
                           POS_NAME_FORWARD) == 0)
 
448
                *pos = (*pos * 10) + 3;
 
449
            else
 
450
                g_warning(
 
451
                    "xml_strategy_read_text: unknown position %s\n", 
 
452
                    (gchar*)g_ptr_array_index(positions, i));
 
453
 
 
454
        if(*pos < 100)
 
455
            *pos = *pos % 10;
 
456
 
 
457
        free_gchar_array(&positions);
 
458
    }
 
459
}
 
460
 
 
461
/** Add the strategy described in the file
 
462
    to the strategies array. */
 
463
void
 
464
xml_strategy_read(const gchar *filename)
 
465
{
 
466
    gint i;
 
467
    Strategy new_strat;
 
468
    GMarkupParser parser = {xml_strategy_read_start_element,
 
469
                            xml_strategy_read_end_element,
 
470
                            xml_strategy_read_text, NULL, NULL};
 
471
    GMarkupParseContext *context;
 
472
    gchar *file_contents;
 
473
    gsize length;
 
474
    GError *error = NULL;
 
475
 
 
476
    context = 
 
477
        g_markup_parse_context_new(&parser, 0, NULL, NULL);
 
478
 
 
479
    if(!g_file_get_contents(filename, &file_contents, &length, &error))
 
480
    {
 
481
        g_warning("xml_strategy_read: error reading file %s\n", filename);
 
482
        misc_print_error(&error, TRUE);
 
483
        return;
 
484
    }
 
485
 
 
486
    new_strat.sid = new_strat.desc = NULL;
 
487
    new_strat.priority = 1;
 
488
    new_strat.prematch = g_array_new(FALSE, FALSE, sizeof(StrategyPrematch));
 
489
    new_strat.match_action = g_array_new(FALSE, FALSE, sizeof(StrategyMatchAction));
 
490
 
 
491
    g_array_append_val(strategies, new_strat);
 
492
 
 
493
    action_id = 0;
 
494
 
 
495
    if(g_markup_parse_context_parse(context, file_contents, length, &error))
 
496
    {
 
497
        g_markup_parse_context_end_parse(context, NULL);        
 
498
        g_markup_parse_context_free(context);
 
499
        g_free(file_contents);
 
500
    }
 
501
    else
 
502
    {
 
503
        g_critical("xml_strategy_read: error parsing file %s\n", filename);
 
504
        misc_print_error(&error, TRUE);
 
505
    }
 
506
 
 
507
 
 
508
    for(i=0;i<curstrat.match_action->len;i++)
 
509
    {
 
510
        if(g_array_index(curstrat.match_action, StrategyMatchAction, i).condition == NULL)
 
511
            main_exit_program(EXIT_STRATEGY_ERROR, "xml_strategy_read: unconditional match action encountered in file %s. match actions MUST have conditions.", filename);
 
512
    }
 
513
}
 
514
 
 
515
/** Load all strategy files found in the appropriate folder. */
 
516
void
 
517
xml_strategy_load_strategies(void)
 
518
{
 
519
    gint i, j, k;
 
520
    const gchar *strategydir = file_get_first_support_dir_suffix("strategy");
 
521
    GPtrArray *files = NULL;
 
522
    gchar buf[SMALL];
 
523
  
 
524
    if(strategydir == NULL)
 
525
        main_exit_program(EXIT_STRATEGY_ERROR, 
 
526
                          "xml_strategy_load_strategies: strategy directory not found.");
 
527
 
 
528
    files = file_dir_get_contents(strategydir, "strategy_", ".xml");
 
529
 
 
530
    if(files->len == 0)
 
531
    {
 
532
        g_ptr_array_free(files, TRUE);
 
533
        main_exit_program(EXIT_STRATEGY_ERROR, 
 
534
                          "xml_strategy_load_strategies: no CPU strategies found.");
 
535
    }
 
536
 
 
537
    for(i=0;i<files->len;i++)
 
538
    {
 
539
        sprintf(buf, "%s%s%s", strategydir, G_DIR_SEPARATOR_S,
 
540
                (const gchar*)g_ptr_array_index(files, i));
 
541
        xml_strategy_read(buf);
 
542
    }
 
543
 
 
544
    free_gchar_array(&files);
 
545
 
 
546
    /* Fill secondary prematches with default values. */
 
547
    for(i=0;i<strategies->len;i++)
 
548
    {
 
549
        StrategyPrematch *prem0 = &g_array_index(
 
550
            g_array_index(strategies, Strategy, i).prematch,
 
551
            StrategyPrematch, 0),
 
552
            *premcur = NULL;
 
553
 
 
554
        if(prem0->formations->len == 0)
 
555
            main_exit_program(EXIT_STRATEGY_ERROR,
 
556
                              "xml_strategy_read (%s): The primary prematch should have at least one formation.",
 
557
                              g_array_index(strategies, Strategy, i).sid);
 
558
 
 
559
        for(j=1;j<g_array_index(strategies, Strategy, i).prematch->len;j++)
 
560
        {
 
561
            premcur = &g_array_index(
 
562
                g_array_index(strategies, Strategy, i).prematch,
 
563
                StrategyPrematch, j);
 
564
 
 
565
            if(premcur->formations->len == 0)
 
566
                for(k=0;k<prem0->formations->len;k++)
 
567
                    g_array_append_val(premcur->formations,
 
568
                                       g_array_index(prem0->formations, gint, k));
 
569
                                                                       
 
570
            
 
571
            if(premcur->boost == -100)
 
572
                premcur->boost = prem0->boost;
 
573
            if(premcur->style == -100)
 
574
                premcur->style = prem0->style;
 
575
            if(premcur->lineup == -100)
 
576
                premcur->lineup = prem0->lineup;
 
577
            if(premcur->min_fitness == -100)
 
578
                premcur->min_fitness = prem0->min_fitness;
 
579
        }
 
580
    }
 
581
}