~ubuntu-branches/ubuntu/natty/gtkboard/natty

« back to all changes in this revision

Viewing changes to .pc/debian-changes-0.11pre0+cvs.2003.11.02-2/src/stopgate.c

  • Committer: Bazaar Package Importer
  • Author(s): Barak A. Pearlmutter
  • Date: 2011-02-28 11:25:02 UTC
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20110228112502-e9aah248wxelm7ao
Tags: 0.11pre0+cvs.2003.11.02-2
autotools tweaks, most notably -lSDL to supplement -lSDL_mixer

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is a part of gtkboard, a board games system.
 
2
    Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
 
17
 
 
18
*/
 
19
#include <stdio.h>
 
20
#include <stdlib.h>
 
21
#include <string.h>
 
22
#include <assert.h>
 
23
 
 
24
#include "game.h"
 
25
#include "aaball.h"
 
26
 
 
27
#define STOPGATE_CELL_SIZE 40
 
28
#define STOPGATE_NUM_PIECES 4
 
29
 
 
30
#define STOPGATE_BOARD_WID 9
 
31
#define STOPGATE_BOARD_HEIT 9
 
32
 
 
33
char stopgate_colors[6] = {180, 200, 180, 200, 140, 140};
 
34
 
 
35
static char * blue_gate_north_40_xpm [] =
 
36
{
 
37
"40 40 2 1",
 
38
"  c none",
 
39
". c #0000ff",
 
40
"              ............              ",
 
41
"              ............              ",
 
42
"              ............              ",
 
43
"              ............              ",
 
44
"              ............              ",
 
45
"              ............              ",
 
46
"              ............              ",
 
47
"              ............              ",
 
48
"              ............              ",
 
49
"              ............              ",
 
50
"              ............              ",
 
51
"              ............              ",
 
52
"              ............              ",
 
53
"              ............              ",
 
54
"              ............              ",
 
55
"              ............              ",
 
56
"              ............              ",
 
57
"              ............              ",
 
58
"              ............              ",
 
59
"              ............              ",
 
60
"              ............              ",
 
61
"              ............              ",
 
62
"              ............              ",
 
63
"              ............              ",
 
64
"              ............              ",
 
65
"              ............              ",
 
66
"                                        ",
 
67
"                                        ",
 
68
"                                        ",
 
69
"                                        ",
 
70
"                                        ",
 
71
"                                        ",
 
72
"                                        ",
 
73
"                                        ",
 
74
"                                        ",
 
75
"                                        ",
 
76
"                                        ",
 
77
"                                        ",
 
78
"                                        ",
 
79
"                                        ",
 
80
};
 
81
 
 
82
static char * blue_gate_south_40_xpm [] =
 
83
{
 
84
"40 40 2 1",
 
85
"  c none",
 
86
". c #0000ff",
 
87
"                                        ",
 
88
"                                        ",
 
89
"                                        ",
 
90
"                                        ",
 
91
"                                        ",
 
92
"                                        ",
 
93
"                                        ",
 
94
"                                        ",
 
95
"                                        ",
 
96
"                                        ",
 
97
"                                        ",
 
98
"                                        ",
 
99
"                                        ",
 
100
"                                        ",
 
101
"              ............              ",
 
102
"              ............              ",
 
103
"              ............              ",
 
104
"              ............              ",
 
105
"              ............              ",
 
106
"              ............              ",
 
107
"              ............              ",
 
108
"              ............              ",
 
109
"              ............              ",
 
110
"              ............              ",
 
111
"              ............              ",
 
112
"              ............              ",
 
113
"              ............              ",
 
114
"              ............              ",
 
115
"              ............              ",
 
116
"              ............              ",
 
117
"              ............              ",
 
118
"              ............              ",
 
119
"              ............              ",
 
120
"              ............              ",
 
121
"              ............              ",
 
122
"              ............              ",
 
123
"              ............              ",
 
124
"              ............              ",
 
125
"              ............              ",
 
126
"              ............              ",
 
127
};
 
128
 
 
129
static char * blue_gate_east_40_xpm [] =
 
