~ubuntu-branches/ubuntu/gutsy/grhino/gutsy

« back to all changes in this revision

Viewing changes to gen_pattern.cc

  • Committer: Bazaar Package Importer
  • Author(s): Bart Martens
  • Date: 2007-04-02 20:38:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070402203809-fxyqqtkhj9ou03dy
Tags: upstream-0.16.0
ImportĀ upstreamĀ versionĀ 0.16.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        gen_pattern.cc  Game Pattern Generator
 
3
        Copyright (c) 2001, 2002, 2003, 2004, 2005 Kriang Lerdsuwanakij
 
4
        email:          lerdsuwa@users.sourceforge.net
 
5
 
 
6
        This program is free software; you can redistribute it and/or modify
 
7
        it under the terms of the GNU General Public License as published by
 
8
        the Free Software Foundation; either version 2 of the License, or
 
9
        (at your option) any later version.
 
10
 
 
11
        This program is distributed in the hope that it will be useful,
 
12
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
        GNU General Public License for more details.
 
15
 
 
16
        You should have received a copy of the GNU General Public License
 
17
        along with this program; if not, write to the Free Software
 
18
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
*/
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <fstream>
 
24
#include <sstream>
 
25
 
 
26
#include <math.h>
 
27
#include <unistd.h>
 
28
#include <fcntl.h>
 
29
#include <sys/stat.h>
 
30
#include <sys/types.h>
 
31
 
 
32
#include "pattern.h"
 
33
#include "log_proc.h"
 
34
 
 
35
#include "gtstream.h"
 
36
 
 
37
#ifdef _
 
38
#undef _
 
39
#endif
 
40
 
 
41
#ifdef N_
 
42
#undef N_
 
43
#endif
 
44
 
 
45
#include <libintl.h>
 
46
#define _(x) gettext(x)
 
47
#define N_(x) x
 
48
 
 
49
// Grab version number in VERSION variable
 
50
// Use same version number as main GRhino program
 
51
#undef VERSION
 
52
const char *
 
53
#include "scripts/version"
 
54
;
 
55
 
 
56
const char *prog_name = "gen_pattern";
 
57
const char *prog_ver = VERSION;
 
58
 
 
59
struct pattern_state {
 
60
        pattern_t p;
 
61
 
 
62
                        // Pattern information
 
63
                        //   pat[PATTERN][MOVE_INDEX][PATTERN_INDEX]
 
64
                        // where
 
65
                        //   PATTERN = ROW1, ROW2, etc.
 
66
                        //   MOVE_INDEX = 0, 1, ..., num_move_index-1
 
67
                        //   PATTERN_INDEX = 0, 1, ... according to
 
68
                        //     positions of black and white pieces
 
69
        raw_pattern_info ***pat;
 
70
        pattern_state(pattern_t p_, raw_pattern_info ***pat_)
 
71
                : p(p_), pat(pat_) {}
 
72
};
 
73
 
 
74
/* Calculate score based on
 
75
     b = number of black wins
 
76
     w = number of white wins
 
77
   Result truncated to fit signed char.  */
 
78
 
 
79
signed char     log_func(long b, long w)
 
80
{
 
81
        if (b == w)     // Special case to avoid round-off problem
 
82
                return 0;
 
83
 
 
84
        long    a;      // Make sure we don't put too high score for case
 
85
                        // like win-loss = 1-0
 
86
        if (b+w < 5)
 
87
                a = 5 - b - w;
 
88
        else
 
89
                a = 1;  // Make formula work even when either b or w is zero
 
90
 
 
91
 
 
92
        long    x;
 
93
                        // Make sure we don't have rounding non-symmetry
 
94
        if (b > w)
 
95
                x = static_cast<long>(10*log(static_cast<double>(b+a)/(w+a)));
 
96
        else
 
97
                x = -static_cast<long>(10*log(static_cast<double>(w+a)/(b+a)));
 
98
 
 
99
                        // Limit value to fit signed char
 
100
        if (x > 7)
 
101
                x = 7;
 
102
        else if (x < -7)
 
103
                x = -7;
 
104
        return static_cast<signed char>(x);
 
105
}
 
106
 
 
107
void    init_file(pattern_t p)
 
