~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/dotsandboxes.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 DNB_CELL_SIZE 24
 
28
#define DNB_NUM_PIECES 5
 
29
 
 
30
#define DNB_BOARD_SIZE 10
 
31
 
 
32
#define DNB_BOARD_WID (2*DNB_BOARD_SIZE+1)
 
33
#define DNB_BOARD_HEIT (2*DNB_BOARD_SIZE+1)
 
34
 
 
35
char dnb_colors[6] = {220, 220, 220, 220, 220, 220};
 
36
 
 
37
static char * dnb_red_24_xpm [] =
 
38
{
 
39
"24 24 1 1",
 
40
"  c #ee0000",
 
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
static char * dnb_blue_24_xpm [] =
 
68
{
 
69
"24 24 1 1",
 
70
"  c #0000ee",
 
71
"                        ",
 
72
"                        ",
 
73
"                        ",
 
74
"                        ",
 
75
"                        ",
 
76
"                        ",
 
77
"                        ",
 
78
"                        ",
 
79
"                        ",
 
80
"                        ",
 
81
"                        ",
 
82
"                        ",
 
83
"                        ",
 
84
"                        ",
 
85
"                        ",
 
86
"                        ",
 
87
"                        ",
 
88
"                        ",
 
89
"                        ",
 
90
"                        ",
 
91
"                        ",
 
92
"                        ",
 
93
"                        ",
 
94
"                        ",
 
95
};
 
96
 
 
97
static char * dnb_vertical_24_xpm [] =
 
98
{
 
99
"24 24 2 1",
 
100
"  c none",
 
101
". c #101010",
 
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
static char * dnb_horizontal_24_xpm [] =
 
129
{
 
130
"24 24 2 1",
 
131
"  c none",
 
132
". c #101010",
 
133
"                        ",
 
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
/*char ** dnb_pixmaps [] = 
 
161
{
 
162
        blue_gate_horiz_40_xpm,
 
163
        blue_gate_south_40_xpm,
 
164
        blue_gate_east_40_xpm,
 
165
        blue_gate_west_40_xpm,
 
166
};*/
 
167
 
 
168
 
 
169
#define DNB_EMPTY 0
 
170
#define DNB_DOT   1
 
171
#define DNB_HOR   2
 
172
#define DNB_VERT  3
 
173
#define DNB_RED   4
 
174
#define DNB_BLUE  5
 
175
 
 
176
#define abs(x) ((x) < 0 ? -(x) : (x))
 
177
 
 
178
int dnb_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
179
void dnb_search (Pos *pos, byte **movp);
 
180
void dnb_init ();
 
181
ResultType dnb_who_won (Pos *, Player, char **);
 
182
void dnb_set_init_pos (Pos *pos);
 
183
char ** dnb_get_pixmap (int idx, int color);
 
184
int dnb_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, 
 
185
                byte **movp, int **rmovp);
 
186
static void dnb_get_render (Pos *pos, byte *move, int **rmovp);
 
187
 
 
188
Game Dnb = { DNB_CELL_SIZE, DNB_BOARD_WID, DNB_BOARD_HEIT, 
 
189
        DNB_NUM_PIECES, dnb_colors, NULL, NULL, "Dots and Boxes", "Nimlike games", dnb_init};
 
190
 
 
191
static int dnb_curx = - 1, dnb_cury = -1;
 
192
 
 
193
 
 
194
void dnb_init ()
 
195
{
 
196
//      game_getmove = dnb_getmove;
 
197
/*      game_who_won = dnb_who_won;
 
198
        game_eval = dnb_eval;
 
199
        game_movegen = dnb_movegen;
 
200
*/
 
201
        game_set_init_pos = dnb_set_init_pos;
 
202
        game_get_pixmap = dnb_get_pixmap;
 
203
        game_get_render = dnb_get_render;
 
204
        game_white_string = "Red";
 
205
        game_black_string = "Blue";
 
206
        game_getmove = dnb_getmove;
 
207
        game_search = dnb_search;
 
208
        game_allow_flip = TRUE;
 
209
        game_doc_about_status = STATUS_UNPLAYABLE;
 
210
        game_doc_about = 
 
211
                "Dots and boxes\n"
 
212
                "Two player game\n"
 
213
                "Status: partially implemented (the AI is totally dumb)\n"
 
214
                "URL: "GAME_DEFAULT_URL ("dnb");
 
215
}
 
216
 
 
217
char ** dnb_get_pixmap (int idx, int color)
 
218
{
 
219
        int bg, i;
 
220
        char *colors = dnb_colors;
 
221
        static char pixbuf[DNB_CELL_SIZE * (DNB_CELL_SIZE+1)];
 
222
        if (color == BLACK) colors += 3;
 
223
        for(i=0, bg=0;i<3;i++) 
 
224
        { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
225
        if (idx == DNB_DOT)
 
226
                return pixmap_ball_gen (DNB_CELL_SIZE, pixbuf, 0x101010, bg, 8, 30);
 
227
        if (idx == DNB_VERT) return dnb_vertical_24_xpm;
 
228
        if (idx == DNB_HOR) return dnb_horizontal_24_xpm;
 
229
        if (idx == DNB_RED) return dnb_red_24_xpm;
 
230
        if (idx == DNB_BLUE) return dnb_blue_24_xpm;
 
231
        return NULL;
 
232
}
 
233
 
 
234
void dnb_set_init_pos (Pos *pos)
 
235
{
 
236
        int i, j;
 
237
        for (i=0; i<board_wid; i++)
 
238
        for (j=0; j<board_heit; j++)
 
239
                if (i%2 == 0 && j%2 == 0)
 
240
                        pos->board[j * board_wid + i] = DNB_DOT;
 
241
                else
 
242
                        pos->board[j * board_wid + i] = DNB_EMPTY;
 
243
}
 
244
 
 
245
/*
 
246
ResultType dnb_who_won (Pos *pos, Player player, char ** commp)
 
247
{
 
248
        char *who_str[2] = {"Vertical won", "Horizontal won"};
 
249
        int wscore, bscore, i, j;
 
250
        float eval;
 
251
        ResultType result;
 
252
        result = dnb_eval (pos, player, &eval);
 
253
        if (result == RESULT_WHITE) *commp = who_str[0];
 
254
        if (result == RESULT_BLACK) *commp = who_str[1];
 
255
        printf ("%f\n", eval);
 
256
        return result;
 
257
}
 
258
*/
 
259
 
 
260
static int dnb_incx[] = {-1, 0, 0, 1};
 
261
static int dnb_incy[] = {0, -1, 1, 0};
 
262
 
 
263
static int num_nbr_walls (byte *board, int *render, int x, int y)
 
264
{
 
265
        int k, newx, newy;
 
266
        int count;
 
267
        if (x % 2 == 0 || y % 2 == 0)
 
268
                return -1;
 
269
        for (k=0, count=0; k<4; k++)
 
270
        {
 
271
                newx = x + dnb_incx[k];
 
272
                newy = y + dnb_incy[k];
 
273
                if (board [newy * board_wid + newx] != DNB_EMPTY ||
 
274
                                (render && render[newy * board_wid + newx] != RENDER_NONE))
 
275
                        count++;
 
276
        }
 
277
        return count;
 
278
}
 
279
 
 
280
int dnb_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player player, 
 
281
                byte **movp, int **rmovp)
 
282
{
 
283
        int incx, incy;
 
284
        int newx, newy;
 
285
        static byte move[2048];
 
286
        static int rmove[16];   
 
287
        byte *mp = move;
 
288
        int *rp = rmove;
 
289
        int i, j, k;
 
290
        gboolean found;
 
291
        
 
292
        if (type == GTKBOARD_BUTTON_PRESS)
 
293
        {
 
294
                if (pos->board [y * board_wid + x] != DNB_DOT)
 
295
                        return -1;
 
296
                dnb_curx = x;
 
297
                dnb_cury = y;
 
298
                return 0;
 
299
        }
 
300
        
 
301
        if (type != GTKBOARD_BUTTON_RELEASE)
 
302
                return 0;
 
303
        
 
304
        if (dnb_curx < 0) return -1;
 
305
        
 
306
        if ((x != dnb_curx && y != dnb_cury) || (x == dnb_curx && y == dnb_cury))
 
307
                { dnb_curx = dnb_cury = -1;     return -1; }
 
308
 
 
309
        if (x == dnb_curx)
 
310
        {
 
311
                incx = 0;
 
312
                incy = y > dnb_cury ? 1 : -1;
 
313
        }
 
314
        else
 
315
        {
 
316
                incy = 0;
 
317
                incx = x > dnb_curx ? 1 : -1;
 
318
        }
 
319
        
 
320
        newx = dnb_curx + incx;
 
321
        newy = dnb_cury + incy;
 
322
        if (pos->board [newy * board_wid + newx] != DNB_EMPTY || 
 
323
                        pos->render [newy * board_wid + newx] != RENDER_NONE)
 
324
        { dnb_curx = dnb_cury = -1; return -1; }
 
325
        
 
326
        *rp++ = newx;
 
327
        *rp++ = newy;
 
328
        *rp++ = RENDER_REPLACE | ((dnb_curx == x ? DNB_VERT : DNB_HOR) << 8);
 
329
        dnb_curx = dnb_cury = -1;
 
330
 
 
331
        // do we complete a square
 
332
        found = FALSE;
 
333
        for (k=0; k<4; k++)
 
334
        {
 
335
                x = newx + dnb_incx[k];
 
336
                y = newy + dnb_incy[k];
 
337
                if (pos->board [y * board_wid + x] == DNB_EMPTY)
 
338
                        if (num_nbr_walls (pos->board, pos->render, x, y) == 3)
 
339
                        {
 
340
                                *rp++ = x;
 
341
                                *rp++ = y;
 
342
                                *rp++ = RENDER_REPLACE | ((player == WHITE ? DNB_RED : DNB_BLUE) << 8);
 
343
                                found = TRUE;
 
344
                        }
 
345
        }
 
346
        *rp++ = -1;
 
347
        if (found)
 
348
        {
 
349
                *rmovp = rmove;
 
350
                return 0;
 
351
        }
 
352
 
 
353
        else
 
354
        {
 
355
                for (i=0; rmove[3*i] >= 0; i++)
 
356
                        if ((rmove [3*i+2] & 0xff) == RENDER_REPLACE)
 
357
                        {
 
358
                                *mp++ = rmove [3*i];
 
359
                                *mp++ = rmove [3*i+1];
 
360
                                *mp++ = rmove [3*i+2] >> 8;
 
361
                        }
 
362
                for (i=0; i<board_wid; i++)
 
363
                for (j=0; j<board_heit; j++)
 
364
                        if ((pos->render [j * board_wid + i] & 0xff) == RENDER_REPLACE)
 
365
                        {
 
366
                                *mp++ = i;
 
367
                                *mp++ = j;
 
368
                                *mp++ = pos->render [j * board_wid + i] >> 8;
 
369
                        }
 
370
                *mp++ = -1;
 
371
                *movp = move;
 
372
                return 1;
 
373
        }
 
374
}
 
375
 
 
376
static void dnb_get_render (Pos *pos, byte *move, int **rmovp)
 
377
{
 
378
        static int rmove[2048];
 
379
        int *rp = rmove;
 
380
        int i, j;
 
381
        for (i=0; i<board_wid; i++)
 
382
        for (j=0; j<board_heit; j++)
 
383
                if (pos->render [j * board_wid + i] != RENDER_NONE)
 
384
                {
 
385
                        *rp++ = i;
 
386
                        *rp++ = j;
 
387
                        *rp++ = RENDER_NONE;
 
388
                }
 
389
        *rp++ = -1;
 
390
        *rmovp = rmove;
 
391
}
 
392
 
 
393
 
 
394
void dnb_search (Pos *pos, byte **movp)
 
395
{
 
396
        /* first greedily close all possible squares, then choose some edge arbitrarily */
 
397
        // TODO: this AI needs MAJOR improvement
 
398
        static byte move[2048];
 
399
        byte *mp = move;
 
400
        int i, j;
 
401
        gboolean found;
 
402
        static byte newboard[DNB_BOARD_WID * DNB_BOARD_HEIT];
 
403
        Player player = pos->player;
 
404
        memcpy (newboard, pos->board, board_wid * board_heit);
 
405
        
 
406
        do // very slow, but speed probably doesn't matter here
 
407
        {
 
408
                found = FALSE;
 
409
                for (i=1; i<board_wid; i+=2)
 
410
                for (j=1; j<board_heit; j+=2)
 
411
                        if (num_nbr_walls (newboard, NULL, i, j) == 3)
 
412
                        {
 
413
                                int k, newx, newy, newval;
 
414
                                for (k=0; k<4; k++)
 
415
                                {
 
416
                                        newx = i + dnb_incx[k];
 
417
                                        newy = j + dnb_incy[k];
 
418
                                        if (newboard [newy * board_wid + newx] == DNB_EMPTY)
 
419
                                        {
 
420
                                                newval = (newx % 2 == 0 ? DNB_VERT : DNB_HOR);
 
421
                                                *mp++ = newx;
 
422
                                                *mp++ = newy;
 
423
                                                *mp++ = newval;
 
424
                                                newboard [newy * board_wid + newx] = newval;
 
425
                                        }
 
426
                                }
 
427
                                newval = (player == WHITE ? DNB_RED : DNB_BLUE);
 
428
                                *mp++ = i;
 
429
                                *mp++ = j;
 
430
                                *mp++ = newval;
 
431
                                newboard [j * board_wid + i] = newval;
 
432
                                found = TRUE;
 
433
                        }
 
434
        } while (found);
 
435
 
 
436
        while (1) // FIXME: inf. loop when game is over
 
437
        {
 
438
                i = random() % board_wid;
 
439
                j = random() % board_heit;
 
440
                if ((i+j) % 2 == 0) continue;
 
441
                if (newboard [j * board_wid + i] != DNB_EMPTY) continue;
 
442
                *mp++ = i;
 
443
                *mp++ = j;
 
444
                *mp++ = (i % 2 == 0 ? DNB_VERT : DNB_HOR);
 
445
                *mp++ = -1;
 
446
                *movp = move;
 
447
                return;
 
448
        }
 
449
}