1
/* This file is a part of gtkboard, a board games system.
2
Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
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.
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.
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
27
#define CHECKERS_CELL_SIZE 40
28
#define CHECKERS_NUM_PIECES 4
30
#define CHECKERS_BOARD_WID 8
31
#define CHECKERS_BOARD_HEIT 8
38
#define CHECKERS_ISKING(x) (x == 1 || x == 3)
39
#define CHECKERS_ISPAWN(x) (x == 2 || x == 4)
41
#define CHECKERS_ISWHITE(x) (x >= 1 && x <= 2)
42
#define CHECKERS_ISBLACK(x) (x >= 3 && x <= 4)
44
char checkers_colors[] =
48
int checkers_init_pos[] =
50
0 , 4 , 0 , 4 , 0 , 4 , 0 , 4 ,
51
4 , 0 , 4 , 0 , 4 , 0 , 4 , 0 ,
52
0 , 4 , 0 , 4 , 0 , 4 , 0 , 4 ,
53
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
54
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
55
2 , 0 , 2 , 0 , 2 , 0 , 2 , 0 ,
56
0 , 2 , 0 , 2 , 0 , 2 , 0 , 2 ,
57
2 , 0 , 2 , 0 , 2 , 0 , 2 , 0 ,
60
static int checkers_max_moves = 200;
63
void checkers_init ();
64
int checkers_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
65
ResultType checkers_who_won (Pos *, Player, char **);
66
byte *checkers_movegen (Pos *);
67
ResultType checkers_eval (Pos *, Player, float *);
68
char ** checkers_get_pixmap (int idx, int color);
69
void checkers_reset_uistate ();
72
{ CHECKERS_CELL_SIZE, CHECKERS_BOARD_WID, CHECKERS_BOARD_HEIT,
74
checkers_colors, checkers_init_pos, NULL, "Checkers", NULL,
79
game_getmove = checkers_getmove;
80
game_movegen = checkers_movegen;
81
game_who_won = checkers_who_won;
82
game_eval = checkers_eval;
83
game_get_pixmap = checkers_get_pixmap;
84
game_reset_uistate = checkers_reset_uistate;
85
game_file_label = FILERANK_LABEL_TYPE_ALPHA;
86
game_rank_label = FILERANK_LABEL_TYPE_NUM | FILERANK_LABEL_DESC;
87
game_allow_flip = TRUE;
88
game_doc_about_status = STATUS_UNPLAYABLE;
92
"Status: Partially implemented (currently unplayable)\n"
93
"URL: "GAME_DEFAULT_URL("checkers");
96
ResultType checkers_who_won (Pos *pos, Player player, char **commp)
98
static char comment[32];
99
char *who_str [2] = { "white won", "black won"};
100
int found_w = 0, found_b = 0;
102
for (i=0; i<board_wid * board_heit; i++)
103
if (CHECKERS_ISWHITE (pos->board[i])) found_w = 1;
104
else if (CHECKERS_ISBLACK (pos->board[i])) found_b = 1;
107
strncpy (comment, who_str[0], 31);
113
strncpy (comment, who_str[1], 31);
117
return RESULT_NOTYET;
120
byte * checkers_movegen (Pos *pos)
122
int i, j, diffx, diffy;
124
byte *movlist, *mp = movbuf;
125
byte *board = pos->board;
126
Player player = pos->player;
127
for (i=0; i<board_wid; i++)
128
for (j=0; j<board_heit; j++)
130
if (player == BLACK && !CHECKERS_ISBLACK(board [j * board_wid + i]))
132
if (player == WHITE && !CHECKERS_ISWHITE(board [j * board_wid + i]))
134
for (diffx = -1; diffx <= 1; diffx += 2)
135
for (diffy = -1; diffy <= 1; diffy += 2)
137
if (CHECKERS_ISPAWN (board [j * board_wid + i])
138
&& diffy != (player == WHITE ? 1 : -1))
140
if (!ISINBOARD(i+diffx, j+diffy)) continue;
141
if (board [(j + diffy) * board_wid + (i + diffx)] != 0)
143
*mp++ = i; *mp++ = j; *mp++ = 0;
144
*mp++ = i + diffx; *mp++ = j + diffy;
145
if ((player == WHITE && (j + diffy) == board_heit - 1)
146
|| (player == BLACK && (j + diffy) == 0))
147
*mp++ = (player == WHITE ? CHECKERS_WK : CHECKERS_BK);
149
*mp++ = board [j * board_wid + i];
152
for (diffx = -2; diffx <= 2; diffx += 4)
153
for (diffy = -2; diffy <= 2; diffy += 4)
156
if (CHECKERS_ISPAWN (board [j * board_wid + i])
157
&& diffy != (player == WHITE ? 2 : -2))
159
if (!ISINBOARD(i+diffx, j+diffy)) continue;
160
if (board [(j + diffy) * board_wid + (i + diffx)] != 0)
162
val = board [(j + diffy/2) * board_wid + i + diffx/2];
163
if ((player == WHITE && !CHECKERS_ISBLACK(val)) ||
164
(player == BLACK && !CHECKERS_ISWHITE (val)))
166
*mp++ = i; *mp++ = j; *mp++ = 0;
167
*mp++ = i + diffx; *mp++ = j + diffy;
168
if ((player == WHITE && (j + diffy) == board_heit - 1)
169
|| (player == BLACK && (j + diffy) == 0))
170
*mp++ = (player == WHITE ? CHECKERS_WK : CHECKERS_BK);
172
*mp++ = board [j * board_wid + i];
173
*mp++ = i + diffx/2; *mp++ = j + diffy/2; *mp++ = 0;
182
movlist = (byte *) (malloc (mp - movbuf));
183
memcpy (movlist, movbuf, (mp - movbuf));
187
ResultType checkers_eval (Pos *pos, Player to_play, float *eval)
191
for (i=0; i<board_wid; i++)
192
for (j=0; j<board_heit; j++)
194
switch (pos->board [j * board_wid + i])
196
case CHECKERS_WK: sum += (5 - fabs ((i-3.5) * (j-3.5)) / 10); break;
197
case CHECKERS_WP: sum += (1 + j / 10.0); break;
198
case CHECKERS_BK: sum -= (5 - fabs ((i-3.5) * (j-3.5)) / 10); break;
199
case CHECKERS_BP: sum -= (1 + (board_heit - 1 - j) / 10.0); break;
203
return RESULT_NOTYET;
207
static int oldx = -1, oldy = -1;
209
void checkers_reset_uistate ()
211
oldx = -1, oldy = -1;
214
int checkers_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play,
215
byte **movp, int ** rmovep)
217
static byte move[10];
220
byte *board = pos->board;
221
if (type != GTKBOARD_BUTTON_RELEASE) return 0;
224
int val = board [y * board_wid + x];
225
if ((CHECKERS_ISWHITE(val) && !(to_play == WHITE)) ||
226
(CHECKERS_ISBLACK(val) && !(to_play == BLACK)))
232
if (x == oldx && y == oldy)
234
oldx = -1; oldy = -1; return 0;
238
if (abs (diffx) == 1)
241
if (abs (diffy) != 1)
242
{ oldx = oldy = -1; return -1;}
243
if (!CHECKERS_ISKING(board [oldy * board_wid + oldx])
244
&& diffy != (to_play == WHITE ? 1 : -1))
245
{ oldx = oldy = -1; return -1;}
246
if (board [y * board_wid + x] != 0)
247
{ oldx = oldy = -1; return -1;}
248
*mp++ = oldx; *mp++ = oldy; *mp++ = 0;
249
*mp++ = x; *mp++ = y;
250
if ((to_play == WHITE && y == board_heit - 1)
251
|| (to_play == BLACK && y == 0))
252
*mp++ = (to_play == WHITE ? CHECKERS_WK : CHECKERS_BK);
254
*mp++ = board [oldy * board_wid + oldx];
260
if (abs (diffx) == 2)
264
if (abs (diffy) != 2)
265
{ oldx = oldy = -1; return -1;}
266
if (!CHECKERS_ISKING(board [oldy * board_wid + oldx])
267
&& diffy != (to_play == WHITE ? 2 : -2))
268
{ oldx = oldy = -1; return -1;}
269
if (board [y * board_wid + x] != 0)
270
{ oldx = oldy = -1; return -1;}
271
val = board [(y-diffy/2) * board_wid + (x-diffx/2)];
272
if ((!CHECKERS_ISWHITE(val) && (to_play == BLACK)) ||
273
(!CHECKERS_ISBLACK(val) && (to_play == WHITE)))
274
{ oldx = oldy = -1; return -1;}
275
*mp++ = oldx; *mp++ = oldy; *mp++ = 0;
276
*mp++ = oldx+diffx/2; *mp++ = oldy+diffy/2; *mp++ = 0;
277
*mp++ = x; *mp++ = y;
278
if ((to_play == WHITE && y == board_heit - 1)
279
|| (to_play == BLACK && y == 0))
280
*mp++ = (to_play == WHITE ? CHECKERS_WK : CHECKERS_BK);
282
*mp++ = board [oldy * board_wid + oldx];
288
{ oldx = oldy = -1; return -1;}
291
char ** checkers_get_pixmap (int idx, int color)
295
static char pixbuf[CHECKERS_CELL_SIZE * (CHECKERS_CELL_SIZE+1)];
296
for(i=0, bg=0;i<3;i++)
297
{ int col = checkers_colors[i+3];
298
if (col<0) col += 256; bg += col * (1 << (16-8*i));}
299
return pixmap_ball_gen (CHECKERS_CELL_SIZE, pixbuf,
300
CHECKERS_ISWHITE(idx) ? 0xffffff : 0x0000ff, bg,
301
(idx == CHECKERS_WP || idx == CHECKERS_BP) ? 8 : 12, 24);