130
{
 
131
"40 40 2 1",
 
132
"  c none",
 
133
". c #0000ff",
 
134
"                                        ",
 
135
"                                        ",
 
136
"                                        ",
 
137
"                                        ",
 
138
"                                        ",
 
139
"                                        ",
 
140
"                                        ",
 
141
"                                        ",
 
142
"                                        ",
 
143
"                                        ",
 
144
"                                        ",
 
145
"                                        ",
 
146
"                                        ",
 
147
"                                        ",
 
148
"              ..........................",
 
149
"              ..........................",
 
150
"              ..........................",
 
151
"              ..........................",
 
152
"              ..........................",
 
153
"              ..........................",
 
154
"              ..........................",
 
155
"              ..........................",
 
156
"              ..........................",
 
157
"              ..........................",
 
158
"              ..........................",
 
159
"              ..........................",
 
160
"                                        ",
 
161
"                                        ",
 
162
"                                        ",
 
163
"                                        ",
 
164
"                                        ",
 
165
"                                        ",
 
166
"                                        ",
 
167
"                                        ",
 
168
"                                        ",
 
169
"                                        ",
 
170
"                                        ",
 
171
"                                        ",
 
172
"                                        ",
 
173
"                                        ",
 
174
};
 
175
 
 
176
static char * blue_gate_west_40_xpm [] =
 
177
{
 
178
"40 40 2 1",
 
179
"  c none",
 
180
". c #0000ff",
 
181
"                                        ",
 
182
"                                        ",
 
183
"                                        ",
 
184
"                                        ",
 
185
"                                        ",
 
186
"                                        ",
 
187
"                                        ",
 
188
"                                        ",
 
189
"                                        ",
 
190
"                                        ",
 
191
"                                        ",
 
192
"                                        ",
 
193
"                                        ",
 
194
"                                        ",
 
195
"..........................              ",
 
196
"..........................              ",
 
197
"..........................              ",
 
198
"..........................              ",
 
199
"..........................              ",
 
200
"..........................              ",
 
201
"..........................              ",
 
202
"..........................              ",
 
203
"..........................              ",
 
204
"..........................              ",
 
205
"..........................              ",
 
206
"..........................              ",
 
207
"                                        ",
 
208
"                                        ",
 
209
"                                        ",
 
210
"                                        ",
 
211
"                                        ",
 
212
"                                        ",
 
213
"                                        ",
 
214
"                                        ",
 
215
"                                        ",
 
216
"                                        ",
 
217
"                                        ",
 
218
"                                        ",
 
219
"                                        ",
 
220
"                                        ",
 
221
};
 
222
 
 
223
 
 
224
char ** stopgate_pixmaps [] = 
 
225
{
 
226
        blue_gate_north_40_xpm,
 
227
        blue_gate_south_40_xpm,
 
228
        blue_gate_east_40_xpm,
 
229
        blue_gate_west_40_xpm,
 
230
};
 
231
 
 
232
 
 
233
#define STOPGATE_NORTH 1
 
234
#define STOPGATE_SOUTH 2
 
235
#define STOPGATE_EAST  3
 
236
#define STOPGATE_WEST  4
 
237
#define STOPGATE_EMPTY 0
 
238
 
 
239
#define abs(x) ((x) < 0 ? -(x) : (x))
 
240
 
 
241
int stopgate_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
242
void stopgate_init ();
 
243
ResultType stopgate_who_won (Pos *, Player, char **);
 
244
ResultType stopgate_eval (Pos *, Player, float *eval);
 
245
byte * stopgate_movegen (Pos *);
 
246
 
 
247
Game Stopgate = { STOPGATE_CELL_SIZE, STOPGATE_BOARD_WID, STOPGATE_BOARD_HEIT, 
 
248
        STOPGATE_NUM_PIECES, 
 
249
        stopgate_colors, NULL, stopgate_pixmaps, "Stopgate", "Nimlike games", stopgate_init};
 
250
 
 
251
static int stopgate_curx = - 1, stopgate_cury = -1;
 
252
 
 
253
 
 
254
void stopgate_init ()
 
255
{
 
256
        game_getmove = stopgate_getmove;
 
257
        game_who_won = stopgate_who_won;
 
258
        game_eval = stopgate_eval;
 
259
        game_movegen = stopgate_movegen;
 
260
        game_white_string = "Vertical";
 
261
        game_black_string = "Horizontally";
 
262
        game_doc_about_status = STATUS_COMPLETE;
 
263
        game_doc_rules = "Two players take turns in placing dominoes on the board. The first player places them vertically and the second horizontally. To place a domino, press the mouse button on a square, drag the mouse to the adjacent square and release the mouse button. The goal is to be the last player to place a domino; the game ends when it becomes obvious who the winner is.";
 
264
        game_doc_strategy = "Make parallel columns of dominoes such that you will be able to play in between the columns but the opponent won't.";
 
265
}
 
