~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/ataxx.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 <string.h>
 
21
#include <assert.h>
 
22
#include <stdlib.h>
 
23
 
 
24
#include "game.h"
 
25
#include "aaball.h"
 
26
 
 
27
#define ATAXX_CELL_SIZE 55
 
28
#define ATAXX_NUM_PIECES 2
 
29
 
 
30
#define ATAXX_BOARD_WID 7
 
31
#define ATAXX_BOARD_HEIT 7
 
32
 
 
33
#define ATAXX_EMPTY 0
 
34
#define ATAXX_WP 1
 
35
#define ATAXX_BP 2
 
36
 
 
37
#define ATAXX_MOVEGEN_PLAUSIBLE 1
 
38
 
 
39
static char ataxx_colors[6] = {140, 160, 140, 200, 200, 200};
 
40
 
 
41
static int ataxx_init_pos [ATAXX_BOARD_WID*ATAXX_BOARD_HEIT] = 
 
42
{
 
43
        1 , 0 , 0 , 0 , 0 , 0 , 2 ,
 
44
        0 , 0 , 0 , 0 , 0 , 0 , 0 ,
 
45
        0 , 0 , 0 , 0 , 0 , 0 , 0 ,
 
46
        0 , 0 , 0 , 0 , 0 , 0 , 0 ,
 
47
        0 , 0 , 0 , 0 , 0 , 0 , 0 ,
 
48
        0 , 0 , 0 , 0 , 0 , 0 , 0 ,
 
49
        2 , 0 , 0 , 0 , 0 , 0 , 1 ,
 
50
};
 
51
 
 
52
void ataxx_init ();
 
53
 
 
54
Game Ataxx = { ATAXX_CELL_SIZE, ATAXX_BOARD_WID, ATAXX_BOARD_HEIT, 
 
55
        ATAXX_NUM_PIECES,
 
56
        ataxx_colors, ataxx_init_pos, NULL, "Ataxx", NULL, ataxx_init};
 
57
 
 
58
ResultType ataxx_eval (Pos *, Player, float *);
 
59
byte *ataxx_movegen (Pos *);
 
60
 
 
61
static int ataxx_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
62
static ResultType ataxx_who_won (Pos *, Player , char **);
 
63
unsigned char * ataxx_get_rgbmap (int, int);
 
64
void ataxx_reset_uistate ();
 
65
 
 
66
 
 
67
static int ataxx_max_moves = 200;
 
68
 
 
69
void ataxx_init ()
 
70
{
 
71
        game_eval = ataxx_eval;
 
72
        game_movegen = ataxx_movegen;
 
73
        game_getmove = ataxx_getmove;
 
74
        game_who_won = ataxx_who_won;
 
75
        game_get_rgbmap = ataxx_get_rgbmap;
 
76
        game_white_string = "Red";
 
77
        game_black_string = "Blue";
 
78
        game_file_label = FILERANK_LABEL_TYPE_ALPHA;
 
79
        game_rank_label = FILERANK_LABEL_TYPE_NUM | FILERANK_LABEL_DESC;
 
80
        game_reset_uistate = ataxx_reset_uistate;
 
81
        game_allow_flip = TRUE;
 
82
        game_doc_about_status = STATUS_COMPLETE;
 
83
        game_doc_about = 
 
84
                "Ataxx\n"
 
85
                "Two player game\n"
 
86
                "Status: Fully implemented\n"
 
87
                "URL: "GAME_DEFAULT_URL("ataxx");
 
88
        game_doc_rules = 
 
89
                "  - The objective of the game is to get as many balls of your color as possible.\n"
 
90
                "  - In each move you must click an existing ball of your color followed by an empty square.\n"
 
91
                "  - The new square should be at a distance of at most 2 from the first square (a diagonal counts as one unit).\n"
 
92
                "  - If the distance is two the first square becomes empty, but not if the distance is 1.\n"
 
93
                "  - In either case all balls adjacent to the new square, if they are the opponent's color, get converted to your color.\n"
 
94
                "  - If one player has no moves the player with more balls wins.\n";
 
95
}
 
96
 
 
97
ResultType ataxx_who_won (Pos *pos, Player to_play, char **commp)
 