108
{
 
109
                                // Special marker for all patterns
 
110
        if (p == PATTERN_UNKNOWN) {
 
111
                for (int p = 0; p != PATTERN_UNKNOWN; p++)
 
112
                        init_file(static_cast<pattern_t>(p));
 
113
                return;
 
114
        }
 
115
 
 
116
        int handle = creat(get_pattern_file(p), S_IRUSR | S_IWUSR);
 
117
        if (handle == -1) {
 
118
                gtstream bufstr;
 
119
                gtout(bufstr, _("cannot create file %$\n"))
 
120
                        << get_pattern_file(p);
 
121
                throw std::runtime_error(bufstr.str());
 
122
        }
 
123
 
 
124
                                // Loop for all move indexes
 
125
        raw_pattern_info **pat = new raw_pattern_info *[num_move_index];
 
126
        for (int pos = 0; pos < num_move_index; ++pos) {
 
127
                pat[pos] = new raw_pattern_info[get_pattern_size(p)];
 
128
 
 
129
                                // Loop for all pattern indexes
 
130
                for (int i = 0; i < get_pattern_size(p); ++i) {
 
131
                        pat[pos][i].black_win = 0;
 
132
                        pat[pos][i].white_win = 0;
 
133
                }
 
134
        }
 
135
 
 
136
                                // Loop for all move indexes
 
137
        for (int pos = 0; pos < num_move_index; ++pos) {
 
138
 
 
139
                                // Write all pattern indexes
 
140
                int size = sizeof(raw_pattern_info) * get_pattern_size(p);
 
141
                if (write(handle, pat[pos], size) != size) {
 
142
                        close(handle);
 
143
 
 
144
                        gtstream bufstr;
 
145
                        gtout(bufstr, _("cannot write file %$\n"))
 
146
                                << get_pattern_file(p);
 
147
                        throw std::runtime_error(bufstr.str());
 
148
                }
 
149
        }
 
150
 
 
151
        for (int pos = 0; pos < num_move_index; ++pos) {
 
152
                delete [] pat[pos];
 
153
        }
 
154
        delete [] pat;
 
155
 
 
156
        close(handle);
 
157
}
 
158
 
 
159
int     num_update[PATTERN_UNKNOWN][num_move_index];
 
160
int     update_list[PATTERN_UNKNOWN][num_move_index][60];
 
161
int     update_move_index;
 
162
 
 
163
void    init_info()
 
164
{
 
165
        update_move_index = -1;
 
166
        for (int p = 0; p != PATTERN_UNKNOWN; ++p)
 
167
                for (int i = 0; i < num_move_index; ++i)
 
168
                        num_update[p][i] = 0;
 
169
}
 
170
 
 
171
bool    find_update(pattern_t p, int move_index, int pos)
 
172
{
 
173
        for (int i = 0; i < num_update[p][move_index]; ++i) {
 
174
                if (pos == update_list[p][move_index][i])       // Already updated
 
175
                        return true;
 
176
        }
 
177
        return false;
 
178
}
 
179
 
 
180
void    update_info_table(pattern_t p, raw_pattern_info ***pat, int diff,
 
181
                          int move_index, int pos1, int pos2, int pos3, int pos4)
 
