~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-1/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
 
}