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
24
#include <gdk/gdkkeysyms.h>
27
#include "../pixmaps/arrows.xpm"
30
#define HYPERMAZE_CELL_SIZE 20
31
#define HYPERMAZE_NUM_PIECES 10
33
#define HYPERMAZE_BOARD_WID 25
34
#define HYPERMAZE_BOARD_HEIT 25
36
char hypermaze_colors[6] = {100, 150, 200, 100, 150, 200};
38
int * hypermaze_init_pos = NULL;
40
int hypermaze_hypermaze[HYPERMAZE_BOARD_WID][HYPERMAZE_BOARD_HEIT] = {{0}};
42
#define HYPERMAZE_CUR 1
47
#define HYPERMAZE_NE 6
48
#define HYPERMAZE_SE 7
49
#define HYPERMAZE_SW 8
50
#define HYPERMAZE_NW 9
51
#define HYPERMAZE_WALL 10
53
void hypermaze_init ();
55
SCORE_FIELD hypermaze_score_fields[] = {SCORE_FIELD_USER, SCORE_FIELD_TIME, SCORE_FIELD_DATE, SCORE_FIELD_NONE};
56
char *hypermaze_score_field_names[] = {"User", "Time", "Date", NULL};
58
Game Hypermaze = { HYPERMAZE_CELL_SIZE, HYPERMAZE_BOARD_WID, HYPERMAZE_BOARD_HEIT,
59
HYPERMAZE_NUM_PIECES, hypermaze_colors, NULL, NULL, "Hypermaze", "Maze", hypermaze_init};
62
static void hypermaze_set_init_pos (Pos *pos);
63
static char ** hypermaze_get_pixmap (int idx, int color);
64
static int hypermaze_getmove_kb (Pos *, int, byte **, int **);
65
int hypermaze_getmove (Pos *pos, int, int, GtkboardEventType, Player, byte **, int **);
66
ResultType hypermaze_who_won (Pos *, Player, char **);
69
void hypermaze_init ()
71
game_single_player = TRUE;
72
game_set_init_pos = hypermaze_set_init_pos;
73
game_get_pixmap = hypermaze_get_pixmap;
74
game_getmove_kb = hypermaze_getmove_kb;
75
game_getmove = hypermaze_getmove;
76
game_who_won = hypermaze_who_won;
77
game_start_immediately = TRUE;
78
game_scorecmp = game_scorecmp_def_time;
79
game_score_fields = hypermaze_score_fields;
80
game_score_field_names = hypermaze_score_field_names;
81
game_doc_about_status = STATUS_COMPLETE;
84
"Single player game\n"
85
"Status: Partially implemented (playable)\n"
86
"URL: "GAME_DEFAULT_URL ("hypermaze");
88
"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."
90
"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";
93
void hypermaze_get_cur_pos (byte *pos, int *x, int *y)
96
for (i=0; i<board_wid; i++)
97
for (j=0; j<board_heit; j++)
98
if (pos [j * board_wid + i] == HYPERMAZE_CUR)
99
{ *x = i; *y = j; return;
104
ResultType hypermaze_who_won (Pos *pos, Player to_play, char **commp)
106
static char comment[32];
107
gboolean over = (pos->board [board_wid * board_heit - 1] == HYPERMAZE_CUR);
108
snprintf (comment, 32, "%sMoves: %d",
109
over ? "You won. " : "",
112
return over ? RESULT_WON : RESULT_NOTYET;
115
int hypermaze_canmove (byte *board, int curx, int cury, int incx, int incy)
117
switch (board [(cury + incy/2) * board_wid + curx + incx/2])
119
case HYPERMAZE_N: if (incx != 0 || incy != 2) return 0; break;
120
case HYPERMAZE_S: if (incx != 0 || incy != -2) return 0; break;
121
case HYPERMAZE_E: if (incx != 2 || incy != 0) return 0; break;
122
case HYPERMAZE_W: if (incx != -2 || incy != 0) return 0; break;
123
case HYPERMAZE_NE: if (incx != 2 || incy != 2) return 0; break;
124
case HYPERMAZE_NW: if (incx != -2 || incy != 2) return 0; break;
125
case HYPERMAZE_SE: if (incx != 2 || incy != -2) return 0; break;
126
case HYPERMAZE_SW: if (incx != -2 || incy != -2) return 0; break;
127
case HYPERMAZE_WALL: return 0;
132
int hypermaze_getmove_common (Pos *pos, byte **movp,
133
int x, int y, int curx, int cury, int incx, int incy)
135
static byte move[10];
136
if (x < 0 || y < 0 || x >= board_wid || y >= board_heit) return -1;
137
if (pos->board[y * board_wid + x] == HYPERMAZE_WALL) return -1;
138
if (!hypermaze_canmove (pos->board, curx, cury, incx, incy)) return -1;
139
move[0] = curx; move[1] = cury; move[2] = 0;
140
move[3] = x; move[4] = y; move[5] = HYPERMAZE_CUR;
146
int hypermaze_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
148
int curx = -1, cury = -1;
149
int incx = -1, incy = -1;
150
if (type != GTKBOARD_BUTTON_RELEASE)
152
hypermaze_get_cur_pos (pos->board, &curx, &cury);
153
g_assert (curx >= 0 && cury >= 0);
154
if (abs (x - curx) != 2 && abs (x - curx) != 0) return -1;
155
if (abs (y - cury) != 2 && abs (y - cury) != 0) return -1;
156
if (abs (x - curx) == 0 && abs (y - cury) == 0) return -1;
157
return hypermaze_getmove_common (pos, movp,
158
x, y, curx, cury, x - curx, y - cury);
162
int hypermaze_getmove_kb (Pos *pos, int key, byte **movp, int **rmovp)
164
//static byte move[10];
165
int curx = -1, cury = -1;
166
int incx = -1, incy = -1;
168
hypermaze_get_cur_pos (pos->board, &curx, &cury);
169
g_assert (curx >= 0 && cury >= 0);
172
case GDK_KP_Home: incx = -2; incy = 2; break;
173
case GDK_KP_Page_Up: incx = 2; incy = 2; break;
174
case GDK_KP_End: incx = -2; incy = -2; break;
175
case GDK_KP_Page_Down: incx = 2; incy = -2; break;
177
case GDK_KP_Up: incx = 0; incy = 2; break;
179
case GDK_KP_Down: incx = 0; incy = -2; break;
181
case GDK_KP_Right: incx = 2; incy = 0; break;
183
case GDK_KP_Left: incx = -2; incy = 0; break;
188
return hypermaze_getmove_common (pos, movp, x, y, curx, cury, incx, incy);
191
static void recursive_pathgen (byte *board, int x, int y, int val)
193
static int incx[8] = {-2, 0, 0, 2, -2, -2, 2, 2};
194
static int incy[8] = {0, -2, 2, 0, -2, 2, -2, 2};
197
if (!ISINBOARD(x, y)) return;
198
if (board[y * board_wid + x] == val) return;
199
board [y * board_wid + x] = val;
201
if (hypermaze_canmove (board, x, y, incx[i], incy[i]))
202
recursive_pathgen (board, x+incx[i], y+incy [i], val);
205
void hypermaze_set_init_pos (Pos *pos)
211
for (i=0; i<board_wid; i++)
212
for (j=0; j<board_heit; j++)
215
if ((i + j) % 2 == 0)
216
pos->board [j * board_wid + i] = 6 + random() % 4;
218
pos->board [j * board_wid + i] = 2 + random() % 4;
221
pos->board [j * board_wid + i] = 0;
223
// edges can't have arbitrary arrows
224
for (i=0; i<board_wid; i+=(board_wid-1))
225
for (j=1; j<board_heit; j+=2)
226
pos->board [j * board_wid + i] = (random() % 2 ? HYPERMAZE_N : HYPERMAZE_S);
227
for (i=1; i<board_wid; i+=2)
228
for (j=0; j<board_heit; j+=(board_heit-1))
229
pos->board [j * board_wid + i] = (random() % 2 ? HYPERMAZE_E : HYPERMAZE_W);
231
recursive_pathgen (pos->board, 0, 0, -1);
233
while (pos->board [(board_heit - 1) * board_wid + (board_wid - 1)] != -1);
234
for (i=0; i<board_wid; i+=2)
235
for (j=0; j<board_heit; j+=2)
236
pos->board [j * board_wid + i] = 0;
237
pos->board [0] = HYPERMAZE_CUR;
240
char ** hypermaze_pixmap_square_gen (int idx, char *col)
245
pixmap = g_new(char *, HYPERMAZE_CELL_SIZE + 2);
246
pixmap[0] = "20 20 1 1";
247
pixmap[1] = g_strdup_printf (" c %s", col);
248
for (i=0; i<HYPERMAZE_CELL_SIZE; i++) pixmap[i+2] = line; return pixmap;
251
char ** hypermaze_get_pixmap (int idx, int color)
254
char *colors = hypermaze_colors;
255
static char pixbuf[HYPERMAZE_CELL_SIZE * (HYPERMAZE_CELL_SIZE+1)];
256
for(i=0, bg=0;i<3;i++)
257
{ int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
258
if (idx == HYPERMAZE_WALL)
259
return hypermaze_pixmap_square_gen(idx, "#443333");
260
if (idx == HYPERMAZE_CUR)
261
return pixmap_ball_gen (HYPERMAZE_CELL_SIZE, pixbuf,
262
0xffffff, bg, 6, 20);
263
// return hypermaze_pixmap_square_gen(idx, "#ff7777");
266
case HYPERMAZE_N: return arrow_blue_n_xpm;
267
case HYPERMAZE_S: return arrow_blue_s_xpm;
268
case HYPERMAZE_E: return arrow_blue_e_xpm;
269
case HYPERMAZE_W: return arrow_blue_w_xpm;
270
case HYPERMAZE_NE: return arrow_blue_ne_xpm;
271
case HYPERMAZE_NW: return arrow_blue_nw_xpm;
272
case HYPERMAZE_SW: return arrow_blue_sw_xpm;
273
case HYPERMAZE_SE: return arrow_blue_se_xpm;