182
{
 
183
        if (find_update(p, move_index, pos1))
 
184
                return;
 
185
        update_list[p][move_index][num_update[p][move_index]] = pos1;
 
186
        num_update[p][move_index]++;
 
187
        update_list[p][move_index][num_update[p][move_index]] = pos2;
 
188
        num_update[p][move_index]++;
 
189
        update_list[p][move_index][num_update[p][move_index]] = pos3;
 
190
        num_update[p][move_index]++;
 
191
        update_list[p][move_index][num_update[p][move_index]] = pos4;
 
192
        num_update[p][move_index]++;
 
193
 
 
194
                        // Find winner
 
195
        {
 
196
                if (diff > 0)
 
197
                        pat[p][move_index][pos1].black_win++;
 
198
                else if (diff < 0)
 
199
                        pat[p][move_index][pos1].white_win++;
 
200
                else {
 
201
                        // Draw game
 
202
                        pat[p][move_index][pos1].black_win++;
 
203
                        pat[p][move_index][pos1].white_win++;
 
204
                }
 
205
        }
 
206
 
 
207
        if (get_pattern_symmetry(p)) {
 
208
                if (diff > 0)
 
209
                        pat[p][move_index][pos2].black_win++;
 
210
                else if (diff < 0)
 
211
                        pat[p][move_index][pos2].white_win++;
 
212
                else {
 
213
                        pat[p][move_index][pos2].black_win++;
 
214
                        pat[p][move_index][pos2].white_win++;
 
215
                }
 
216
        }
 
217
 
 
218
                                        // Need to maintain fairness when
 
219
                                        // comparing positions during searching
 
220
        {
 
221
                if (diff < 0)
 
222
                        pat[p][move_index][pos3].black_win++;
 
223
                else if (diff > 0)
 
224
                        pat[p][move_index][pos3].white_win++;
 
225
                else {
 
226
                        pat[p][move_index][pos3].black_win++;
 
227
                        pat[p][move_index][pos3].white_win++;
 
228
                }
 
229
        }
 
230
 
 
231
        if (get_pattern_symmetry(p)) {
 
232
                if (diff < 0)
 
233
                        pat[p][move_index][pos4].black_win++;
 
234
                else if (diff > 0)
 
235
                        pat[p][move_index][pos4].white_win++;
 
236
                else {
 
237
                        pat[p][move_index][pos4].black_win++;
 
238
                        pat[p][move_index][pos4].white_win++;
 
239
                }
 
240
        }
 
241
}
 
242
 
 
243
void    update_info(pattern_t p, raw_pattern_info ***pat, byte_board_info *board,
 
244
                    int diff)
 
245
{
 
246
                                // Special marker for all patterns
 
247
        if (p == PATTERN_UNKNOWN) {
 
248
                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++)
 
249
                        update_info(static_cast<pattern_t>(pp), pat,
 
250
                                        board, diff);
 
251
                return;
 
252
        }
 
253
 
 
254
        int move_index = to_move_index(board->get_num_move());
 
255
 
 
256
        for (int i = 0; i < get_num_pattern(p); ++i) {
 
257
 
 
258
                                // Appeared pattern_index
 
259
                int pos1 = 0;
 
260
                for (int j = 0; j < get_pattern_piece(p); ++j) {
 
261
                        pos1 += pow_3[j] * to_pattern_index(board->board[
 
262
                                                static_cast<int>(pattern_data[p].pattern[i][j])]);
 
263
                }
 
264
 
 
265
                                // Mirrored pattern_index
 
266
                int pos2 = 0;
 
267
                for (int j = 0; j < get_pattern_piece(p); ++j) {
 
268
                        pos2 += pow_3[j] * to_pattern_index(board->board[
 
269
                                                static_cast<int>(pattern_data[p].pattern[i][get_pattern_piece(p)-1-j])]);
 
270
                }
 
271
 
 
272
                                // Color swapped pattern_index
 
273
                int pos3 = 0;
 
274
                for (int j = 0; j < get_pattern_piece(p); ++j) {
 
275
                        pos3 += pow_3[j] * to_pattern_index(-board->board[
 
276
                                                static_cast<int>(pattern_data[p].pattern[i][j])]);
 
277
                }
 
278
 
 
279
                                // Mirrored and color swapped pattern_index
 
280
                int pos4 = 0;
 
281
                for (int j = 0; j < get_pattern_piece(p); ++j) {
 
282
                        pos4 += pow_3[j] * to_pattern_index(-board->board[
 
283
                                                static_cast<int>(pattern_data[p].pattern[i][get_pattern_piece(p)-1-j])]);
 
284
                }
 
285
 
 
286
                                // Update some poorly represented patterns during
 
287
                                // early to midgame from late-mid game as well
 
288
                if (move_index < 8
 
289
                    && (p == PATTERN_ROW1 || p == PATTERN_ROW2
 
290
                        || p == PATTERN_EDGE_X || p == PATTERN_CORNER5X2
 
291
                        || p == PATTERN_DIAG1 || p == PATTERN_DIAG2)) {
 
292
 
 
293
                        for (int move_index_ = 0; move_index_ < 8; move_index_++) {
 
294
                                update_info_table(p, pat, diff, move_index_, pos1, pos2, pos3, pos4);
 
295
                        }
 
296
                }
 
297
                else
 
298
                        update_info_table(p, pat, diff, move_index, pos1, pos2, pos3, pos4);
 
299
                
 
300
        }
 