98
{
 
99
        static char comment[32];
 
100
        int i, wscore = 0, bscore = 0, who_idx;
 
101
        char *who_str [3] = { "Red won", "Blue won", "its a tie" };
 
102
        byte *move = ataxx_movegen (pos);
 
103
        for (i=0; i<board_wid * board_heit; i++)
 
104
                if (pos->board[i] == ATAXX_WP)
 
105
                        wscore++;
 
106
                else if (pos->board[i] == ATAXX_BP)
 
107
                        bscore++;
 
108
        if (move[0] != -2)
 
109
        {
 
110
                free (move);
 
111
                if (pos->num_moves > ataxx_max_moves)
 
112
                {
 
113
                        fprintf (stderr, "max moves reached\n");
 
114
                        snprintf (comment, 32, "%s", who_str[2]);
 
115
                        *commp = comment;
 
116
                        return RESULT_TIE;
 
117
                }
 
118
                else
 
119
                {
 
120
                        snprintf (comment, 32, "%d : %d", wscore, bscore);
 
121
                        *commp = comment;
 
122
                        return RESULT_NOTYET;
 
123
                }
 
124
        }
 
125
        free (move);
 
126
        if (wscore > bscore) who_idx = 0;
 
127
        else if (wscore < bscore) who_idx = 1;
 
128
        else who_idx = 2;
 
129
        snprintf (comment, 32, "%s (%d : %d)", who_str [who_idx], wscore, bscore);
 
130
        *commp = comment;
 
131
        if (wscore > bscore)
 
132
                return RESULT_WHITE;
 
133
        if (wscore < bscore)
 
134
                return RESULT_BLACK;
 
135
        return RESULT_TIE;
 
136
}
 
137
 
 
138
 
 
139
ResultType ataxx_eval (Pos *pos, Player to_play, float *eval)
 
140
{
 
141
        int i;
 
142
        int wcount, bcount;
 
143
        for (i=0, wcount=0, bcount=0; i<board_wid*board_heit; i++)
 
144
        {
 
145
                if (pos->board[i] == ATAXX_WP) wcount++;
 
146
                if (pos->board[i] == ATAXX_BP) bcount++;
 
147
        }
 
148
        *eval = wcount-bcount;
 
149
        if (!wcount || !bcount) *eval *= GAME_EVAL_INFTY;
 
150
        if (!wcount) return RESULT_BLACK;
 
151
        if (!bcount) return RESULT_WHITE;
 
152
        return RESULT_NOTYET;
 
153
}
 
154
 
 
155
byte *ataxx_movegen (Pos *pos)
 
156
        /* to keep things from getting out of hand, we'll generate only 
 
157
           _plausible_ moves: find the max #flips possible and generate
 
158
           only those moves that lead to at least max-1 flips */
 