266
 
 
267
static int incx[] = { -1, -1, -1, 0, 0, 1, 1, 1};
 
268
static int incy[] = { -1, 0, 1, -1, 1, -1, 0, 1};
 
269
 
 
270
ResultType stopgate_who_won (Pos *pos, Player player, char ** commp)
 
271
{
 
272
        char *who_str[2] = {"Vertical won", "Horizontal won"};
 
273
        int wscore, bscore, i, j;
 
274
        float eval;
 
275
        ResultType result;
 
276
        result = stopgate_eval (pos, player, &eval);
 
277
        if (result == RESULT_WHITE) *commp = who_str[0];
 
278
        if (result == RESULT_BLACK) *commp = who_str[1];
 
279
        return result;
 
280
}
 
281
 
 
282
#define EVAL_ISEMPTY(x, y) ((ISINBOARD((x), (y))) && (board[(y) * board_wid + (x)] == STOPGATE_EMPTY))
 
283
 
 
284
#define EVAL_OPENSQUARE(x, y) (EVAL_ISEMPTY ((x), (y)) && (EVAL_ISEMPTY ((x)-1,(y)) || EVAL_ISEMPTY ((x)+1, (y))) && (EVAL_ISEMPTY ((x),(y)-1) || EVAL_ISEMPTY ((x), (y)+1)))
 
285
 
 
286
enum {
 
287
        REGION_WHITE = STOPGATE_NUM_PIECES + 1, 
 
288
        REGION_BLACK, 
 
289
        REGION_OPEN_X = 1 << 4,
 
290
        REGION_OPEN_Y = 1 << 5,
 
291
};
 
292
 
 
293
 
 
294
 
 
295
static int regions[STOPGATE_BOARD_WID * STOPGATE_BOARD_HEIT];
 
296
 
 
297
/* Find which regions are open, which are vertical (REGION_WHITE) and which
 
298
   are horizontal (REGION_BLACK)
 
299
   clever algo that avoids a queue: every square in an open region must
 
300
   be on a straight line from a square which has unfilled nbrs in both directions
 
301
   */
 
302
static void find_regions (byte *board)
 
303
{
 
304
        int i, j;
 
305
        static int count = 0;
 
306
        for (i=0; i<board_wid*board_heit; i++)
 
307
                regions[i] = 0;
 
308
        for (i=0; i < board_wid; i++)
 
309
        for (j=0; j < board_heit; j++)
 
310
        {
 
311
                int x;
 
312
                if (regions [j * board_wid + i] & REGION_OPEN_X)
 
313
                        continue;
 
314
                if (EVAL_OPENSQUARE (i, j))
 
315
                {
 
316
                        for (x=i; EVAL_ISEMPTY (x, j); x++)
 
317
                                regions [j * board_wid + x] |=  REGION_OPEN_X;
 
318
                        for (x=i; EVAL_ISEMPTY (x, j); x--)
 
319
                                regions [j * board_wid + x] |=  REGION_OPEN_X;
 
320
                }
 
321
        }
 
322
        for (i=0; i < board_wid; i++)
 
323
        for (j=0; j < board_heit; j++)
 
324
        {
 
325
                int y;
 
326
                if (regions [j * board_wid + i] & REGION_OPEN_Y)
 
327
                        continue;
 
328
                if (EVAL_OPENSQUARE (i, j))
 
329
                {
 
330
                        for (y=j; EVAL_ISEMPTY (i, y); y++)
 
331
                                regions [y * board_wid + i] |=  REGION_OPEN_Y;
 
332
                        for (y=j; EVAL_ISEMPTY (i, y); y--)
 
333
                                regions [y * board_wid + i] |=  REGION_OPEN_Y;
 
334
                }
 
335
        }
 
336
        for (i=0; i < board_wid; i++)
 
337
        for (j=0; j < board_heit; j++)
 
338
                if (board [j * board_wid + i] == 0 && regions[j * board_wid + i] == 0)
 
339
                {
 
340
                        if (EVAL_ISEMPTY (i,j+1) || EVAL_ISEMPTY (i,j-1))
 
341
                                regions[j * board_wid + i] = REGION_WHITE;
 
342
                        else if (EVAL_ISEMPTY (i+1,j) || EVAL_ISEMPTY (i-1,j))
 
343
                                regions[j * board_wid + i] = REGION_BLACK;
 
344
                }
 
345
        // TODO: find the lengths of the runs also
 
346
}
 