301
}
 
302
 
 
303
void    process_game(pattern_state &t, game_log &game)
 
304
{
 
305
        byte_board_info board(game.board);
 
306
 
 
307
        init_info();
 
308
 
 
309
                                // Now collect pattern info
 
310
 
 
311
                                // Loop for all game moves
 
312
        for (int i = 0; i < game.num_move_queue; ++i) {
 
313
                int player = game.move_queue_color[i];
 
314
                int pos = game.move_queue[i];
 
315
 
 
316
                                // Dump core upon broken game record
 
317
                if (!board.can_play(player, pos))
 
318
                        throw std::runtime_error(_("invalid game moves"));
 
319
                board.place_piece(player, pos);
 
320
 
 
321
                                // Update game info using final scores
 
322
                update_info(t.p, t.pat, &board,
 
323
                        game.black_score-game.white_score);
 
324
        }
 
325
}
 
326
 
 
327
void    load_file(const char *f, pattern_state &t)
 
328
{
 
329
        pattern_t p = t.p;
 
330
        raw_pattern_info ***pat = t.pat;
 
331
 
 
332
                                // Special marker for all patterns
 
333
        if (p == PATTERN_UNKNOWN) {
 
334
                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++) {
 
335
                        pattern_state tt(static_cast<pattern_t>(pp), pat);
 
336
                        load_file(f, tt);
 
337
                }
 
338
                return;
 
339
        }
 
340
 
 
341
        int handle = open(get_pattern_file(p), O_RDONLY);
 
342
        if (handle == -1) {
 
343
                gtstream bufstr;
 
344
                gtout(bufstr, _("cannot open file %$\n"))
 
345
                        << get_pattern_file(p);
 
346
                throw std::runtime_error(bufstr.str());
 
347
        }
 
348
 
 
349
        int io_size = sizeof(raw_pattern_info) * get_pattern_size(p);
 
350
 
 
351
        pat[p] = new raw_pattern_info *[num_move_index];
 
352
 
 
353
                                // Loop for all move indexes
 
354
        for (int pos = 0; pos < num_move_index; ++pos) {
 
355
 
 
356
                                // Read all pattern indexes
 
357
                pat[p][pos] = new raw_pattern_info[get_pattern_size(p)];
 
358
                if (read(handle, pat[p][pos], io_size) != io_size) {
 
359
                        close(handle);
 
360
 
 
361
                        gtstream bufstr;
 
362
                        gtout(bufstr, _("cannot read file %$\n"))
 
363
                                << get_pattern_file(p);
 
364
                        throw std::runtime_error(bufstr.str());
 
365
                }
 
366
        }
 
367
        close(handle);
 
368
}
 
369
 
 
370
void    store_file(const char *f, pattern_state &t)
 
371
{
 
372
        pattern_t p = t.p;
 
373
        raw_pattern_info ***pat = t.pat;
 
374
 
 
375
                                // Special marker for all patterns
 
376
        if (p == PATTERN_UNKNOWN) {
 
377
                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++) {
 
378
                        pattern_state tt(static_cast<pattern_t>(pp), pat);
 
379
                        store_file(f, tt);
 
380
                }
 
381
                return;
 
382
        }
 
383
 
 
384
        int io_size = sizeof(raw_pattern_info) * get_pattern_size(p);
 
385
 
 
386
        int handle = creat(get_pattern_file(p), S_IRUSR | S_IWUSR);
 
387
        if (handle == -1) {
 
388
                gtstream bufstr;
 
389
                gtout(bufstr, _("cannot create file %$\n"))
 
390
                        << get_pattern_file(p);
 
391
                throw std::runtime_error(bufstr.str());
 
392
        }
 
393
 
 
394
                                // Loop for all move indexes
 
