This is the doxygen documentation for gtkboard.
.00001 /* This file is a part of gtkboard, a board games system. 00002 Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net> 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA 00017 00018 */ 00019 #include <stdio.h> 00020 #include <string.h> 00021 #include <assert.h> 00022 #include <stdlib.h> 00023 00024 #include "game.h" 00025 #include "aaball.h" 00026 00027 #define QUARTO_CELL_SIZE 60 00028 #define QUARTO_NUM_PIECES 17 00029 00030 #define QUARTO_BOARD_WID 9 00031 #define QUARTO_BOARD_HEIT 4 00032 00033 #define QUARTO_EMPTY 0 00034 #define QUARTO_SEPARATOR 17 00035 00036 #define QUARTO_SHAPE_MASK (1 << 0) 00037 #define QUARTO_SIZE_MASK (1 << 1) 00038 #define QUARTO_HOLE_MASK (1 << 2) 00039 #define QUARTO_COLOR_MASK (1 << 3) 00040 #define QUARTO_ALL_PIECES_MASK (QUARTO_SHAPE_MASK | QUARTO_SIZE_MASK | QUARTO_HOLE_MASK | QUARTO_COLOR_MASK) 00041 00042 char quarto_colors[9] = {200, 200, 200, 200, 200, 200, 0, 0, 0}; 00043 00044 char quarto_highlight_colors[9] = {0, 0xff, 0, 0, 0, 0, 0, 0, 0}; 00045 00046 int quarto_init_pos[QUARTO_BOARD_HEIT * QUARTO_BOARD_WID] = 00047 { 00048 0, 0, 0, 0, 17, 1, 2, 3, 4, 00049 0, 0, 0, 0, 17, 5, 6, 7, 8, 00050 0, 0, 0, 0, 17, 9, 10, 11, 12, 00051 0, 0, 0, 0, 17, 13, 14, 15, 16, 00052 }; 00053 00054 00055 00056 void quarto_init (); 00057 00058 Game Quarto = { QUARTO_CELL_SIZE, QUARTO_BOARD_WID, QUARTO_BOARD_HEIT, 00059 QUARTO_NUM_PIECES, 00060 quarto_colors, quarto_init_pos, NULL, "Quarto", quarto_init}; 00061 00062 00063 static int quarto_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **); 00064 static ResultType quarto_who_won (Pos *, Player, char **); 00065 void quarto_init (void); 00066 static byte * quarto_movegen (Pos *); 00067 static ResultType quarto_eval (Pos *, Player, float *eval); 00068 static void quarto_reset_uistate (Pos *pos); 00069 static unsigned char * quarto_get_rgbmap (int idx, int color); 00070 void quarto_get_render (Pos *pos, byte *move, int **rmovp); 00071 00072 void quarto_init () 00073 { 00074 game_eval = quarto_eval; 00075 game_movegen = quarto_movegen; 00076 game_who_won = quarto_who_won; 00077 game_getmove = quarto_getmove; 00078 game_get_rgbmap = quarto_get_rgbmap; 00079 game_draw_cell_boundaries = TRUE; 00080 game_highlight_colors = quarto_highlight_colors; 00081 game_reset_uistate = quarto_reset_uistate; 00082 game_get_render = quarto_get_render; 00083 game_allow_flip = TRUE; 00084 game_doc_about = 00085 "Quarto\n" 00086 "Two player game\n" 00087 "Status: Partially implemented\n" 00088 "URL: "GAME_DEFAULT_URL ("quarto"); 00089 game_doc_rules = 00090 "Quarto rules\n" 00091 "\n" 00092 "Two players take turns in placing the pieces from the right side of the board to the left side. Get 4 in a line (horizontal, vertical, diagonal) of any one type -- big, small, square, circle, hole, no hole, red or blue"; 00093 } 00094 00095 static ResultType quarto_who_won (Pos *pos, Player player, char **commp) 00096 { 00097 ResultType result; 00098 float eval; 00099 result = quarto_eval (pos, player, &eval); 00100 if (result == RESULT_WHITE) *commp = "White won"; 00101 if (result == RESULT_BLACK) *commp = "Black won"; 00102 return result; 00103 } 00104 00105 static gboolean eval_column (byte *board, int x, int y, int incx, int incy) 00106 { 00107 int i; 00108 int and1, and2; 00109 and1 = and2 = QUARTO_ALL_PIECES_MASK; 00110 for (i=0; i<4; i++, x+=incx, y+=incy) 00111 { 00112 int val; 00113 val = board[y * board_wid + x]; 00114 if (val == 0) 00115 return FALSE; 00116 val--; 00117 and1 &= val; 00118 and2 &= ~val; 00119 } 00120 if (and1 != 0 || and2 != 0) 00121 return TRUE; 00122 else 00123 return FALSE; 00124 } 00125 00126 static ResultType quarto_eval (Pos *pos, Player player, float *eval) 00127 { 00128 int i, j; 00129 int and1, and2; 00130 ResultType result = player == WHITE ? RESULT_BLACK : RESULT_WHITE; 00131 *eval = player == WHITE ? -1 : 1; 00132 00133 for (i=0; i<4; i++) 00134 if (eval_column (pos->board, i, 0, 0, 1)) 00135 return result; 00136 00137 for (j=0; j<4; j++) 00138 if (eval_column (pos->board, 0, j, 1, 0)) 00139 return result; 00140 00141 if (eval_column (pos->board, 0, 0, 1, 1)) 00142 return result; 00143 00144 if (eval_column (pos->board, 0, 3, 1, -1)) 00145 return result; 00146 00147 *eval = random() * 0.01 / RAND_MAX; 00148 return RESULT_NOTYET; 00149 } 00150 00151 static int cur_piece = -1, curx = -1, cury = -1; 00152 00153 int quarto_getmove 00154 (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep) 00155 { 00156 static byte move[7]; 00157 static int rmove[7]; 00158 byte *mp = move; 00159 int *rp = rmove; 00160 00161 if (type != GTKBOARD_BUTTON_RELEASE) 00162 return 0; 00163 00164 if (x == 4) return 0; 00165 00166 if (x > 4) 00167 { 00168 if (pos->render[y * board_wid + x] == RENDER_SHADE1) 00169 return -1; 00170 *rp++ = x; 00171 *rp++ = y; 00172 *rp++ = RENDER_HIGHLIGHT1; 00173 if (cur_piece >= 0) 00174 { 00175 *rp++ = curx; 00176 *rp++ = cury; 00177 *rp++ = RENDER_NONE; 00178 } 00179 *rp++ = -1; 00180 cur_piece = pos->board [y * board_wid + x]; 00181 curx = x; 00182 cury = y; 00183 *rmovep = rmove; 00184 return 0; 00185 } 00186 00187 if (cur_piece < 0) 00188 return -1; 00189 00190 if (pos->board[y * board_wid + x] != QUARTO_EMPTY) 00191 return -1; 00192 *mp++ = x; 00193 *mp++ = y; 00194 *mp++ = cur_piece; 00195 *mp++ = -1; 00196 *movp = move; 00197 cur_piece = -1; 00198 *rp++ = curx; 00199 *rp++ = cury; 00200 *rp++ = 0; 00201 *rp++ = -1; 00202 *rmovep = rmove; 00203 return 1; 00204 } 00205 00206 void quarto_get_render (Pos *pos, byte *move, int **rmovp) 00207 { 00208 static int rmove[4]; 00209 int *rp = rmove; 00210 int val, shadeval; 00211 int i, j; 00212 if (move[2] == QUARTO_EMPTY) 00213 { 00214 val = pos->board [move[1] * board_wid + move[0]]; 00215 shadeval = RENDER_NONE; 00216 } 00217 else 00218 { 00219 val = move[2]; 00220 shadeval = RENDER_SHADE1; 00221 } 00222 for (i=5; i<9; i++) 00223 for (j=0; j<4; j++) 00224 if (pos->board[j * board_wid + i] == val) 00225 { 00226 *rp++ = i; 00227 *rp++ = j; 00228 *rp++ = shadeval; 00229 *rp++ = -1; 00230 } 00231 *rmovp = rmove; 00232 } 00233 00234 void quarto_reset_uistate (Pos *pos) 00235 { 00236 cur_piece = curx = cury = -1; 00237 } 00238 00239 byte *quarto_movegen (Pos *pos) 00240 { 00241 byte movbuf[2048]; 00242 byte *movlist, *movp = movbuf; 00243 int from_x, from_y, to_x, to_y; 00244 Player player = pos->player; 00245 00246 int count = 0; 00247 for (to_x=0; to_x<4; to_x++) 00248 for (to_y=0; to_y<4; to_y++) 00249 if (pos->board [to_y * board_wid + to_x] != QUARTO_EMPTY) 00250 count++; 00251 assert ((player == WHITE && count % 2 == 0) || (player == BLACK && count % 2 == 1)); 00252 00253 00254 for (from_x=5; from_x<9; from_x++) 00255 for (from_y=0; from_y<4; from_y++) 00256 { 00257 gboolean found = FALSE; 00258 int val = pos->board [from_y * board_wid + from_x]; 00259 for (to_x=0; to_x<4; to_x++) 00260 for (to_y=0; to_y<4; to_y++) 00261 if (val == pos->board [to_y * board_wid + to_x]) 00262 { 00263 found = TRUE; 00264 break; 00265 } 00266 if (!found) 00267 { 00268 for (to_x=0; to_x<4; to_x++) 00269 for (to_y=0; to_y<4; to_y++) 00270 { 00271 if (pos->board [to_y * board_wid + to_x] == QUARTO_EMPTY) 00272 { 00273 *movp++ = to_x; 00274 *movp++ = to_y; 00275 *movp++ = val; 00276 *movp++ = -1; 00277 } 00278 } 00279 } 00280 } 00281 *movp++ = -2; 00282 movlist = (byte *) (malloc (movp - movbuf)); 00283 memcpy (movlist, movbuf, (movp - movbuf)); 00284 return movlist; 00285 } 00286 00287 unsigned char * quarto_get_rgbmap (int idx, int color) 00288 { 00289 int fg = 0, bg, i; 00290 char *colors; 00291 static char rgbbuf[3*QUARTO_CELL_SIZE*QUARTO_CELL_SIZE]; 00292 int color1 = 0xff << 16, color2 = 0xff, sepcolor = 0xaaaa66; 00293 float grad = 30.0; 00294 int size; 00295 colors = quarto_colors; 00296 for(i=0, bg=0;i<3;i++) 00297 { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));} 00298 if (idx == QUARTO_SEPARATOR) 00299 { 00300 rgbmap_square_gen (QUARTO_CELL_SIZE, rgbbuf, sepcolor, bg, QUARTO_CELL_SIZE); 00301 return rgbbuf; 00302 } 00303 fg = ((idx - 1) & QUARTO_COLOR_MASK) ? color1 : color2; 00304 size = ((idx - 1) & QUARTO_SIZE_MASK) ? 00305 3.0 * QUARTO_CELL_SIZE / 4 : QUARTO_CELL_SIZE / 2.0; 00306 if ((idx - 1) & QUARTO_SHAPE_MASK) 00307 rgbmap_ball_gen(QUARTO_CELL_SIZE, rgbbuf, fg, bg, size/2, grad); 00308 else 00309 rgbmap_square_gen (QUARTO_CELL_SIZE, rgbbuf, fg, bg, size); 00310 if ((idx - 1) & QUARTO_HOLE_MASK) 00311 rgbmap_ball_gen_nobg (QUARTO_CELL_SIZE, rgbbuf, bg, fg, QUARTO_CELL_SIZE/8.0, grad); 00312 return rgbbuf; 00313 00314 } 00315 00316