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/arrows.xpm" 00028 #include "aaball.h" 00029 00030 #define HYPERMAZE_CELL_SIZE 20 00031 #define HYPERMAZE_NUM_PIECES 10 00032 00033 #define HYPERMAZE_BOARD_WID 25 00034 #define HYPERMAZE_BOARD_HEIT 25 00035 00036 char hypermaze_colors[6] = {100, 150, 200, 100, 150, 200}; 00037 00038 int * hypermaze_init_pos = NULL; 00039 00040 int hypermaze_hypermaze[HYPERMAZE_BOARD_WID][HYPERMAZE_BOARD_HEIT] = {{0}}; 00041 00042 #define HYPERMAZE_CUR 1 00043 #define HYPERMAZE_N 2 00044 #define HYPERMAZE_E 3 00045 #define HYPERMAZE_S 4 00046 #define HYPERMAZE_W 5 00047 #define HYPERMAZE_NE 6 00048 #define HYPERMAZE_SE 7 00049 #define HYPERMAZE_SW 8 00050 #define HYPERMAZE_NW 9 00051 #define HYPERMAZE_WALL 10 00052 00053 void hypermaze_init (); 00054 00055 SCORE_FIELD hypermaze_score_fields[] = {SCORE_FIELD_USER, SCORE_FIELD_TIME, SCORE_FIELD_DATE, SCORE_FIELD_NONE}; 00056 char *hypermaze_score_field_names[] = {"User", "Time", "Date", NULL}; 00057 00058 Game Hypermaze = { HYPERMAZE_CELL_SIZE, HYPERMAZE_BOARD_WID, HYPERMAZE_BOARD_HEIT, 00059 HYPERMAZE_NUM_PIECES, hypermaze_colors, NULL, NULL, "Hypermaze", hypermaze_init}; 00060 00061 00062 static void hypermaze_set_init_pos (Pos *pos); 00063 static char ** hypermaze_get_pixmap (int idx, int color); 00064 static int hypermaze_getmove_kb (Pos *, int, Player, byte **, int **); 00065 int hypermaze_getmove (Pos *pos, int, int, GtkboardEventType, Player, byte **, int **); 00066 ResultType hypermaze_who_won (Pos *, Player, char **); 00067 00068 00069 void hypermaze_init () 00070 { 00071 game_single_player = TRUE; 00072 game_set_init_pos = hypermaze_set_init_pos; 00073 game_get_pixmap = hypermaze_get_pixmap; 00074 game_getmove_kb = hypermaze_getmove_kb; 00075 game_getmove = hypermaze_getmove; 00076 game_who_won = hypermaze_who_won; 00077 game_start_immediately = TRUE; 00078 game_scorecmp = game_scorecmp_def_time; 00079 game_score_fields = hypermaze_score_fields; 00080 game_score_field_names = hypermaze_score_field_names; 00081 game_doc_about = 00082 "HyperMaze\n" 00083 "Single player game\n" 00084 "Status: Partially implemented (playable)\n" 00085 "URL: "GAME_DEFAULT_URL ("hypermaze"); 00086 game_doc_rules = 00087 "Hypermaze rules\n" 00088 "\n" 00089 "Your goal is to get from the lower left corner to the upper right. But you can travel only along the arrows. Beware - the arrows are one-way! You can easily get trapped in a blind end from which there is no escape." 00090 "\n" 00091 "To move with the mouse, click on the square to which you want to move. To move with the keyboard, use the NumPad keys.\n"; 00092 } 00093 00094 void hypermaze_get_cur_pos (byte *pos, int *x, int *y) 00095 { 00096 int i, j; 00097 for (i=0; i<board_wid; i++) 00098 for (j=0; j<board_heit; j++) 00099 if (pos [j * board_wid + i] == HYPERMAZE_CUR) 00100 { *x = i; *y = j; return; 00101 } 00102 } 00103 00104 00105 ResultType hypermaze_who_won (Pos *pos, Player to_play, char **commp) 00106 { 00107 static char comment[32]; 00108 gboolean over = (pos->board [board_wid * board_heit - 1] == HYPERMAZE_CUR); 00109 snprintf (comment, 32, "%sMoves: %d", 00110 over ? "You won. " : "", 00111 pos->num_moves); 00112 *commp = comment; 00113 return over ? RESULT_WON : RESULT_NOTYET; 00114 } 00115 00116 int hypermaze_canmove (byte *board, int curx, int cury, int incx, int incy) 00117 { 00118 switch (board [(cury + incy/2) * board_wid + curx + incx/2]) 00119 { 00120 case HYPERMAZE_N: if (incx != 0 || incy != 2) return 0; break; 00121 case HYPERMAZE_S: if (incx != 0 || incy != -2) return 0; break; 00122 case HYPERMAZE_E: if (incx != 2 || incy != 0) return 0; break; 00123 case HYPERMAZE_W: if (incx != -2 || incy != 0) return 0; break; 00124 case HYPERMAZE_NE: if (incx != 2 || incy != 2) return 0; break; 00125 case HYPERMAZE_NW: if (incx != -2 || incy != 2) return 0; break; 00126 case HYPERMAZE_SE: if (incx != 2 || incy != -2) return 0; break; 00127 case HYPERMAZE_SW: if (incx != -2 || incy != -2) return 0; break; 00128 case HYPERMAZE_WALL: return 0; 00129 } 00130 return 1; 00131 } 00132 00133 int hypermaze_getmove_common (Pos *pos, byte **movp, 00134 int x, int y, int curx, int cury, int incx, int incy) 00135 { 00136 static byte move[10]; 00137 if (x < 0 || y < 0 || x >= board_wid || y >= board_heit) return -1; 00138 if (pos->board[y * board_wid + x] == HYPERMAZE_WALL) return -1; 00139 if (!hypermaze_canmove (pos->board, curx, cury, incx, incy)) return -1; 00140 move[0] = curx; move[1] = cury; move[2] = 0; 00141 move[3] = x; move[4] = y; move[5] = HYPERMAZE_CUR; 00142 move[6] = -1; 00143 *movp = move; 00144 return 1; 00145 } 00146 00147 int hypermaze_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep) 00148 { 00149 int curx = -1, cury = -1; 00150 int incx = -1, incy = -1; 00151 if (type != GTKBOARD_BUTTON_RELEASE) 00152 return 0; 00153 hypermaze_get_cur_pos (pos->board, &curx, &cury); 00154 g_assert (curx >= 0 && cury >= 0); 00155 if (abs (x - curx) != 2 && abs (x - curx) != 0) return -1; 00156 if (abs (y - cury) != 2 && abs (y - cury) != 0) return -1; 00157 if (abs (x - curx) == 0 && abs (y - cury) == 0) return -1; 00158 return hypermaze_getmove_common (pos, movp, 00159 x, y, curx, cury, x - curx, y - cury); 00160 00161 } 00162 00163 int hypermaze_getmove_kb (Pos *pos, int key, Player glob_to_play, byte **movp, int **rmovp) 00164 { 00165 //static byte move[10]; 00166 int curx = -1, cury = -1; 00167 int incx = -1, incy = -1; 00168 int x, y; 00169 hypermaze_get_cur_pos (pos->board, &curx, &cury); 00170 g_assert (curx >= 0 && cury >= 0); 00171 switch (key) 00172 { 00173 case GDK_KP_Home: incx = -2; incy = 2; break; 00174 case GDK_KP_Page_Up: incx = 2; incy = 2; break; 00175 case GDK_KP_End: incx = -2; incy = -2; break; 00176 case GDK_KP_Page_Down: incx = 2; incy = -2; break; 00177 case GDK_Up: 00178 case GDK_KP_Up: incx = 0; incy = 2; break; 00179 case GDK_Down: 00180 case GDK_KP_Down: incx = 0; incy = -2; break; 00181 case GDK_Right: 00182 case GDK_KP_Right: incx = 2; incy = 0; break; 00183 case GDK_Left: 00184 case GDK_KP_Left: incx = -2; incy = 0; break; 00185 default: return -1; 00186 } 00187 x = curx + incx; 00188 y = cury + incy; 00189 return hypermaze_getmove_common (pos, movp, x, y, curx, cury, incx, incy); 00190 } 00191 00192 static void recursive_pathgen (byte *board, int x, int y, int val) 00193 { 00194 static int incx[8] = {-2, 0, 0, 2, -2, -2, 2, 2}; 00195 static int incy[8] = {0, -2, 2, 0, -2, 2, -2, 2}; 00196 00197 int i; 00198 if (!ISINBOARD(x, y)) return; 00199 if (board[y * board_wid + x] == val) return; 00200 board [y * board_wid + x] = val; 00201 for (i=0; i<8; i++) 00202 if (hypermaze_canmove (board, x, y, incx[i], incy[i])) 00203 recursive_pathgen (board, x+incx[i], y+incy [i], val); 00204 } 00205 00206 void hypermaze_set_init_pos (Pos *pos) 00207 { 00208 int i, j; 00209 int x, y; 00210 do 00211 { 00212 for (i=0; i<board_wid; i++) 00213 for (j=0; j<board_heit; j++) 00214 if (i % 2 || j % 2) 00215 { 00216 if ((i + j) % 2 == 0) 00217 pos->board [j * board_wid + i] = 6 + random() % 4; 00218 else 00219 pos->board [j * board_wid + i] = 2 + random() % 4; 00220 } 00221 else 00222 pos->board [j * board_wid + i] = 0; 00223 00224 // edges can't have arbitrary arrows 00225 for (i=0; i<board_wid; i+=(board_wid-1)) 00226 for (j=1; j<board_heit; j+=2) 00227 pos->board [j * board_wid + i] = (random() % 2 ? HYPERMAZE_N : HYPERMAZE_S); 00228 for (i=1; i<board_wid; i+=2) 00229 for (j=0; j<board_heit; j+=(board_heit-1)) 00230 pos->board [j * board_wid + i] = (random() % 2 ? HYPERMAZE_E : HYPERMAZE_W); 00231 00232 recursive_pathgen (pos->board, 0, 0, -1); 00233 } 00234 while (pos->board [(board_heit - 1) * board_wid + (board_wid - 1)] != -1); 00235 for (i=0; i<board_wid; i+=2) 00236 for (j=0; j<board_heit; j+=2) 00237 pos->board [j * board_wid + i] = 0; 00238 pos->board [0] = HYPERMAZE_CUR; 00239 } 00240 00241 char ** hypermaze_pixmap_square_gen (int idx, char *col) 00242 { 00243 int i, j; 00244 char **pixmap; 00245 char *line = " "; 00246 pixmap = g_new(char *, HYPERMAZE_CELL_SIZE + 2); 00247 pixmap[0] = "20 20 1 1"; 00248 pixmap[1] = g_strdup_printf (" c %s", col); 00249 for (i=0; i<HYPERMAZE_CELL_SIZE; i++) pixmap[i+2] = line; return pixmap; 00250 } 00251 00252 char ** hypermaze_get_pixmap (int idx, int color) 00253 { 00254 int fg, bg, i; 00255 char *colors = hypermaze_colors; 00256 static char pixbuf[HYPERMAZE_CELL_SIZE * (HYPERMAZE_CELL_SIZE+1)]; 00257 for(i=0, bg=0;i<3;i++) 00258 { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));} 00259 if (idx == HYPERMAZE_WALL) 00260 return hypermaze_pixmap_square_gen(idx, "#443333"); 00261 if (idx == HYPERMAZE_CUR) 00262 return pixmap_ball_gen (HYPERMAZE_CELL_SIZE, pixbuf, 00263 0xffffff, bg, 6, 20); 00264 // return hypermaze_pixmap_square_gen(idx, "#ff7777"); 00265 switch (idx) 00266 { 00267 case HYPERMAZE_N: return arrow_blue_n_xpm; 00268 case HYPERMAZE_S: return arrow_blue_s_xpm; 00269 case HYPERMAZE_E: return arrow_blue_e_xpm; 00270 case HYPERMAZE_W: return arrow_blue_w_xpm; 00271 case HYPERMAZE_NE: return arrow_blue_ne_xpm; 00272 case HYPERMAZE_NW: return arrow_blue_nw_xpm; 00273 case HYPERMAZE_SW: return arrow_blue_sw_xpm; 00274 case HYPERMAZE_SE: return arrow_blue_se_xpm; 00275 default: assert (0); 00276 } 00277 } 00278