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 #include <math.h> 00024 #include <gdk/gdkkeysyms.h> 00025 00026 #include "game.h" 00027 #include "../pixmaps/memory.xpm" 00028 00029 #define MEMORY_CELL_SIZE 48 00030 #define MEMORY_NUM_PIECES 72 00031 00032 #define MEMORY_BOARD_WID 9 00033 #define MEMORY_BOARD_HEIT 8 00034 00035 00036 #define MEMORY_EMPTY 0 00037 #define MEMORY_ISOPEN(x) ((x)>MEMORY_NUM_PIECES/2) 00038 #define MEMORY_FLIP(x) ((x)>MEMORY_NUM_PIECES/2?\ 00039 (x)-MEMORY_NUM_PIECES/2:(x)+MEMORY_NUM_PIECES/2) 00040 00041 char ** memory_pixmaps [] = { 00042 memory_blank_xpm, 00043 memory_blank_xpm, 00044 memory_blank_xpm, 00045 memory_blank_xpm, 00046 memory_blank_xpm, 00047 memory_blank_xpm, 00048 memory_blank_xpm, 00049 memory_blank_xpm, 00050 memory_blank_xpm, 00051 memory_blank_xpm, 00052 memory_blank_xpm, 00053 memory_blank_xpm, 00054 memory_blank_xpm, 00055 memory_blank_xpm, 00056 memory_blank_xpm, 00057 memory_blank_xpm, 00058 memory_blank_xpm, 00059 memory_blank_xpm, 00060 memory_blank_xpm, 00061 memory_blank_xpm, 00062 memory_blank_xpm, 00063 memory_blank_xpm, 00064 memory_blank_xpm, 00065 memory_blank_xpm, 00066 memory_blank_xpm, 00067 memory_blank_xpm, 00068 memory_blank_xpm, 00069 memory_blank_xpm, 00070 memory_blank_xpm, 00071 memory_blank_xpm, 00072 memory_blank_xpm, 00073 memory_blank_xpm, 00074 memory_blank_xpm, 00075 memory_blank_xpm, 00076 memory_blank_xpm, 00077 memory_blank_xpm, 00078 memory1_xpm, 00079 memory2_xpm, 00080 //memory3_xpm, 00081 memory4_xpm, 00082 memory5_xpm, 00083 memory6_xpm, 00084 memory7_xpm, 00085 memory8_xpm, 00086 //memory9_xpm, 00087 memory10_xpm, 00088 //memory11_xpm, 00089 memory12_xpm, 00090 memory13_xpm, 00091 memory14_xpm, 00092 memory15_xpm, 00093 memory16_xpm, 00094 memory17_xpm, 00095 memory18_xpm, 00096 memory19_xpm, 00097 //memory20_xpm, 00098 memory21_xpm, 00099 memory22_xpm, 00100 memory23_xpm, 00101 //memory24_xpm, 00102 memory25_xpm, 00103 memory26_xpm, 00104 memory27_xpm, 00105 memory28_xpm, 00106 memory29_xpm, 00107 memory30_xpm, 00108 memory31_xpm, 00109 //memory32_xpm, 00110 memory33_xpm, 00111 memory34_xpm, 00112 memory35_xpm, 00113 memory36_xpm, 00114 memory37_xpm, 00115 memory38_xpm, 00116 memory39_xpm, 00117 memory40_xpm, 00118 memory41_xpm, 00119 memory42_xpm, 00120 }; 00121 00122 char memory_colors[9] = {220, 220, 180, 220, 220, 180, 0, 0, 0}; 00123 00124 int * memory_init_pos = NULL; 00125 00126 void memory_init (); 00127 00128 Game Memory = { MEMORY_CELL_SIZE, MEMORY_BOARD_WID, MEMORY_BOARD_HEIT, 00129 MEMORY_NUM_PIECES, memory_colors, NULL, memory_pixmaps, 00130 "Memory", memory_init}; 00131 00132 00133 typedef struct 00134 { 00135 int num_moves; 00136 int num_found; 00137 } Memory_state; 00138 00139 static Memory_state state = {0, 0}; 00140 00141 static int memory_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **); 00142 static int memory_animate (Pos *pos, byte **movp); 00143 static void memory_set_init_pos (Pos *pos); 00144 void *memory_newstate (Pos *, byte *); 00145 ResultType memory_who_won (Pos *, Player, char **); 00146 void memory_free (); 00147 00148 void memory_init () 00149 { 00150 game_single_player = TRUE; 00151 game_set_init_pos = memory_set_init_pos; 00152 game_getmove = memory_getmove; 00153 game_animate = memory_animate; 00154 game_animation_time = 100; 00155 game_stateful = TRUE; 00156 game_state_size = sizeof (Memory_state); 00157 game_newstate = memory_newstate; 00158 game_who_won = memory_who_won; 00159 game_free = memory_free; 00160 game_draw_cell_boundaries = FALSE; 00161 game_allow_back_forw = FALSE; 00162 game_scorecmp = game_scorecmp_def_iscore; 00163 game_doc_about = 00164 "Memory\n" 00165 "Single player game\n" 00166 "Status: Fully implemented\n" 00167 "URL: "GAME_DEFAULT_URL("memory"); 00168 game_doc_rules = 00169 "Memory rules\n" 00170 "\n" 00171 "There are 36 pairs of images. Your goal is to match these pairs in as few turns as possible.\n" 00172 "In each turn you click on two squares. If they match they stay uncovered for the rest of the game. If not they go back to being hidden."; 00173 } 00174 00175 static int waiting = 0; 00176 00177 void memory_free () 00178 { 00179 waiting = 0; 00180 } 00181 00182 void *memory_newstate (Pos *pos, byte *move) 00183 { 00184 int i, j, found; 00185 state.num_moves = pos->state ? ((Memory_state *)pos->state)->num_moves : 0; 00186 state.num_found = pos->state ? ((Memory_state *)pos->state)->num_found : 0; 00187 if (move[2] <= MEMORY_NUM_PIECES/2) 00188 state.num_moves = pos->state ? ((Memory_state *)pos->state)->num_moves + 1 : 1; 00189 else 00190 for (i=0, found=0; i<board_wid; i++) 00191 { 00192 for (j=0; j<board_heit; j++) 00193 { 00194 if (i == move[0] && j == move[1]) 00195 continue; 00196 if (pos->board [j * board_wid + i] == move[2]) 00197 { 00198 state.num_found = pos->state ? ((Memory_state *)pos->state)->num_found + 1 : 1; 00199 found = 1; 00200 break; 00201 } 00202 } 00203 if (found) break; 00204 } 00205 return &state; 00206 } 00207 00208 ResultType memory_who_won (Pos *pos, Player to_play, char **commp) 00209 { 00210 static char comment[32]; 00211 int found = pos->state ? ((Memory_state *)pos->state)->num_found : 0; 00212 snprintf (comment, 32, "%s %d; %s %d", 00213 "Missed:", pos->state ? ((Memory_state *)pos->state)->num_moves : 0, 00214 "Found:", found); 00215 *commp = comment; 00216 return (found == board_wid * board_heit / 2) ? RESULT_WON : RESULT_NOTYET; 00217 } 00218 00219 00220 int memory_animate (Pos *pos, byte **movp) 00221 { 00222 static byte move[10]; 00223 static int count = 0; 00224 byte *mp = move; 00225 int val; 00226 int i, j; 00227 int pair [MEMORY_BOARD_HEIT * MEMORY_BOARD_WID/2+1]; 00228 if (waiting > 0) waiting ++; 00229 if (waiting == 10) 00230 { 00231 waiting = 0; 00232 for (i=0; i<=MEMORY_BOARD_WID * MEMORY_BOARD_HEIT/2; i++) 00233 pair [i] = 0; 00234 for (i=0; i<board_wid; i++) 00235 for (j=0; j<board_heit; j++) 00236 if (MEMORY_ISOPEN (val = pos->board [j * board_wid + i])) 00237 pair [MEMORY_FLIP (val)] ++; 00238 for (i=0; i<board_wid; i++) 00239 for (j=0; j<board_heit; j++) 00240 { 00241 if (MEMORY_ISOPEN (val = pos->board [j * board_wid + i]) 00242 && pair [MEMORY_FLIP (val)] == 1) 00243 { 00244 *mp++ = i; 00245 *mp++ = j; 00246 *mp++ = MEMORY_FLIP(val); 00247 } 00248 } 00249 } 00250 else return -1; 00251 *mp++ = -1; 00252 *movp = move; 00253 return 1; 00254 } 00255 00256 void memory_set_init_pos (Pos *pos) 00257 { 00258 int i, j, tmp; 00259 int size = board_wid * board_heit; 00260 int swaps = 0; 00261 byte *board = pos->board; 00262 for (i=0; i<size; i++) 00263 board[i] = i/2+1; 00264 for (i=1; i<size; i++) 00265 { 00266 j = random() % i; 00267 tmp = board[i]; board[i] = board[j]; board[j] = tmp; 00268 } 00269 } 00270 00271 int memory_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, 00272 byte **movp, int **rmovp) 00273 { 00274 static byte move[16]; 00275 byte *mp = move; 00276 int val, num; 00277 int i, j; 00278 gboolean pair = FALSE; 00279 int found = 0; 00280 if (type != GTKBOARD_BUTTON_RELEASE) 00281 return 0; 00282 if (waiting > 0) return 0; 00283 if ((val = pos->board [y * board_wid + x]) == MEMORY_EMPTY) return 0; 00284 if (MEMORY_ISOPEN (val)) return 0; 00285 *mp++ = x; *mp++ = y; 00286 num = board_wid * board_heit / 2; 00287 if (val <= num) val += num; else val -= num; 00288 *mp++ = val; 00289 *mp++ = -1; 00290 *movp = move; 00291 00292 for (i=0; i<board_wid; i++) 00293 for (j=0; j<board_heit; j++) 00294 { 00295 if (x == i && y == j) continue; 00296 if (MEMORY_ISOPEN(pos->board [j * board_wid + i])) 00297 { 00298 found++; 00299 if (pos->board [j * board_wid + i] == val) pair = TRUE; 00300 } 00301 } 00302 if (!pair && (found %2 == 1)) waiting = 1; 00303 return 1; 00304 } 00305