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>
28
#include "../pixmaps/alpha.xpm"
32
#define FLW_CELL_SIZE 36
34
#define FLW_NUM_PIECES 26
36
#define FLW_BOARD_WID 4
37
#define FLW_BOARD_HEIT 6
41
char flw_colors[9] = {0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0, 0, 0xff};
42
char flw_highlight_colors[9] = {0xff, 0, 0, 0, 0, 0, 0, 0, 0};
44
static char **flw_pixmaps [] =
46
char_A_grey_36_36_xpm,
47
char_B_grey_36_36_xpm,
48
char_C_grey_36_36_xpm,
49
char_D_grey_36_36_xpm,
50
char_E_grey_36_36_xpm,
51
char_F_grey_36_36_xpm,
52
char_G_grey_36_36_xpm,
53
char_H_grey_36_36_xpm,
54
char_I_grey_36_36_xpm,
55
char_J_grey_36_36_xpm,
56
char_K_grey_36_36_xpm,
57
char_L_grey_36_36_xpm,
58
char_M_grey_36_36_xpm,
59
char_N_grey_36_36_xpm,
60
char_O_grey_36_36_xpm,
61
char_P_grey_36_36_xpm,
62
char_Q_grey_36_36_xpm,
63
char_R_grey_36_36_xpm,
64
char_S_grey_36_36_xpm,
65
char_T_grey_36_36_xpm,
66
char_U_grey_36_36_xpm,
67
char_V_grey_36_36_xpm,
68
char_W_grey_36_36_xpm,
69
char_X_grey_36_36_xpm,
70
char_Y_grey_36_36_xpm,
71
char_Z_grey_36_36_xpm,
74
SCORE_FIELD flw_score_fields[] = {SCORE_FIELD_USER, SCORE_FIELD_TIME, SCORE_FIELD_DATE, SCORE_FIELD_NONE};
75
char *flw_score_field_names[] = {"User", "Time", "Date", NULL};
77
static int flw_wordcmp (const void *p1, const void *p2)
79
return strcmp ((char *)p1, *(char **)p2);
82
void flw_find_chain (char chain[FLW_LEN+1][FLW_LEN+1])
89
strncpy (word, flwords[random() % num_flwords], FLW_LEN+1);
90
sprintf (chain[0], "%s", word);
91
for (i=0, memset (done, 0, FLW_LEN * sizeof (int)); i<FLW_LEN; i++)
94
do {idx = random() % FLW_LEN;} while (done[idx]); done[idx] = 1;
96
for (j=0, found=0; j<100; j++)
98
if ((word[idx] = random() % 26 + 'a') == orig) continue;
99
if (bsearch (word, flwords, num_flwords, sizeof (flwords[0]), flw_wordcmp))
101
sprintf (chain[i+1], "%s", word);
113
static void flw_init ();
114
int flw_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
115
int flw_getmove_kb (Pos *, int, byte **, int **);
117
ResultType flw_who_won (Pos *, Player , char **);
119
Game Flw = { FLW_CELL_SIZE, FLW_BOARD_WID, FLW_BOARD_HEIT,
121
flw_colors, NULL, flw_pixmaps,
127
static char flw_chain[FLW_LEN+1][FLW_LEN+1];
130
static void flw_set_init_pos (Pos *pos)
133
for (i=0; i<board_wid * board_heit; i++)
135
flw_find_chain (flw_chain);
136
for (i=0; i<FLW_LEN; i++)
138
pos->board[(board_heit - 1) * board_wid + i] = flw_chain[0][i] - 'a' + 1;
139
pos->board[i] = flw_chain[FLW_LEN][i] - 'a' + 1;
143
static void flw_init ()
145
game_single_player = TRUE;
146
game_set_init_pos = flw_set_init_pos;
147
game_draw_cell_boundaries = TRUE;
148
game_free = flw_free;
149
game_getmove = flw_getmove;
150
game_getmove_kb = flw_getmove_kb;
151
game_who_won = flw_who_won;
152
game_start_immediately = TRUE;
153
game_scorecmp = game_scorecmp_def_iscore;
154
game_score_fields = flw_score_fields;
155
game_score_field_names = flw_score_field_names;
156
game_highlight_colors = flw_highlight_colors;
157
game_doc_about_status = STATUS_COMPLETE;
159
"Four letter words\n"
160
"Single player game\n"
161
"Status: Partially implemented (playable)\n"
162
"URL: "GAME_DEFAULT_URL("flw");
164
" This is a simple game in which the objective is to change the word at the top to the word at the bottom by changing one letter at a time. All intermediate words must be legal.\n"
165
" To start playing, hit enter. This will make a copy of the top word on the second row. Click on the letter you want to change and change it by typing the new letter. Now hit enter. Repeat until all the rows are filled.";
168
static int flw_curx = -1, flw_cury = -1;
170
ResultType flw_who_won (Pos *pos, Player to_play, char **commp)
172
static char comment[32] = "You won.";
174
for (i=0; i<FLW_LEN; i++)
175
if (pos->board [i] != pos->board [board_wid + i])
176
return RESULT_NOTYET;
181
static int flw_get_cur_row (byte *board)
184
for (j = board_heit - 1; j>=0 && board[j * board_wid]; j--)
190
void flw_get_render (Pos *pos, byte *move, int type, int **rmovp)
196
for (i=0; i<board_wid; i++)
197
for (j=0; j<board_heit; j++)
198
if (pos->render [j * board_wid + i] == RENDER_HIGHLIGHT1)
200
assert (rp == rmove);
207
*rp++ = flw_get_cur_row (pos->board);
208
*rp++ = RENDER_HIGHLIGHT1;
214
int flw_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play,
215
byte **movp, int ** rmovep)
219
if (type != GTKBOARD_BUTTON_RELEASE)
221
if (y == 0 || y == board_heit - 1) return 0;
222
if (pos->board [y * board_wid + x] == 0) return 0;
223
if (y != 1 && pos->board [(y-1) * board_wid + x] != 0) return 0;
224
if (flw_curx == x && flw_cury == y) return 0;
225
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = 0;
226
*rp++ = x; *rp++ = y; *rp++ = RENDER_HIGHLIGHT1;
234
int flw_getmove_kb (Pos *pos, int key, byte **movp, int **rmovp)
238
static byte move[10];
241
char word[FLW_LEN+1], prevword[FLW_LEN+1];
244
if (!(pos->board [flw_cury * board_wid] &&
245
(pos->board [(flw_cury-1) * board_wid] == 0 || flw_cury == 1)))
248
// find the current row
249
/*for (j = board_heit - 1; j>=0 && pos->board[j * board_wid]; j--)
254
flw_cury = flw_get_cur_row (pos->board);
258
if (key == GDK_Return)
260
if ((cury = flw_cury) < 0)
261
cury = board_heit - 1;
262
for (i=0; i<FLW_LEN; i++)
264
word[i] = pos->board [cury * board_wid + i] + 'a' - 1;
266
prevword[i] = pos->board [(cury+1) * board_wid + i] + 'a' - 1;
268
word[FLW_LEN] = '\0';
269
prevword[FLW_LEN] = '\0';
270
if (!bsearch (word, flwords, num_flwords, sizeof (flwords[0]), flw_wordcmp))
274
int diff_cnt_prev = 0, diff_cnt_last = 0;
275
for (i=0; i<FLW_LEN; i++)
277
if (word[i] != prevword[i])
279
if (word[i] != flw_chain[FLW_LEN+1][i])
282
if (diff_cnt_prev != 1)
284
if (cury == 1 && diff_cnt_last != 1)
289
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = 0;
294
flw_cury = board_heit - 1;
297
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = RENDER_HIGHLIGHT1;
300
for (i=0; i<FLW_LEN; i++)
302
*mp++ = i; *mp++ = flw_cury; *mp++ = word[i] - 'a' + 1;
308
if (flw_cury < 0 || flw_cury == board_heit - 1)
310
if (key == GDK_Right)
312
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = 0;
313
if (++flw_curx == FLW_LEN) flw_curx = 0;
314
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = RENDER_HIGHLIGHT1;
321
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = 0;
322
if (--flw_curx < 0) flw_curx = FLW_LEN - 1;
323
*rp++ = flw_curx; *rp++ = flw_cury; *rp++ = RENDER_HIGHLIGHT1;
328
if (key >= GDK_A && key <= GDK_Z)
329
key = key + GDK_a - GDK_A;
330
if (key >= GDK_a && key <= GDK_z)
332
*mp++ = flw_curx; *mp++ = flw_cury; *mp++ = key - GDK_a + 1;
342
flw_curx = flw_cury = -1;