159
{
 
160
        int incx[] = { -1, -1, -1, 0, 0, 1, 1, 1};
 
161
        int incy[] = { -1, 0, 1, -1, 1, -1, 0, 1};
 
162
        int incx2[] = { -2, -2, -2, -2, -2, -1, -1, 0, 0, 1, 1, 2, 2, 2, 2, 2};
 
163
        int incy2[] = { -2, -1, 0, 1, 2, -2, 2, -2, 2, -2, 2, -2, -1, 0, 1, 2};
 
164
        int x, y, i, j, newx, newy;
 
165
        Player player = pos->player;
 
166
        byte our = (player == WHITE ? ATAXX_WP : ATAXX_BP);
 
167
        byte other = (player == WHITE ? ATAXX_BP : ATAXX_WP);
 
168
        byte *board = pos->board;
 
169
#ifdef ATAXX_MOVEGEN_PLAUSIBLE
 
170
        int max_nbrs;
 
171
#endif
 
172
        int found = 0;
 
173
        byte movbuf [4096];
 
174
        byte *movp = movbuf;
 
175
        byte *movlist;
 
176
        byte *nbrs;
 
177
        nbrs = (byte *) malloc (board_wid * board_heit * sizeof (byte));
 
178
        assert (nbrs);
 
179
        for (i=0; i<board_wid * board_heit; i++)
 
180
                nbrs[i] = 0;
 
181
        for (x=0; x<board_wid; x++)
 
182
                for (y=0; y<board_heit; y++)
 
183
                {
 
184
                        if (board [y * board_wid + x] != other)
 
185
                                continue;
 
186
                        for (i=0; i<8; i++)
 
187
                        {
 
188
                                newx = x + incx[i];
 
189
                                newy = y + incy[i];
 
190
                                if (newx >= 0 && newy >= 0 
 
191
                                                && newx < board_wid && newy < board_heit)
 
192
                                        nbrs [newy * board_wid + newx] ++;
 
193
                        }
 
194
                }
 
195
#ifdef ATAXX_MOVEGEN_PLAUSIBLE
 
196
        max_nbrs=0;
 
197
        for (x=0; x<board_wid; x++)
 
198
                for (y=0; y<board_heit; y++)
 
199
                if (board[y * board_wid + x] == ATAXX_EMPTY 
 
200
                                && nbrs[y * board_wid + x] > max_nbrs)
 
201
                {
 
202
                        found=0;
 
203
                        for (j=0; j<8; j++)
 
204
                        {
 
205
                                newx = x + incx[j];
 
206
                                newy = y + incy[j];
 
207
                                if (newx >= 0 && newy >= 0 
 
208
                                                && newx < board_wid && newy < board_heit
 
209
                                                && board [newy * board_wid + newx] == our)
 
210
                                {
 
211
                                        max_nbrs = nbrs[y * board_wid + x];
 
212
                                        found=1;
 
213
                                        break;
 
214
                                }
 
215
                        }
 
216
                        /*if (found) continue;
 
217
                        nbrs [y * board_wid + x]--;
 
218
                        if (nbrs[y * board_wid + x] <= max_nbrs) continue;
 
219
                        for (j=0; j<16; j++)
 
220
                        {
 
221
                                newx = x + incx2[j];
 
222
                                newy = y + incy2[j];
 
223
                                if (newx >= 0 && newy >= 0 
 
224
                                                && newx < board_wid && newy < board_heit
 
225
                                                && board [newy * board_wid + newx] == our)
 
226
                                {
 
227
                                        max_nbrs = nbrs[y * board_wid + x];
 
228
                                        break;
 
229
                                }
 
230
                        }*/
 
231
                } 
 
232
#endif
 
233
        for (x=0; x<board_wid; x++)
 
234
                for (y=0; y<board_heit; y++)
 
235
                {
 
236
                        found=0;
 
237
                        if (board [y * board_wid + x] != ATAXX_EMPTY)
 
238
                                continue;
 
239
#ifdef ATAXX_MOVEGEN_PLAUSIBLE
 
240
                        if (nbrs [y * board_wid + x] < max_nbrs - 1)
 
241
                                continue;
 
242
#endif
 
243
                        for (i=0; i<8; i++)
 
244
                        {
 
245
                                newx = x + incx[i];
 
246
                                newy = y + incy[i];
 
247
                                if (newx >= 0 && newy >= 0 
 
248
                                                && newx < board_wid && newy < board_heit)
 
249
                                        if (board [newy * board_wid + newx] == our)
 
250
                                        {
 
251
                                                /* found a same col neighbor */
 
252
                                                found=1;
 
253
                                                break;
 
254
                                        }
 
255
                        }
 
256
                        if (found)
 
257
                        {
 
258
                                *movp++ = x;
 
259
                                *movp++ = y;
 
260
                                *movp++ = our;
 
261
                                for (i=0; i<8; i++)
 
262
                                {
 
263
                                        newx = x + incx[i];
 
264
                                        newy = y + incy[i];
 
265
                                        if (newx >= 0 && newy >= 0 
 
266
                                                        && newx < board_wid && newy < board_heit)
 
267
                                                if (board [newy * board_wid + newx] == other)
 
268
                                                {
 
269
                                                        *movp++ = newx;
 
270
                                                        *movp++ = newy;
 
271
                                                        *movp++ = our;
 
272
                                                }
 
273
                                }
 
274
                                *movp++ = -1;
 
275
                        }       
 
276
                        else
 
277
                        {
 
278
                                for (i=0; i<16; i++)
 
279
                                {
 
280
                                        newx = x + incx2[i];
 
281
                                        newy = y + incy2[i];
 
282
                                        if (!(newx >= 0 && newy >= 0 
 
283
                                                        && newx < board_wid && newy < board_heit))
 
284
                                                continue;
 
285
                                        if (board [newy * board_wid + newx] != our)
 
286
                                                continue;
 
287
                                        *movp++ = x;
 
288
                                        *movp++ = y;
 
289
                                        *movp++ = our;
 
290
                                        *movp++ = newx;
 
291
                                        *movp++ = newy;
 
292
                                        *movp++ = ATAXX_EMPTY;
 
293
                                        for (j=0; j<8; j++)
 
294
                                        {
 
295
                                                newx = x + incx[j];
 
296
                                                newy = y + incy[j];
 
297
                                                if (newx >= 0 && newy >= 0 
 
298
                                                                && newx < board_wid && newy < board_heit)
 
299
                                                        if (board [newy * board_wid + newx] == other)
 
300
                                                        {
 
301
                                                                *movp++ = newx;
 
302
                                                                *movp++ = newy;
 
303
                                                                *movp++ = our;
 
304
                                                        }
 
305
                                        }
 
306
                                        *movp++ = -1;
 
307
                                }
 
308
                        }
 
309
                }
 
310
        *movp++ = -2;
 
311
        movlist = (byte *) (malloc (movp - movbuf));
 
312
        memcpy (movlist, movbuf, (movp - movbuf));
 
313
        free (nbrs);
 
314
        return movlist;
 
315
        
 
316
}
 
