~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/antichess.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 <stdlib.h>
 
22
 
 
23
#include "game.h"
 
24
#include "../pixmaps/chess.xpm"
 
25
 
 
26
 
 
27
#define ANTICHESS_CELL_SIZE 54
 
28
#define ANTICHESS_NUM_PIECES 12
 
29
 
 
30
#define ANTICHESS_BOARD_WID 8
 
31
#define ANTICHESS_BOARD_HEIT 8
 
32
 
 
33
#define ANTICHESS_EMPTY 0
 
34
#define ANTICHESS_WK 1
 
35
#define ANTICHESS_WQ 2
 
36
#define ANTICHESS_WR 3
 
37
#define ANTICHESS_WB 4
 
38
#define ANTICHESS_WN 5
 
39
#define ANTICHESS_WP 6
 
40
#define ANTICHESS_BK 7
 
41
#define ANTICHESS_BQ 8
 
42
#define ANTICHESS_BR 9
 
43
#define ANTICHESS_BB 10
 
44
#define ANTICHESS_BN 11
 
45
#define ANTICHESS_BP 12
 
46
 
 
47
#define ANTICHESS_ISWHITE(x) (x >= 1 && x <= 6)
 
48
#define ANTICHESS_ISBLACK(x) (x >= 7 && x <= 12)
 
49
 
 
50
#ifndef abs
 
51
#define abs(x) ((x) < 0 ? -(x) : (x))
 
52
#endif
 
53
 
 
54
static char antichess_colors[] = 
 
55
        {200, 200, 130, 
 
56
        0, 140, 0};
 
57
char antichess_highlight_colors[9] = {0xff, 0, 0};
 
58
 
 
59
static int antichess_init_pos[] = 
 
60
{
 
61
         9 , 11, 10, 8 , 7 , 10, 11, 9  ,
 
62
         12, 12, 12, 12, 12, 12, 12, 12 ,
 
63
         0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
64
         0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
65
         0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
66
         0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
67
         6 , 6 , 6 , 6 , 6 , 6 , 6 , 6  ,
 
68
         3 , 5 , 4 , 2 , 1 , 4 , 5 , 3  ,
 
69
};
 
70
static int antichess_max_moves = 200;
 
71
 
 
72
static char ** antichess_pixmaps[] =
 
73
 
 
74
{
 
75
        chess_wk_54_xpm, 
 
76
        chess_wq_54_xpm, 
 
77
        chess_wr_54_xpm, 
 
78
        chess_wb_54_xpm, 
 
79
        chess_wn_54_xpm, 
 
80
        chess_wp_54_xpm, 
 
81
        chess_bk_54_xpm, 
 
82
        chess_bq_54_xpm, 
 
83
        chess_br_54_xpm, 
 
84
        chess_bb_54_xpm, 
 
85
        chess_bn_54_xpm, 
 
86
        chess_bp_54_xpm,
 
87
};
 
88
 
 
89
 
 
90
 
 
91
void antichess_init ();
 
92
int antichess_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
93
ResultType antichess_who_won (Pos *, Player, char **);
 
94
byte *antichess_movegen (Pos *);
 
95
ResultType antichess_eval (Pos *, Player, float *);
 
96
ResultType antichess_eval_incr (Pos *, Player, byte *, float *);
 
97
        
 
98
Game Antichess = 
 
99
        { ANTICHESS_CELL_SIZE, ANTICHESS_BOARD_WID, ANTICHESS_BOARD_HEIT, 
 
100
        ANTICHESS_NUM_PIECES,
 
101
        antichess_colors, antichess_init_pos, antichess_pixmaps, "Antichess", 
 
102
        "Chess variants",
 
103
        antichess_init};
 
104
 
 
105
Game * plugin_game = &Antichess;
 
106
 
 
107
void antichess_init ()
 