395
        for (int pos = 0; pos < num_move_index; ++pos) {
 
396
 
 
397
                                // Write all pattern indexes
 
398
                if (write(handle, pat[p][pos], io_size) != io_size) {
 
399
                        close(handle);
 
400
 
 
401
                        gtstream bufstr;
 
402
                        gtout(bufstr, _("cannot write file %$\n"))
 
403
                                << get_pattern_file(p);
 
404
                        throw std::runtime_error(bufstr.str());
 
405
                }
 
406
        }
 
407
 
 
408
        close(handle);
 
409
}
 
410
 
 
411
void    generate_file(const char *f, pattern_state &t)
 
412
{
 
413
        pattern_t p = t.p;
 
414
        raw_pattern_info ***pat = t.pat;
 
415
 
 
416
                                // Special marker for all patterns
 
417
        if (p == PATTERN_UNKNOWN) {
 
418
                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++) {
 
419
                        pattern_state tt(static_cast<pattern_t>(pp), pat);
 
420
                        generate_file(f, tt);
 
421
                }
 
422
                return;
 
423
        }
 
424
 
 
425
        int handle = creat(get_pattern_data_file(p), S_IRUSR | S_IWUSR);
 
426
        if (handle == -1) {
 
427
                gtstream bufstr;
 
428
                gtout(bufstr, _("cannot create file %$\n"))
 
429
                        << get_pattern_data_file(p);
 
430
                throw std::runtime_error(bufstr.str());
 
431
        }
 
432
 
 
433
        int size = get_pattern_size(p);
 
434
        pattern_info **pat2 = new pattern_info *[num_move_index];
 
435
        for (int pos = 0; pos < num_move_index; ++pos) {
 
436
                pat2[pos] = new pattern_info[size];
 
437
                for (int i = 0; i < size; ++i) {
 
438
                        pat2[pos][i] = log_func(
 
439
                                        pat[p][pos][i].black_win,
 
440
                                        pat[p][pos][i].white_win);
 
441
                }
 
442
        }
 
443
 
 
444
                                // Set default value according to
 
445
                                // number of corners
 
446
        for (int pos = 1; pos < num_move_index-1; ++pos) {
 
447
                for (int i = 0; i < size; ++i) {
 
448
                        if (pat[p][pos][i].black_win + pat[p][pos][i].white_win == 0) {
 
449
                                int pat2i = 0;
 
450
                                if (p == PATTERN_ROW1) {
 
451
                                        pat2i += 64 * extract_color(i, 0);
 
452
                                        pat2i += 64 * extract_color(i, 7);
 
453
                                }
 
454
                                else if (p == PATTERN_DIAG1) {
 
455
                                        pat2i += 64 * extract_color(i, 0);
 
456
                                        pat2i += 64 * extract_color(i, 7);
 
457
                                }
 
458
                                else if (p == PATTERN_EDGE_X) {
 
459
                                        pat2i += 64 * extract_color(i, 1);
 
460
                                        pat2i += 64 * extract_color(i, 8);
 
461
                                }
 
462
                                else if (p == PATTERN_CORNER5X2) {
 
463
                                        pat2i += 64 * extract_color(i, 0);
 
464
                                }
 
465
 
 
466
                                if (pat2i > 127)
 
467
                                        pat2[pos][i] = 127;
 
468
                                else if (pat2i < -127)
 
469
                                        pat2[pos][i] = -127;
 
470
                                else
 
471
                                        pat2[pos][i] = pat2i;
 
472
                        }
 
473
                }
 
474
        }
 
475
 
 
476
                                // Interpolate
 
477
        for (int pos = 1; pos < num_move_index-1; ++pos) {
 
478
                for (int i = 0; i < size; ++i) {
 
479
                        if (pat[p][pos][i].black_win + pat[p][pos][i].white_win == 0
 
480
                            && pat2[pos][i] == 0) {
 
481
                                int pos_a = pos-1;
 
482
                                int pos_b = pos+1;
 
483
                                while (pos_a > 0 && pat2[pos_a][i] == 0 &&
 
484
                                       pat[p][pos_a][i].black_win + pat[p][pos_a][i].white_win == 0)
 
485
                                        pos_a--;
 
486
                                while (pos_b < num_move_index-1 && pat2[pos_b][i] == 0 &&
 
487
                                       pat[p][pos_b][i].black_win + pat[p][pos_b][i].white_win == 0)
 
488
                                        pos_b++;
 
489
 
 
490
                                // Should not suffer symmetry problem during
 
491
                                // division
 
492
                                pat2[pos][i] = ((pos-pos_a)*pat2[pos_b][i]
 
493
                                                + (pos_b-pos)*pat2[pos_a][i])
 
494
                                               /(pos_b-pos_a);
 
495
                        }
 
496
                }
 
497
        }
 