347
 
 
348
 
 
349
byte * stopgate_movegen (Pos *pos)
 
350
{
 
351
        int i, j;
 
352
        byte movbuf [512], *movp = movbuf, *movlist;
 
353
        byte *board = pos->board;
 
354
        Player player = pos->player;
 
355
        for (i=0; i<board_wid; i++)
 
356
        for (j=0; j<board_heit; j++)
 
357
        {
 
358
                int incx = (player == WHITE ? 0 : 1), incy = (player == WHITE ? 1 : 0);
 
359
                if (board [j * board_wid + i] != STOPGATE_EMPTY) continue;
 
360
                if (!ISINBOARD (i + incx, j + incy)) continue;
 
361
                if (pos->board [(j + incy) * board_wid + (i + incx)] != STOPGATE_EMPTY) continue;
 
362
                if (!EVAL_OPENSQUARE (i, j) && !EVAL_OPENSQUARE (i + incx, j + incy))
 
363
                        continue;
 
364
                *movp++ = i;
 
365
                *movp++ = j;
 
366
                *movp++ = (player == WHITE ? STOPGATE_NORTH : STOPGATE_EAST);
 
367
                *movp++ = i + incx;
 
368
                *movp++ = j + incy;
 
369
                *movp++ = (player == WHITE ? STOPGATE_SOUTH : STOPGATE_WEST);
 
370
                *movp++ = -1;
 
371
        }
 
372
        *movp++ = -2;
 
373
        movlist = (byte *) (malloc (movp - movbuf));
 
374
        memcpy (movlist, movbuf, (movp - movbuf));
 
375
        return movlist;
 
376
}
 
377
 
 
378
 
 
379
ResultType stopgate_eval (Pos *pos, Player player, float *eval)
 
380
{
 
381
        int i, j;
 
382
        float val = 0;
 
383
        gboolean wfound = FALSE, bfound = FALSE, openfound = FALSE;
 
384
        int run_len=0;
 
385
        int run_eval_w = 0, run_eval_b = 0;
 
386
        byte *board = pos->board;
 
387
        find_regions (board);
 
388
        for (i=0; i<board_wid; i++)
 
389
        {
 
390
                for (j=0; j<board_heit; j++)
 
391
                        if (regions[j * board_wid + i] == REGION_WHITE)
 
392
                                run_len++;
 
393
                        else
 
394
                        {
 
395
                                run_eval_w += 2 * (run_len / 2);
 
396
                                run_len = 0;
 
397
                        }
 
398
                run_eval_w += 2 * (run_len / 2);
 
399
                run_len = 0;
 
400
        }
 
401
        for (j=0; j<board_heit; j++)
 
402
        {
 
403
                for (i=0; i<board_wid; i++)
 
404
                        if (regions[j * board_wid + i] == REGION_BLACK)
 
405
                                run_len++;
 
406
                        else
 
407
                        {
 
408
                                run_eval_b += 2 * (run_len / 2);
 
409
                                run_len = 0;
 
410
                        }
 
411
                run_eval_b += 2 * (run_len / 2);
 
412
                run_len = 0;
 
413
        }
 
414
        val = run_eval_w - run_eval_b;
 
415
/*      if (++count == 5000)
 
416
        {
 
417
                count = 0;
 
418
                val = run_eval_w - run_eval_b;
 
419
                printf ("%d, %d\n", run_eval_w, run_eval_b);
 
420
                for (j=board_heit-1; j>=0; j--)
 
421
                {
 
422
                        for (i=0; i<board_wid; i++)
 
423
                        {
 
424
                                if (board [j * board_wid + i])
 
425
                                        printf (" #");
 
426
                                else if (regions[j * board_wid + i] == REGION_WHITE)
 
427
                                        printf (" W");
 
428
                                else if (regions[j * board_wid + i] == REGION_BLACK)
 
429
                                        printf (" B");
 
430
                                else printf (" _");
 
431
                        }
 
432
                        printf ("\n");
 
433
                }
 
434
                printf ("\n");
 
435
        }       
 
436
*/
 
437
        for (i=0; i<board_wid; i++)
 
438
        for (j=0; j<board_heit; j++)
 
439
        {
 
440
                if (board [j * board_wid + i] != STOPGATE_EMPTY) continue;
 
441
                if (regions[j * board_wid + i] == REGION_WHITE)
 
442
                        wfound = TRUE;
 
443
                else if (regions[j * board_wid + i] == REGION_BLACK)
 
444
                        bfound = TRUE;
 
445
                else
 
446
                {
 
447
                        if (EVAL_ISEMPTY (i, j+1) || EVAL_ISEMPTY (i, j-1))
 
448
                        {
 
449
                                val++;
 
450
                                wfound = TRUE;
 
451
                                openfound = TRUE;
 
452
                        }
 
453
                        if (EVAL_ISEMPTY (i+1, j) || EVAL_ISEMPTY (i-1, j))
 
454
                        {
 
455
                                val--;
 
456
                                bfound = TRUE;
 
457
                                openfound = TRUE;
 
458
                        }
 
459
                }
 
460
        }
 
461
        if (!openfound)
 
462
        {
 
463
                val += (player == WHITE ? -1 : 1);
 
464
                *eval = val;
 
465
                return val > 0 ? RESULT_WHITE : RESULT_BLACK;
 
466
        }
 
467
        if (player == WHITE && !wfound)
 
468
        {
 
469
                *eval = (val-1);
 
470
                return RESULT_BLACK;
 
471
        }
 
472
        if (player == BLACK && !bfound)
 
473
        {
 
474
                *eval = (val+1);
 
475
                return RESULT_WHITE;
 
476
        }
 
477
        *eval =  val + 0.01 * random () / RAND_MAX;
 
478
        return RESULT_NOTYET;
 
479
}
 