108
{
 
109
        game_getmove = antichess_getmove;
 
110
        game_who_won = antichess_who_won;
 
111
        game_movegen = antichess_movegen;
 
112
        game_eval = antichess_eval;
 
113
//      game_eval_incr = antichess_eval_incr;
 
114
        game_file_label = FILERANK_LABEL_TYPE_ALPHA;
 
115
        game_rank_label = FILERANK_LABEL_TYPE_NUM | FILERANK_LABEL_DESC;
 
116
        game_highlight_colors = antichess_highlight_colors;
 
117
        game_allow_flip = TRUE;
 
118
        game_doc_about_status = STATUS_COMPLETE;
 
119
        game_doc_about = 
 
120
                "Antichess\n"
 
121
                "Two player game\n"
 
122
                "Status: Fully implemented\n"
 
123
                "URL: "GAME_DEFAULT_URL("antichess");
 
124
        game_doc_rules = 
 
125
                "The objective of the game is to force your opponent to capture all your pieces or to stalemate you. What makes this possible is that if you can capture, then you MUST.\n"
 
126
                "\n"
 
127
                "The pieces move as in chess. However:\n"
 
128
                "   - The king is NOT a special piece. No check(mate), no castling. The king can be captured like any other piece.\n"
 
129
                "   - No taking en passant.\n"
 
130
                "   - Pawn promotion is as in chess.\n"
 
131
                "\n"
 
132
                "A couple of notes on the gtkboard implementation of chess and antichess:\n"
 
133
                "   - Drag and drop doesn't work (yet). To make the move 1. e4, you have to click on e2 and then on e4.\n"
 
134
                "   - To promote, after clicking on the pawn and then on the promotion square, you have to click on a third square which indicates which piece you want to promote to. This square should be any one of the squares of the file of that piece. (Thus, to queen, click anywhere on the 'd' file, etc.)";
 
135
}
 
136
 
 
137
static int isfreeline (byte *pos, int oldx, int oldy, int newx, int newy)
 
138
{
 
139
        int x = oldx, y = oldy, dx, dy, diffx = newx - oldx, diffy = newy - oldy;
 
140
        if (abs (diffx) != abs(diffy) && diffx != 0 && diffy != 0)
 
141
                return 0;
 
142
        dx = (diffx ? (diffx / abs (diffx)) : 0);
 
143
        dy = (diffy ? (diffy / abs (diffy)) : 0);
 
144
        for (x+=dx, y+=dy; x != newx || y != newy; x+=dx, y+=dy)
 
145
                if (pos [y * board_wid + x] != 0)
 
146
                        return 0;
 
147
        return 1;       
 
148
}
 
149
 
 
150
static int islegal (Pos *pos, int oldx, int oldy, int x, int y, int player)
 
151
{
 
152
        int piece = pos->board [oldy * board_wid + oldx];
 
153
        byte *board = pos->board;
 
154
        switch (piece)
 
155
        {
 
156
                case ANTICHESS_WK:
 
157
                case ANTICHESS_BK:
 
158
                        {
 
159
                                int diffx = abs (x - oldx), diffy = abs (y - oldy);
 
160
                                return diffx <= 1 && diffy <= 1;
 
161
                        }
 
162
                case ANTICHESS_WQ:
 
163
                case ANTICHESS_BQ:
 
164
                        return isfreeline (board, oldx, oldy, x, y);
 
165
                case ANTICHESS_WR:
 
166
                case ANTICHESS_BR:
 
167
                        if (!isfreeline (board, oldx, oldy, x, y))
 
168
                                return 0;
 
169
                        if (oldx == x || oldy == y)
 
170
                                return 1;
 
171
                        return 0;
 
172
                case ANTICHESS_WB:
 
173
                case ANTICHESS_BB:
 
174
                        if (!isfreeline (board, oldx, oldy, x, y))
 
175
                                return 0;
 
176
                        if (oldx == x || oldy == y)
 
177
                                return 0;
 
178
                        return 1;
 
179
                case ANTICHESS_WN:
 
180
                case ANTICHESS_BN:
 
181
                        {
 
182
                                int diffx = abs (x - oldx), diffy = abs (y - oldy);
 
183
                                if (diffx == 2 && diffy == 1)
 
184
                                        return 1;
 
185
                                if (diffx == 1 && diffy == 2)
 
186
                                        return 1;
 
187
                                return 0;
 
188
                        }
 
189
                case ANTICHESS_WP:
 
190
                        if (board [y * board_wid + x] == 0)
 
191
                                return (x == oldx && (y == oldy + 1 || 
 
192
                                                (y == 3 && oldy == 1 && board [(2*board_wid + x)] == 0)));
 
193
                        return y == oldy + 1  && (x == oldx + 1 || x == oldx - 1) ;
 
194
                case ANTICHESS_BP:
 
195
                        if (board [y * board_wid + x] == 0)
 
196
                                return (x == oldx && (y == oldy - 1 ||
 
197
                                                (y == 4 && oldy == 6 && board [5*board_wid + x] == 0)));
 
198
                        return y == oldy - 1  && (x == oldx + 1 || x == oldx - 1) ;
 
199
                default:
 
200
                        return 1;
 
201
        }
 
202
}
 