498
 
 
499
                                // Compress table
 
500
        int comp_size = size/3*2;
 
501
        for (int pos = 0; pos < num_move_index; ++pos) {
 
502
 
 
503
                                        // Verify table symmetry
 
504
                for (int j = comp_size, k = size/3-1; j < size; ++j, --k) {
 
505
                        if (pat2[pos][j] != -pat2[pos][k]) {
 
506
/*                              std::cout << "p=" << p << " pos=" << pos << " j=" << j << " k=" << k
 
507
                                << " : " << int(pat2[pos][j]) << ' ' << int(pat2[pos][k]);
 
508
                                show_pattern(p, j);
 
509
                                std::cout << " : ";
 
510
                                show_pattern(p, k);
 
511
                                std::cout << ' ' << pat[p][pos][j].black_win;
 
512
                                std::cout << ' ' << pat[p][pos][j].white_win;
 
513
                                std::cout << ' ' << pat[p][pos][k].black_win;
 
514
                                std::cout << ' ' << pat[p][pos][k].white_win;
 
515
                                std::cout << '\n';*/
 
516
                                throw std::runtime_error(_("pattern symmetry error"));
 
517
                        }
 
518
                }
 
519
                if (write(handle, pat2[pos], comp_size) != comp_size) {
 
520
                        close(handle);
 
521
 
 
522
                        gtstream bufstr;
 
523
                        gtout(bufstr, _("cannot write file %$\n"))
 
524
                                << get_pattern_data_file(p);
 
525
                        throw std::runtime_error(bufstr.str());
 
526
                }
 
527
        }
 
528
 
 
529
        for (int pos = 0; pos < num_move_index; ++pos) {
 
530
                delete [] pat2[pos];
 
531
        }
 
532
        delete [] pat2;
 
533
 
 
534
        close(handle);
 
535
}
 
536
 
 
537
void    process_pattern(pattern_t pattern, int argc, char *argv[])
 
538
{
 
539
        bool    init_pattern = false;
 
540
 
 
541
        raw_pattern_info ***pat = 0;
 
542
 
 
543
        for (int i = 2; i < argc; ++i) {
 
544
                if (strcmp(argv[i], "init") == 0) {
 
545
                                                // Create new file with empty
 
546
                                                // pattern data
 
547
 
 
548
                        init_file(pattern);     // Write empty pattern data
 
549
                        init_pattern = false;   // Force reload
 
550
                }
 
551
                else if (strcmp(argv[i], "gen") == 0) {
 
552
                                                // Generate data file suitable
 
553
                                                // for GRhino
 
554
 
 
555
                                                // Pattern data not yet initialized
 
556
                        if (init_pattern == false) {
 
557
                                delete [] pat;
 
558
                                pat = new raw_pattern_info **[PATTERN_UNKNOWN];
 
559
                                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++)
 
560
                                        pat[pp] = 0;
 
561
                        }
 
562
                        pattern_state t(pattern, pat);
 
563
                        if (init_pattern == false) {
 
564
                                load_file(argv[i], t);  // Only load once
 
565
                                init_pattern = true;
 
566
                        }
 
567
 
 
568
                        generate_file(argv[i], t);
 
569
                }
 
570
                else {
 
571
                                                // Command line argument is
 
572
                                                // a filename
 
573
 
 
574
                                                // Pattern data not yet initialized
 
575
                        if (init_pattern == false) {
 
576
                                delete [] pat;
 
577
                                pat = new raw_pattern_info **[PATTERN_UNKNOWN];
 
578
                                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++)
 
579
                                        pat[pp] = 0;
 
580
                        }
 
581
                        pattern_state t(pattern, pat);
 
582
                        if (init_pattern == false) {
 
583
                                load_file(argv[i], t);  // Only load once
 
584
                                init_pattern = true;
 
585
                        }
 
586
 
 
587
                        process_file<game_log>(argv[i], t);
 
588
                        store_file(argv[i], t);         // Store after every processed
 
589
                                                        // file
 
590
                }
 