317
 
 
318
static int  oldx = -1, oldy = -1;
 
319
 
 
320
void ataxx_reset_uistate ()
 
321
{
 
322
        oldx = -1, oldy = -1;
 
323
}
 
324
 
 
325
int ataxx_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int **rmovep)
 
326
{
 
327
        static byte move[32];
 
328
        static int rmove[4];
 
329
        byte *mptr = move;
 
330
        int *rp = rmove;
 
331
        int diffx, diffy;
 
332
        int other, i;
 
333
        int incx[] = { -1, -1, -1, 0, 0, 1, 1, 1};
 
334
        int incy[] = { -1, 0, 1, -1, 1, -1, 0, 1};
 
335
        if (type != GTKBOARD_BUTTON_RELEASE)
 
336
                return 0;
 
337
        if (oldx == -1)
 
338
        {
 
339
                if (pos->board [y * board_wid + x] != (to_play == WHITE ? ATAXX_WP : ATAXX_BP))
 
340
                        return -1;
 
341
                oldx = x; oldy = y;
 
342
                *rp++ = x;
 
343
                *rp++ = y;
 
344
                *rp++ = RENDER_HIGHLIGHT1;
 
345
                *rp++ = -1;
 
346
                *rmovep = rmove;
 
347
                return 0;
 
348
        }
 
349
 
 
350
        if (x == oldx && y == oldy) 
 
351
        { 
 
352
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
353
                oldx = -1; oldy = -1; return 0; 
 
354
        } 
 
355
        if (pos->board [y * board_wid + x] != ATAXX_EMPTY) 
 
356
        { 
 
357
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
358
                return oldx = oldy = -1; 
 
359
        }
 
360
        diffx = abs (x - oldx); diffy = abs (y - oldy);
 
361
        if (diffx > 2 || diffy > 2) { return oldx = oldy = -1; }
 
362
        if (diffx > 1 || diffy > 1)
 
363
        { *mptr++ = oldx; *mptr++ = oldy; *mptr++ = ATAXX_EMPTY; }
 
364
        other = (to_play == WHITE ? ATAXX_BP : ATAXX_WP);
 
365
        for (i=0; i<8; i++)
 
366
        {
 
367
                int newx = x + incx[i], newy = y + incy[i];
 
368
                if (newx < 0 || newy < 0 || newx >= board_wid || newy >= board_heit)
 
369
                        continue;
 
370
                if (pos->board[newy * board_wid + newx] == other)
 
371
                {
 
372
                        *mptr++ = newx; *mptr++ = newy; 
 
373
                        *mptr++ = (to_play == WHITE ? ATAXX_WP : ATAXX_BP);
 
374
                }
 
375
        }
 
376
        { *mptr++ = x; *mptr++ = y; *mptr++ = 
 
377
                (to_play == WHITE ? ATAXX_WP : ATAXX_BP); }
 
378
        *mptr = -1;
 
379
        if (movp)
 
380
                *movp = move;   
 
381
        *rp++ = oldx;
 
382
        *rp++ = oldy;
 
383
        *rp++ = RENDER_NONE;
 
384
        *rp++ = -1;
 
385
        *rmovep = rmove;
 
386
        oldx = -1; oldy = -1;
 
387
        return 1;
 
388
}
 
389
 
 
390
unsigned char * ataxx_get_rgbmap (int idx, int color)
 
391
{
 
392
        int fg, bg, i;
 
393
        char *colors;
 
394
        static char rgbbuf[3 * ATAXX_CELL_SIZE * ATAXX_CELL_SIZE];
 
395
        colors = ataxx_colors;
 
396
        fg = (idx == ATAXX_WP ? 0xee << 16 : 0xee);
 
397
        if (color == BLACK) colors += 3;
 
398
        for(i=0, bg=0;i<3;i++) 
 
399
        { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
400
        rgbmap_ball_shadow_gen(55, rgbbuf, fg, bg, 17.0, 35.0, 3);
 
401
        return rgbbuf;
 
402
}
 
403