203
 
 
204
static int can_capture (Pos *pos, int player)
 
205
{
 
206
        int x1, y1, x2, y2, val;
 
207
        for (x1 = 0; x1 < board_wid; x1++)
 
208
        for (y1 = 0; y1 < board_heit; y1++)
 
209
        {
 
210
                val = pos->board [y1 * board_wid + x1];
 
211
                if (player == WHITE && !ANTICHESS_ISWHITE (val)) continue;
 
212
                if (player == BLACK && !ANTICHESS_ISBLACK (val)) continue;
 
213
                for (x2 = 0; x2 < board_wid; x2++)
 
214
                for (y2 = 0; y2 < board_heit; y2++)
 
215
                {
 
216
                        val = pos->board [y2 * board_wid + x2];
 
217
                        if (player == WHITE && !ANTICHESS_ISBLACK (val)) continue;
 
218
                        if (player == BLACK && !ANTICHESS_ISWHITE (val)) continue;
 
219
                        if (islegal (pos, x1, y1, x2, y2, player)) return 1;
 
220
                }               
 
221
        }
 
222
        return 0;
 
223
}
 
224
 
 
225
static int oppcolor (byte *pos, int oldx, int oldy, int x, int y)
 
226
        /* True if one square is W and the other is B */
 
227
{
 
228
        int oldv = pos [oldy * board_wid + oldx], v = pos [y * board_wid + x];
 
229
        if (ANTICHESS_ISWHITE (oldv) && ANTICHESS_ISBLACK (v)) return 1;
 
230
        if (ANTICHESS_ISBLACK (oldv) && ANTICHESS_ISWHITE (v)) return 1;
 
231
        return 0;
 
232
}
 
233
 
 
234
static int oldx = -1, oldy = -1, oldval = -1;
 
235
static int prom = 0, prom_x, prom_oldx;
 
236
 
 
237
void antichess_free ()
 
238
{
 
239
        oldx = -1, oldy = -1, prom = 0;
 
240
}
 
241
 
 
242
int antichess_getmove (Pos *pos, int x, int y, 
 
243
                GtkboardEventType type, Player player, byte ** movep, int ** rmovep)
 
244
        /* Translate mouse clicks into move */
 