591
        }
 
592
 
 
593
                                                        // Free allocated memory
 
594
        if (pat) {
 
595
                for (int pp = 0; pp != PATTERN_UNKNOWN; pp++) {
 
596
                                        // In case we are processing only one
 
597
                                        // pattern
 
598
                        if (pat[pp]) {
 
599
                                for (int pos = 0; pos < num_move_index; ++pos) {
 
600
                                        delete [] pat[pp][pos];
 
601
                                }
 
602
                                delete [] pat[pp];
 
603
                        }
 
604
                }
 
605
        }
 
606
        delete [] pat;
 
607
}
 
608
 
 
609
int     main_real(int argc, char *argv[])
 
610
{
 
611
        use_private_files(true);
 
612
        if (argc == 1) {
 
613
                gtout(std::cout, _("%$ %$ - Pattern generator\n")) << prog_name << prog_ver;
 
614
                std::cout << _("(c) 2001, 2002, 2003, 2004, 2005 Kriang Lerdsuwanakij\n\n");
 
615
                gtout(std::cout, _("Usage:   %$ PATTERN init|gen|FILES\n\n")) << prog_name;
 
616
                return 0;
 
617
        }
 
618
        else if (argc < 3)
 
619
                throw std::runtime_error(_("bad arguments"));
 
620
 
 
621
        pattern_t pattern = PATTERN_UNKNOWN;
 
622
        if (strcmp(argv[1], "row1") == 0) {
 
623
                pattern = PATTERN_ROW1;
 
624
        }
 
625
        else if (strcmp(argv[1], "row2") == 0) {
 
626
                pattern = PATTERN_ROW2;
 
627
        }
 
628
        else if (strcmp(argv[1], "row3") == 0) {
 
629
                pattern = PATTERN_ROW3;
 
630
        }
 
631
        else if (strcmp(argv[1], "row4") == 0) {
 
632
                pattern = PATTERN_ROW4;
 
633
        }
 
634
        else if (strcmp(argv[1], "diag1") == 0) {
 
635
                pattern = PATTERN_DIAG1;
 
636
        }
 
637
        else if (strcmp(argv[1], "diag2") == 0) {
 
638
                pattern = PATTERN_DIAG2;
 
639
        }
 
640
        else if (strcmp(argv[1], "diag3") == 0) {
 
641
                pattern = PATTERN_DIAG3;
 
642
        }
 
643
        else if (strcmp(argv[1], "diag4") == 0) {
 
644
                pattern = PATTERN_DIAG4;
 
645
        }
 
646
        else if (strcmp(argv[1], "diag5") == 0) {
 
647
                pattern = PATTERN_DIAG5;
 
648
        }
 
649
        else if (strcmp(argv[1], "edge-x") == 0) {
 
650
                pattern = PATTERN_EDGE_X;
 
651
        }
 
652
        else if (strcmp(argv[1], "corner5x2") == 0) {
 
653
                pattern = PATTERN_CORNER5X2;
 
654
        }
 
655
        else if (strcmp(argv[1], "all") == 0) {
 
656
                ;
 
657
        }
 
658
        else {
 
659
                throw std::runtime_error(_("bad pattern name"));
 
660
        }
 
661
 
 
662
        process_pattern(pattern, argc, argv);
 
663
        return 0;
 
664
}
 
665
 
 
666
int     main(int argc, char *argv[])
 
667
{
 
668
        try {
 
669
                return main_real(argc, argv);
 
670
        }
 
671
        catch (std::exception &e) {
 
672
                std::cout << std::flush;
 
673
                gtout(std::cerr, _("%$: %$\n")) << prog_name << e.what();
 
674
        }
 
675
        catch (const char *s) {
 
676
                std::cout << std::flush;
 
677
                gtout(std::cerr, _("%$: exception %$\n")) << prog_name << s;
 
678
        }
 
679
        catch (...) {
 
680
                std::cout << std::flush;
 
681
                gtout(std::cerr, _("%$: unknown exception\n")) << prog_name;
 
682
        }
 
683
        return 1;
 
684
}