480
 
 
481
int stopgate_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, 
 
482
                byte **movp, int **rmovp)
 
483
{
 
484
        int i, j, sw_len, found=0;
 
485
        static byte move[128];
 
486
        byte *mp = move;
 
487
        int diffx, diffy, dir1 = -1, dir2 = -1;
 
488
        if (type == GTKBOARD_BUTTON_PRESS)
 
489
        {
 
490
                if (pos->board [y * board_wid + x] != STOPGATE_EMPTY)
 
491
                        return -1;
 
492
                stopgate_curx = x;
 
493
                stopgate_cury = y;
 
494
                return 0;
 
495
        }
 
496
        if (type != GTKBOARD_BUTTON_RELEASE)
 
497
                return 0;
 
498
        if (stopgate_curx < 0) return -1;
 
499
        diffx = x - stopgate_curx;
 
500
        diffy = y - stopgate_cury;
 
501
        if (to_play == WHITE && diffx == 0 && diffy == 1)
 
502
                dir1 = STOPGATE_NORTH, dir2 = STOPGATE_SOUTH;
 
503
        else if (to_play == WHITE && diffx == 0 && diffy == -1)
 
504
                dir1 = STOPGATE_SOUTH, dir2 = STOPGATE_NORTH;
 
505
        else if (to_play == BLACK && diffx == 1 && diffy == 0)
 
506
                dir1 = STOPGATE_EAST, dir2 = STOPGATE_WEST;
 
507
        else if (to_play == BLACK && diffx == -1 && diffy == 0)
 
508
                dir1 = STOPGATE_WEST, dir2 = STOPGATE_EAST;
 
509
        else
 
510
        {
 
511
                stopgate_curx = stopgate_cury = -1;
 
512
                return -1;
 
513
        }
 
514
        if (pos->board [y * board_wid + x] != STOPGATE_EMPTY)
 
515
        {
 
516
                stopgate_curx = stopgate_cury = -1;
 
517
                return -1;
 
518
        }
 
519
        *mp++ = stopgate_curx;
 
520
        *mp++ = stopgate_cury;
 
521
        *mp++ = dir1;
 
522
        *mp++ = x;
 
523
        *mp++ = y;
 
524
        *mp++ = dir2;
 
525
        *mp++ = -1;
 
526
        *movp = move;
 
527
        return 1;
 
528
}
 
529
 
 
530
 
 
531