245
{
 
246
        static byte move [7];
 
247
        static int rmove [7];
 
248
        int *rp = rmove;
 
249
        int val;
 
250
        if (type != GTKBOARD_BUTTON_RELEASE)
 
251
                return 0;
 
252
 
 
253
        val = pos->board [y * board_wid + x];
 
254
 
 
255
        if (oldx >= 0 && x == oldx && y == oldy)
 
256
        {
 
257
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
258
                oldx = -1; oldy = -1; return 0;
 
259
        }
 
260
        
 
261
        // if you can capture you must capture
 
262
        if (oldx >= 0 && can_capture (pos, player) && 
 
263
                        !((ANTICHESS_ISWHITE (val) && ANTICHESS_ISBLACK (oldval))
 
264
                         || (ANTICHESS_ISBLACK (val) && ANTICHESS_ISWHITE (oldval))))
 
265
        {
 
266
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
267
                oldx = oldy = -1;
 
268
                return -1;
 
269
        }
 
270
        
 
271
        /* pawn promotion */ 
 
272
        if (prom)
 
273
        {
 
274
                int new_p = -1;
 
275
                prom = 0;
 
276
                switch(x)
 
277
                {
 
278
                        case 0: case 7:
 
279
                                new_p = (player == WHITE ? ANTICHESS_WR : ANTICHESS_BR); break;
 
280
                        case 1: case 6:
 
281
                                new_p = (player == WHITE ? ANTICHESS_WN : ANTICHESS_BN); break;
 
282
                        case 2: case 5:
 
283
                                new_p = (player == WHITE ? ANTICHESS_WB : ANTICHESS_BB); break;
 
284
                        case 3: case 4:
 
285
                                new_p = (player == WHITE ? ANTICHESS_WQ : ANTICHESS_BQ); break;
 
286
                }
 
287
                move[0] = prom_oldx;
 
288
                move[1] = (player == WHITE ? 6 : 1);
 
289
                move[2] = 0;
 
290
                move[3] = prom_x;
 
291
                move[4] = (player == WHITE ? 7 : 0);
 
292
                move[5] = new_p;
 
293
                move[6] = -1;
 
294
                
 
295
                if (movep)
 
296
                        *movep = move;
 
297
                return 1;
 
298
        }
 
299
        if (oldx == -1)
 
300
        {
 
301
                if (val == 0) return -1;
 
302
                if (player == WHITE && !ANTICHESS_ISWHITE (val))
 
303
                        return -1;
 
304
                if (player == BLACK && !ANTICHESS_ISBLACK (val))
 
305
                        return -1;
 
306
                oldx = x; oldy = y, oldval = val;
 
307
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_HIGHLIGHT1; *rp++ = -1; *rmovep = rmove;
 
308
                return 0;
 
309
        }
 
310
        if (player == WHITE && ANTICHESS_ISWHITE (val))
 
311
        {
 
312
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
313
                oldx = -1; oldy = -1;
 
314
                return -1;
 
315
        }
 
316
        if (player == BLACK && ANTICHESS_ISBLACK (val))
 
317
        {
 
318
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
319
                oldx = -1; oldy = -1;
 
320
                return -1;
 
321
        }
 
322
 
 
323
        if (!islegal (pos, oldx, oldy, x, y, player))
 
324
                // FIXME
 
325
                //|| (can_capture (pos, player) && !oppcolor (pos, oldx, oldy, x, y)))
 
326
        {
 
327
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
328
                oldx = -1; oldy = -1;
 
329
                return -1;
 
330
        }
 
331
 
 
332
        /* pawn promotion */
 
333
        if ((oldval == ANTICHESS_WP || oldval == ANTICHESS_BP) &&
 
334
                        (y == 0 || y == board_heit - 1))
 
335
        {
 
336
                prom = 1;
 
337
                prom_oldx = oldx;
 
338
                prom_x = x;
 
339
                *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
340
                oldx = oldy = -1;
 
341
                return 0;
 
342
        }
 
343
 
 
344
        move[0] = oldx; move[1] = oldy; move[2] = 0;
 
345
        move[3] = x; move[4] = y; move[5] = pos->board [oldy * board_wid + oldx];
 
346
        move[6] = -1;
 
347
 
 
348
        *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove;
 
349
        oldx = -1; oldy = -1;
 
350
        
 
351
        if (movep)
 
352
                *movep = move;
 
353
        return 1;
 
354
        /*if (player == WHITE && ANTICHESS_ISWHITE (val))
 
355
                return 0;*/
 
356
}
 
357
 
 
358
static int hasmove (Pos *pos, int player)
 
359
{
 
360
        int x1, y1, x2, y2, val;
 
361
        for (x1 = 0; x1 < board_wid; x1++)
 
362
        for (y1 = 0; y1 < board_heit; y1++)
 
363
        {
 
364
                val = pos->board [y1 * board_wid + x1];
 
365
                if (player == WHITE && !ANTICHESS_ISWHITE (val)) continue;
 
366
                if (player == BLACK && !ANTICHESS_ISBLACK (val)) continue;
 
367
                for (x2 = 0; x2 < board_wid; x2++)
 
368
                for (y2 = 0; y2 < board_heit; y2++)
 
369
                        if (islegal (pos, x1, y1, x2, y2, player)) return 1;
 
370
        }
 
371
        return 0;
 
372
}
 
373
 
 
374
ResultType antichess_who_won (Pos *pos, Player player, char **commp)
 
