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