375
{
 
376
        static char comment[32];
 
377
        char *who_str [3] = { "White won", "Black won", "Draw" };
 
378
        *commp = NULL;
 
379
        if (hasmove (pos, player)) //return RESULT_NOTYET;
 
380
        {
 
381
                if (pos->num_moves > antichess_max_moves)
 
382
                {
 
383
                        fprintf (stderr, "max moves reached\n");
 
384
                        snprintf (comment, 32, "%s", who_str[2]);
 
385
                        *commp = comment;
 
386
                        return RESULT_TIE;
 
387
                }
 
388
                return RESULT_NOTYET;
 
389
        }
 
390
        *commp = comment;
 
391
        if (hasmove (pos, player == WHITE ? BLACK : WHITE))
 
392
        {
 
393
                strncpy (comment, who_str[player == WHITE ? 0 : 1], 31);
 
394
                return player == WHITE ? RESULT_WHITE : RESULT_BLACK;
 
395
        }
 
396
        else 
 
397
        {
 
398
                strncpy (comment, who_str[2], 31);
 
399
                return RESULT_TIE;
 
400
        }
 
401
}
 
402
 
 
403
int antichess_movegen_square (byte *pos, byte **movp, int player,
 
404
                int oldx, int oldy, int x, int y)
 
405
{
 
406
        int val;
 
407
        if (!ISINBOARD(x, y)) return 0;
 
408
        val = pos [y * board_heit + x];
 
409
        if ((player == WHITE && ANTICHESS_ISWHITE (val))
 
410
                || (player == BLACK && ANTICHESS_ISBLACK (val)))
 
411
                return 0;
 
412
        *(*movp)++ = oldx;
 
413
        *(*movp)++ = oldy;
 
414
        *(*movp)++ = 0;
 
415
        *(*movp)++ = x;
 
416
        *(*movp)++ = y;
 
417
        *(*movp)++ = pos [oldy * board_heit + oldx];
 
418
        *(*movp)++ = -1;
 
419
        return 1;
 
420
}
 
421
 
 
422
int antichess_movegen_line (byte *pos, byte **movp, int player,
 
423
                int x, int y, int incx, int incy)
 
424
{
 
425
        int oldx = x, oldy = y;
 
426
        int capture = 0, val;
 
427
        do
 
428
        {
 
429
                if (capture) return 1;
 
430
                x += incx;
 
431
                y += incy;
 
432
                val = pos [y * board_heit + x];
 
433
                if (ISINBOARD (x, y) && oppcolor (pos, oldx, oldy, x, y))
 
434
                        capture = 1;
 
435
        } while (antichess_movegen_square (pos, movp, player, oldx, oldy, x, y));
 
436
        return 0;
 
437
}
 
438
 
 
439
static void antichess_movegen_promote (byte *board, byte **movp, int player,
 
440
                int oldx, int oldy, int x, int y)
 
441
{
 
442
        int i, j;
 
443
        int promote_pieces[2][4] = {
 
444
                {ANTICHESS_WQ, ANTICHESS_WR, ANTICHESS_WB, ANTICHESS_WN},
 
445
                {ANTICHESS_BQ, ANTICHESS_BR, ANTICHESS_BB, ANTICHESS_BN}
 
446
        };
 
447
        i = (player == WHITE ? 0 : 1);
 
448
        for(j=0; j<4; j++) 
 
449
        {
 
450
                *(*movp)++ = oldx;
 
451
                *(*movp)++ = oldy;
 
452
                *(*movp)++ = 0;
 
453
                *(*movp)++ = x;
 
454
                *(*movp)++ = y;
 
455
                *(*movp)++ = promote_pieces[i][j];
 
456
                *(*movp)++ = -1;
 
457
        }
 
458
}
 
459
 
 
460
byte *antichess_movegen (Pos *pos)
 
461
{
 
462
        byte realbuf[4096];
 
463
        byte *realp = realbuf;
 
464
        byte movbuf[4096], *movp = movbuf;
 
465
        byte *movlist;
 
466
        int i, j, k, x, y, capture = 0;
 
467
        int incxr[] = {0, 0, 1, -1};
 
468
        int incyr[] = {1, -1, 0, 0};
 
469
        int incxb[] = {1, 1, -1, -1};
 
470
        int incyb[] = {1, -1, 1, -1};
 
471
        int incxn[] = {2, 2, -2, -2, 1, 1, -1, -1};
 
472
        int incyn[] = {1, -1, 1, -1, 2, -2, 2, -2};
 
473
        byte *board = pos->board;
 
474
        Player player = pos->player;
 
475
        for (i=0; i<board_wid; i++)
 
476
        for (j=0; j<board_heit; j++)
 
477
        {
 
478
                int val = board[j * board_heit + i];
 
479
                if ((player == WHITE && ANTICHESS_ISWHITE (val))
 
480
                        || (player == BLACK && ANTICHESS_ISBLACK (val)))
 
481
                {
 
482
                        switch (val)
 
483
                        {
 
484
                                case ANTICHESS_WP:
 
485
                                        if (ISINBOARD (i, j+1) && board [(j+1) * board_heit + i] == 0)
 
486
                                        {
 
487
                                                if (j == board_heit - 2)
 
488
                                                        antichess_movegen_promote(board, &movp, player,
 
489
                                                                i, j, i, j+1);
 
490
                                                else
 
491
                                                        antichess_movegen_square (board, &movp, player,
 
492
                                                                i, j, i, j+1);
 
493
                                        }
 
494
                                        if (ISINBOARD (i+1, j+1) && 
 
495
                                                        ANTICHESS_ISBLACK (board [(j+1) * board_heit + i+1]))
 
496
                                        {
 
497
                                                if (j == board_heit - 2)
 
498
                                                        antichess_movegen_promote (board, &movp, player,
 
499
                                                                i, j, i+1, j+1);
 
500
                                                else
 
501
                                                        antichess_movegen_square (board, &movp, player,
 
502
                                                                i, j, i+1, j+1);
 
503
                                                capture ++;
 
504
                                        }
 
505
                                        if (ISINBOARD (i-1, j+1) && 
 
506
                                                        ANTICHESS_ISBLACK (board [(j+1) * board_heit + i-1]))
 
507
                                        {
 
508
                                                if (j == board_heit - 2)
 
509
                                                        antichess_movegen_promote (board, &movp, player,
 
510
                                                                i, j, i-1, j+1);
 
511
                                                else
 
512
                                                        antichess_movegen_square (board, &movp, player,
 
513
                                                                i, j, i-1, j+1);
 
514
                                                capture ++;
 
515
                                        }
 
516
                                        if (j == 1 && board [2 * board_heit + i] == 0
 
517
                                                        && board [3 * board_heit + i] == 0)
 
518
                                                antichess_movegen_square (board, &movp, player,
 
519
                                                                i, j, i, j+2);
 
520
                                        break;
 
521
                                case ANTICHESS_BP:
 
522
                                        if (ISINBOARD (i, j-1) && board [(j-1) * board_heit + i] == 0)
 
523
                                        {
 
524
                                                if (j == 1)
 
525
                                                        antichess_movegen_promote (board, &movp, player,
 
526
                                                                i, j, i, j-1);
 
527
                                                else
 
528
                                                        antichess_movegen_square (board, &movp, player,
 
529
                                                                i, j, i, j-1);
 
530
                                        }
 
531
                                        if (ISINBOARD (i+1, j-1) && 
 
532
                                                        ANTICHESS_ISWHITE (board [(j-1) * board_heit + i+1]))
 
533
                                        {
 
534
                                                if (j == 1)
 
535
                                                        antichess_movegen_promote (board, &movp, player,
 
536
                                                                i, j, i+1, j-1);
 
537
                                                else
 
538
                                                        antichess_movegen_square (board, &movp, player,
 
539
                                                                i, j, i+1, j-1);
 
540
                                                capture ++;
 
541
                                        }
 
542
                                        if (ISINBOARD (i-1, j-1) && 
 
543
                                                        ANTICHESS_ISWHITE (board [(j-1) * board_heit + i-1]))
 
544
                                        {
 
545
                                                if (j == 1)
 
546
                                                        antichess_movegen_promote (board, &movp, player,
 
547
                                                                i, j, i-1, j-1);
 
548
                                                else
 
549
                                                        antichess_movegen_square (board, &movp, player,
 
550
                                                                i, j, i-1, j-1);
 
551
                                                capture ++;
 
552
                                        }
 
553
                                        if (j == 6 && board [5 * board_heit + i] == 0
 
554
                                                        && board [4 * board_heit + i] == 0)
 
555
                                                antichess_movegen_square (board, &movp, player,
 
556
                                                                i, j, i, j-2);
 
557
                                        break;
 
558
                                case ANTICHESS_WK:
 
559
                                case ANTICHESS_BK:
 
560
                                        for (k=0; k<4; k++)
 
561
                                        {
 
562
                                                antichess_movegen_square(board, &movp, player, 
 
563
                                                                i, j, i + incxr[k], j + incyr[k]);
 
564
                                                if (ISINBOARD(i + incxr[k], j + incyr[k]) 
 
565
                                                                && oppcolor (board, i, j, i+incxr[k], j+incyr[k]))
 
566
                                                        capture ++;
 
567
                                        }
 
568
                                        for (k=0; k<4; k++)
 
569
                                        {
 
570
                                                antichess_movegen_square(board, &movp, player, 
 
571
                                                                i, j, i + incxb[k], j + incyb[k]);
 
572
                                                if (ISINBOARD(i + incxb[k], j + incyb[k]) 
 
573
                                                                && oppcolor (board, i, j, i+incxb[k], j+incyb[k]))
 
574
                                                        capture ++;
 
575
                                        }
 
576
                                        break;
 
577
                                case ANTICHESS_WB:
 
578
                                case ANTICHESS_BB:
 
579
                                        for (k=0; k<4; k++)
 
580
                                                capture += antichess_movegen_line (board, &movp, player, 
 
581
                                                                i, j, incxb[k], incyb[k]);
 
582
                                        break;
 
583
                                case ANTICHESS_WR:
 
584
                                case ANTICHESS_BR:
 
585
                                        for (k=0; k<4; k++)
 
586
                                                capture += antichess_movegen_line (board, &movp, player, 
 
587
                                                                i, j, incxr[k], incyr[k]);
 
588
                                        break;
 
589
                                case ANTICHESS_WQ:
 
590
                                case ANTICHESS_BQ:
 
591
                                        for (k=0; k<4; k++)
 
592
                                                capture += antichess_movegen_line (board, &movp, player, 
 
593
                                                                i, j, incxb[k], incyb[k]);
 
594
                                        for (k=0; k<4; k++)
 
595
                                                capture += antichess_movegen_line (board, &movp, player, 
 
596
                                                                i, j, incxr[k], incyr[k]);
 
597
                                        break;
 
598
                                case ANTICHESS_WN:
 
599
                                case ANTICHESS_BN:
 
600
                                        for (k=0; k<8; k++)
 
601
                                        {
 
602
                                                antichess_movegen_square(board, &movp, player, 
 
603
                                                                i, j, i + incxn[k], j + incyn[k]);
 
604
                                                if (ISINBOARD(i + incxn[k], j + incyn[k]) 
 
605
                                                                && oppcolor (board, i, j, i+incxn[k], j+incyn[k]))
 
606
                                                        capture ++;
 
607
                                        }
 
608
                                        break;
 
609
                        }
 
610
                }
 
611
        }
 
612
        *movp++ = -2;
 
613
 
 
614
        /* if there is a capture eliminate all other moves */
 
615
        if (!capture)
 
616
        {
 
617
                movlist = (byte *) malloc (movp - movbuf);
 
618
                memcpy (movlist, movbuf, movp - movbuf);
 
619
                return movlist;
 
620
        }
 
621
        movp = movbuf;
 
622
        realp = realbuf;
 
623
        while (1)
 
624
        {
 
625
                byte *tmp;
 
626
                int w = 0, b = 0;
 
627
                if (*movp == -2)
 
628
                        break;
 
629
                /* a capture is a move that involves a W as well as a B piece */
 
630
                for (tmp = movp; *tmp != -1; tmp += 3)
 
631
                {
 
632
                        if (ANTICHESS_ISWHITE (board [tmp[1] * board_heit + tmp[0]]))   w = 1;
 
633
                        if (ANTICHESS_ISBLACK (board [tmp[1] * board_heit + tmp[0]]))   b = 1;
 
634
                }
 
635
                if (w && b)
 
636
                {
 
637
                        while (*movp != -1)
 
638
                        {
 
639
                                *realp++ = *movp++;
 
640
                                *realp++ = *movp++;
 
641
                                *realp++ = *movp++;
 
642
                        }
 
643
                        *realp++ = *movp++;
 
644
                }
 
645
                else 
 
646
                        movp = tmp+1;
 
647
        }
 
648
        *realp++ = -2;
 
649
        movlist = (byte *) malloc (realp - realbuf);
 
650
        memcpy (movlist, realbuf, realp - realbuf);
 
651
        return movlist;
 
652
}
 
653
 
 
654
// True if this square is a pawn and it can move
 
655
static gboolean eval_pawn_has_move (byte *board, int i, int j)
 
656
{
 
657
        int val = board [j * board_wid + i];
 
658
        int x, y;
 
659
        if (val == ANTICHESS_WP) y = j+1;
 
660
        else if (val == ANTICHESS_BP) y = j-1;
 
661
        else return FALSE;
 
662
 
 
663
        if (board [y * board_wid + i] == ANTICHESS_EMPTY) return TRUE;
 
664
        
 
665
        for (x=i-1; x<=i+1; x+=2)
 
666
        {
 
667
                if (x < 0 || x >= board_wid) continue;
 
668
                if (val == ANTICHESS_WP && ANTICHESS_ISBLACK (board [y * board_wid + x]))
 
669
                        return TRUE;
 
670
                if (val == ANTICHESS_BP && ANTICHESS_ISWHITE (board [y * board_wid + x]))
 
671
                        return TRUE;
 
672
        }
 
673
 
 
674
        return FALSE;   
 
675
}
 
676
 
 
677
ResultType antichess_eval (Pos * pos, Player player, float *eval)
 
678
{
 
679
        int wsum = 0, bsum = 0, i, j;
 
680
        gboolean wfound = FALSE, bfound = FALSE;
 
681
        for (i=0; i < board_wid; i++)
 
682
        for (j=0; j < board_heit; j++)
 
683
                if (ANTICHESS_ISWHITE (pos->board[j * board_wid + i]))
 
684
                {
 
685
                        wsum++;
 
686
                        if (!wfound && eval_pawn_has_move (pos->board, i, j))
 
687
                                wfound = TRUE;
 
688
                                
 
689
                }
 
690
                else if (ANTICHESS_ISBLACK (pos->board[j * board_wid + i]))
 
691
                {
 
692
                        bsum++;
 
693
                        if (!bfound && eval_pawn_has_move (pos->board, i, j))
 
694
                                bfound = TRUE;
 
695
                }
 
696
        
 
697
        if (wsum == 0 || (!wfound && bfound && player == WHITE))
 
698
        {
 
699
                *eval = GAME_EVAL_INFTY;
 
700
                return RESULT_WHITE;
 
701
        }
 
702
        if (bsum == 0 || (!bfound && wfound && player == BLACK))
 
703
        {
 
704
                *eval = -GAME_EVAL_INFTY;
 
705
                return RESULT_BLACK;
 
706
        }
 
707
        if (!wfound && !bfound)
 
708
        {
 
709
                *eval = 0;
 
710
                return RESULT_TIE;
 
711
        }
 
712
        *eval = bsum - wsum;
 
713
        return RESULT_NOTYET;
 
714
}
 
715
 
 
716
ResultType antichess_eval_incr (Pos *pos, Player player, byte *move, float *eval)
 
717
        // check if there's a capture
 
718
{
 
719
        byte *board = pos->board;
 
720
        if (player == WHITE)
 
721
        {
 
722
                if (move[2] && board[move[1] * board_wid + move[0]]) *eval = -1;
 
723
                else if (move[5] && board[move[4] * board_wid + move[3]]) return -1;
 
724
                else *eval = 0;
 
725
        }
 
726
        else
 
727
        {
 
728
                if (move[2] && board[move[1] * board_wid + move[0]]) *eval = 1;
 
729
                else if (move[5] && board[move[4] * board_wid + move[3]]) *eval = 1;
 
730
                else *eval = 0;
 
731
        }
 
732
        return RESULT_NOTYET;
 
733
}