~ubuntu-branches/ubuntu/natty/gtkboard/natty

« back to all changes in this revision

Viewing changes to .pc/debian-changes-0.11pre0+cvs.2003.11.02-2/src/mastermind.c

  • Committer: Bazaar Package Importer
  • Author(s): Barak A. Pearlmutter
  • Date: 2011-02-28 11:25:02 UTC
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20110228112502-e9aah248wxelm7ao
Tags: 0.11pre0+cvs.2003.11.02-2
autotools tweaks, most notably -lSDL to supplement -lSDL_mixer

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is a part of gtkboard, a board games system.
 
2
    Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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
 
17
 
 
18
*/
 
19
 
 
20
/** \file mastermind.c */
 
21
 
 
22
#include <stdio.h>
 
23
#include <string.h>
 
24
#include <assert.h>
 
25
#include <stdlib.h>
 
26
#include <gdk/gdkkeysyms.h>
 
27
 
 
28
#include "game.h"
 
29
#include "aaball.h"
 
30
#include "../pixmaps/misc.xpm"
 
31
 
 
32
#define MASTERMIND_CELL_SIZE 40
 
33
#define MASTERMIND_NUM_PIECES 28
 
34
 
 
35
#define MASTERMIND_BOARD_WID 8
 
36
#define MASTERMIND_BOARD_HEIT 11
 
37
 
 
38
#define MASTERMIND_EMPTY 0
 
39
#define MASTERMIND_MAIN_COL_START 2
 
40
#define MASTERMIND_MAIN_COL_END 5
 
41
 
 
42
#define MASTERMIND_ARROW 27
 
43
#define MASTERMIND_RETURN 28
 
44
 
 
45
#define MASTERMIND_RIGHT_ROW_START 2
 
46
#define MASTERMIND_RIGHT_ROW_END   7
 
47
#define MASTERMIND_GET_SELECTION(x,y) (((x)==7&&(y)>=MASTERMIND_RIGHT_ROW_START&&(y)<(MASTERMIND_RIGHT_ROW_START+6))?(y):-1)
 
48
#define MASTERMIND_IS_MAIN_COL(x) ((x)>1&&(x)<6)
 
49
 
 
50
char mastermind_colors[9] = {200, 200, 200, 200, 200, 200, 0, 0, 0};
 
51
char mastermind_highlight_colors[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
 
52
 
 
53
static char * arrow_blue_return_40_xpm[]=
 
54
{
 
55
"40 40 2 1",
 
56
". c blue",
 
57
"  c none",
 
58
"                                        ",
 
59
"                                        ",
 
60
"                                        ",
 
61
"                                        ",
 
62
"                                        ",
 
63
"                                        ",
 
64
"                                        ",
 
65
"                                        ",
 
66
"                            ....        ",
 
67
"                            ....        ",
 
68
"                            ....        ",
 
69
"                            ....        ",
 
70
"                            ....        ",
 
71
"                            ....        ",
 
72
"                            ....        ",
 
73
"               .            ....        ",
 
74
"              ..            ....        ",
 
75
"             ...            ....        ",
 
76
"            ....            ....        ",
 
77
"           .....            ....        ",
 
78
"          ......            ....        ",
 
79
"         .......................        ",
 
80
"        ........................        ",
 
81
"        ........................        ",
 
82
"         .......................        ",
 
83
"          ......                        ",
 
84
"           .....                        ",
 
85
"            ....                        ",
 
86
"             ...                        ",
 
87
"              ..                        ",
 
88
"               .                        ",
 
89
"                                        ",
 
90
"                                        ",
 
91
"                                        ",
 
92
"                                        ",
 
93
"                                        ",
 
94
"                                        ",
 
95
"                                        ",
 
96
"                                        ",
 
97
"                                        ",
 
98
};
 
99
 
 
100
static char * arrow_blue_left_40_xpm[]=
 
101
{
 
102
"40 40 2 1",
 
103
". c blue",
 
104
"  c none",
 
105
"                                        ",
 
106
"                                        ",
 
107
"                                        ",
 
108
"                                        ",
 
109
"                                        ",
 
110
"                                        ",
 
111
"                                        ",
 
112
"                                        ",
 
113
"                                        ",
 
114
"               .                        ",
 
115
"              ..                        ",
 
116
"             ...                        ",
 
117
"            ....                        ",
 
118
"           .....                        ",
 
119
"          ......                        ",
 
120
"         .......                        ",
 
121
"        ........                        ",
 
122
"       .........                        ",
 
123
"      ............................      ",
 
124
"     .............................      ",
 
125
"     .............................      ",
 
126
"      ............................      ",
 
127
"       .........                        ",
 
128
"        ........                        ",
 
129
"         .......                        ",
 
130
"          ......                        ",
 
131
"           .....                        ",
 
132
"            ....                        ",
 
133
"             ...                        ",
 
134
"              ..                        ",
 
135
"               .                        ",
 
136
"                                        ",
 
137
"                                        ",
 
138
"                                        ",
 
139
"                                        ",
 
140
"                                        ",
 
141
"                                        ",
 
142
"                                        ",
 
143
"                                        ",
 
144
"                                        ",
 
145
};
 
146
 
 
147
 
 
148
int mastermind_init_pos [MASTERMIND_BOARD_WID*MASTERMIND_BOARD_HEIT] = 
 
149
{
 
150
        0, 0, 9, 9, 9, 9, 0, 0,
 
151
        0, 0, 0, 0, 0, 0, 0, 0,
 
152
        0, 0, 0, 0, 0, 0, 0, 0,
 
153
        0, 0, 0, 0, 0, 0, 0, 6,
 
154
        0, 0, 0, 0, 0, 0, 0, 5,
 
155
        0, 0, 0, 0, 0, 0, 0, 4,
 
156
        0, 0, 0, 0, 0, 0, 0, 3,
 
157
        0, 0, 0, 0, 0, 0, 0, 2,
 
158
        0, 0, 0, 0, 0, 0, 0, 1,
 
159
        0, 0, 0, 0, 0, 0, 0, 0,
 
160
        0, 0, 0, 0, 0, 0,27, 0,
 
161
};
 
162
 
 
163
 
 
164
SCORE_FIELD mastermind_score_fields[] = {SCORE_FIELD_USER, SCORE_FIELD_SCORE, SCORE_FIELD_TIME, SCORE_FIELD_DATE, SCORE_FIELD_NONE};
 
165
char *mastermind_score_field_names[] = {"User", "Tries", "Time", "Date", NULL};
 
166
 
 
167
void mastermind_init ();
 
168
char ** mastermind_get_pixmap (int idx, int color);
 
169
 
 
170
Game Mastermind = { MASTERMIND_CELL_SIZE, 
 
171
        MASTERMIND_BOARD_WID, MASTERMIND_BOARD_HEIT, 
 
172
        MASTERMIND_NUM_PIECES,  mastermind_colors,  
 
173
        NULL,   NULL, "Mastermind", NULL, mastermind_init};
 
174
 
 
175
 
 
176
static ResultType mastermind_who_won (Pos *, Player, char **);
 
177
static void mastermind_set_init_pos (Pos *pos);
 
178
int mastermind_getmove (Pos *, int, int, GtkboardEventType, Player, byte**, int **);
 
179
int mastermind_getmove_kb (Pos *, int, byte **, int **);
 
180
void mastermind_reset_uistate ();
 
181
int mastermind_get_cur_row (byte *);
 
182
void mastermind_set_init_render (Pos *);
 
183
void mastermind_free ();
 
184
 
 
185
 
 
186
 
 
187
void mastermind_init ()
 
188
{
 
189
        game_getmove = mastermind_getmove;
 
190
        game_getmove_kb = mastermind_getmove_kb;
 
191
        game_who_won = mastermind_who_won;
 
192
        game_set_init_pos = mastermind_set_init_pos;
 
193
        game_get_pixmap = mastermind_get_pixmap;
 
194
        game_single_player = TRUE;
 
195
        game_reset_uistate = mastermind_reset_uistate;
 
196
        game_draw_cell_boundaries = TRUE;
 
197
        game_scorecmp = game_scorecmp_def_iscore;
 
198
        game_score_fields = mastermind_score_fields;
 
199
        game_score_field_names = mastermind_score_field_names;
 
200
        game_highlight_colors = mastermind_highlight_colors;
 
201
        game_set_init_render = mastermind_set_init_render;
 
202
        game_free = mastermind_free;
 
203
        game_doc_about_status = STATUS_COMPLETE;
 
204
        game_doc_about = 
 
205
                "Mastermind\n"
 
206
                "Single player game\n"
 
207
                "Status: Completely implemented\n"
 
208
                "URL: "GAME_DEFAULT_URL ("mastermind");
 
209
        game_doc_rules = 
 
210
                "The objective is to find the colors of 4 hidden squares in as few tries as possible.\n\n"
 
211
                "Select a color by clicking on one of the balls on the extreme right. Place any 4 colors of your choice on the middle 4 squares of the bottom row and hit enter. You will get two numbers on the left. The number of black balls indicates how many balls you've got in the correct position. The number of white balls indicates how many balls you've got n the wrong position. Now try again on the second row. Repeat until you get all four black balls.";
 
212
        
 
213
        // TODO: complete this
 
214
}
 
215
 
 
216
void mastermind_set_init_render (Pos *pos)
 
217
{
 
218
        pos->render [MASTERMIND_RIGHT_ROW_START * board_wid + board_wid - 1] = RENDER_HIGHLIGHT1;
 
219
}
 
220
 
 
221
ResultType mastermind_who_won (Pos *pos, Player to_play, char **commp)
 
222
{
 
223
        static char comment[32];
 
224
        int j;
 
225
        gboolean over = FALSE;
 
226
        char *scorestr;
 
227
/*              pos->board [(board_heit - 1) * board_wid+ MASTERMIND_MAIN_COL_START] 
 
228
                        <= 8 ? TRUE : FALSE;
 
229
*/
 
230
        for (j=0; j<board_heit-1; j++)
 
231
                if (pos->board[j * board_wid] == 20) // FIXME: don't hard code
 
232
                        over = TRUE;
 
233
        scorestr = over ? "You won! Tries:" : "Tries:";
 
234
        if (!over && mastermind_get_cur_row (pos->board) == board_heit - 1)
 
235
        {
 
236
                snprintf (comment, 32, "You lost. Tries: %d", board_heit - 1);
 
237
                *commp = comment;
 
238
                return RESULT_LOST;
 
239
        }
 
240
        for (j=0; j<board_heit-1; j++)
 
241
                if (!pos->board[j * board_wid])
 
242
                        break;
 
243
        snprintf (comment, 32, "%s %d", scorestr, j);
 
244
        *commp = comment;
 
245
        return over ? RESULT_WON : RESULT_NOTYET;
 
246
 
 
247
}
 
248
 
 
249
int mastermind_get_cur_row (byte *board)
 
250
{
 
251
        int j;
 
252
        for (j=board_heit-2; j>=0; j--)
 
253
        {
 
254
                if (board [j * board_wid + 0] || board [j * board_wid + 1])
 
255
                        return j+1;
 
256
        }
 
257
        return 0;
 
258
}
 
259
 
 
260
void mastermind_set_init_pos (Pos *pos)
 
261
{
 
262
        int i, j;
 
263
        for (i=0; i<board_wid; i++)
 
264
        for (j=0; j<board_heit; j++)
 
265
                pos->board [j * board_wid + i] = 
 
266
                        mastermind_init_pos [(board_heit - 1 - j) * board_wid + i];
 
267
        for (i=MASTERMIND_MAIN_COL_START; i<=MASTERMIND_MAIN_COL_END; i++)
 
268
                pos->board [(board_heit - 1) * board_wid + i] = 9 + random() % 6;
 
269
}
 
270
 
 
271
char ** mastermind_get_pixmap (int idx, int color)
 
272
{
 
273
        int fg = 0, bg = 0, i;
 
274
        char *colors;
 
275
        static char pixbuf[MASTERMIND_CELL_SIZE*(MASTERMIND_CELL_SIZE)+1];
 
276
        static char dice_pixbuf[MASTERMIND_CELL_SIZE*(MASTERMIND_CELL_SIZE)+1];
 
277
        static gboolean first = TRUE;
 
278
        colors = mastermind_colors;
 
279
        if (idx == MASTERMIND_ARROW)
 
280
                return arrow_blue_left_40_xpm;
 
281
        else if (idx == MASTERMIND_RETURN)
 
282
                return arrow_blue_return_40_xpm;
 
283
        if (idx < 16)
 
284
        {
 
285
                fg += (idx & 1);
 
286
                fg += (idx & 2 ? 256 : 0);
 
287
                fg += (idx & 4 ? 65536 : 0);
 
288
                fg *= 255;
 
289
                if (idx >= 9 && idx <= 14) fg = 100 * 0x10101;
 
290
                if (color == BLACK) colors += 3;
 
291
                for(i=0, bg=0;i<3;i++) 
 
292
                { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
293
                if (first)
 
294
                {
 
295
                        first = FALSE;
 
296
                        return pixmap_ball_gen
 
297
                                (MASTERMIND_CELL_SIZE, pixbuf, fg, bg, 10.0, 30.0);
 
298
                }
 
299
                return  pixmap_header_gen 
 
300
                        (MASTERMIND_CELL_SIZE, pixbuf, fg, bg);
 
301
        }
 
302
        else if (idx < 25)
 
303
        {
 
304
                int num = (idx <= 20 ? idx - 16 : idx - 20);
 
305
                for(i=0, bg=0;i<3;i++) 
 
306
                { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
307
                fg = (idx <= 20 ? 0 : 0xffffff);
 
308
                return pixmap_die_gen(MASTERMIND_CELL_SIZE, dice_pixbuf, fg, bg, 3.0, 30.0, num);
 
309
        }
 
310
        else return red_X_40_xpm;
 
311
        return NULL;
 
312
}
 
313
 
 
314
static int active = MASTERMIND_RIGHT_ROW_START;
 
315
 
 
316
void mastermind_free ()
 
317
{
 
318
        active = MASTERMIND_RIGHT_ROW_START;
 
319
}
 
320
 
 
321
void mastermind_reset_uistate ()
 
322
{
 
323
}
 
324
 
 
325
int mastermind_getmove 
 
326
  (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
 
327
{
 
328
        static int rmove[7];
 
329
        int *rp = rmove;
 
330
        int tmp;
 
331
        int i, found;
 
332
        static byte move[7];
 
333
        byte *mp = move;
 
334
        if (type != GTKBOARD_BUTTON_RELEASE)
 
335
                return 0;
 
336
        tmp = MASTERMIND_GET_SELECTION(x,y);
 
337
        if (tmp > 0) 
 
338
        { 
 
339
                int j;
 
340
                active = tmp;
 
341
                for (j=0; j<board_heit; j++)
 
342
                        if (pos->render [j * board_wid + (board_wid - 1)] == RENDER_HIGHLIGHT1)
 
343
                        {
 
344
                                if (j == y) break;
 
345
                                *rp++ = board_wid - 1;
 
346
                                *rp++ = j;
 
347
                                *rp++ = 0;
 
348
                                break;
 
349
                        }
 
350
                *rp++ = board_wid - 1;
 
351
                *rp++ = y;
 
352
                *rp++ = RENDER_HIGHLIGHT1;
 
353
                *rp++ = -1;
 
354
                *rmovep = rmove;
 
355
                return 0;
 
356
        }
 
357
        if (active < 1) return -1;
 
358
        if (!MASTERMIND_IS_MAIN_COL(x)) return -1;
 
359
        if (y == board_heit -1) return -1;
 
360
        if (y != mastermind_get_cur_row (pos->board)) return -1;
 
361
        *mp++ = x;
 
362
        *mp++ = y;
 
363
        *mp++ = active - MASTERMIND_RIGHT_ROW_START + 1;
 
364
        if (movp)
 
365
                *movp = move;   
 
366
        for (found = 0, i=MASTERMIND_MAIN_COL_START;i<=MASTERMIND_MAIN_COL_END;i++)
 
367
        {
 
368
                if (pos->board [y * board_wid + i] == MASTERMIND_EMPTY && i != x)
 
369
                {
 
370
                        found = 1;
 
371
                        break;
 
372
                }
 
373
        }
 
374
        if (!found)
 
375
        {
 
376
                *mp++ = MASTERMIND_MAIN_COL_END + 1;
 
377
                *mp++ = y;
 
378
                *mp++ = MASTERMIND_RETURN;
 
379
        }
 
380
        *mp++ = -1;
 
381
        return 1;
 
382
}
 
383
 
 
384
 
 
385
int mastermind_getmove_kb (Pos *pos, int key, byte **movp, int **rmovp)
 
386
{
 
387
        static byte move[32];
 
388
        static int rmove[7];
 
389
        byte *mp = move;
 
390
        int *rp = rmove;
 
391
        int i, j, nblack = 0, nwhite = 0, seen[4] = { 0 };
 
392
        byte *board = pos->board;
 
393
        int cur_row;
 
394
        if (key == GDK_Up)
 
395
        {
 
396
                *rp++ = board_wid - 1;
 
397
                *rp++ = active;
 
398
                *rp++ = 0;
 
399
                if (++active > MASTERMIND_RIGHT_ROW_END)
 
400
                        active = MASTERMIND_RIGHT_ROW_START;
 
401
                *rp++ = board_wid - 1;
 
402
                *rp++ = active;
 
403
                *rp++ = RENDER_HIGHLIGHT1;
 
404
                *rp++ = -1;
 
405
                *rmovp = rmove;
 
406
                return 0;
 
407
        }
 
408
        if (key == GDK_Down)
 
409
        {
 
410
                *rp++ = board_wid - 1;
 
411
                *rp++ = active;
 
412
                *rp++ = 0;
 
413
                if (--active < MASTERMIND_RIGHT_ROW_START)
 
414
                        active = MASTERMIND_RIGHT_ROW_END;
 
415
                *rp++ = board_wid - 1;
 
416
                *rp++ = active;
 
417
                *rp++ = RENDER_HIGHLIGHT1;
 
418
                *rp++ = -1;
 
419
                *rmovp = rmove;
 
420
                return 0;
 
421
        }
 
422
        if (key != GDK_Return) return 0;
 
423
        if (active < 0) return 0;
 
424
        cur_row = mastermind_get_cur_row (board);
 
425
        if (cur_row == board_heit - 1) return -1;
 
426
        for (i=MASTERMIND_MAIN_COL_START;i<=MASTERMIND_MAIN_COL_END;i++)
 
427
        {
 
428
                if (board [cur_row * board_wid + i] == MASTERMIND_EMPTY)
 
429
                        return 0;
 
430
        }
 
431
        *mp++ = MASTERMIND_MAIN_COL_END + 1;
 
432
        *mp++ = cur_row;
 
433
        *mp++ = MASTERMIND_EMPTY;
 
434
        if (cur_row < board_heit - 2)
 
435
        {
 
436
                *mp++ = MASTERMIND_MAIN_COL_END + 1;
 
437
                *mp++ = cur_row+1;
 
438
                *mp++ = MASTERMIND_ARROW;
 
439
        }
 
440
        nblack = 0;
 
441
        for (i=MASTERMIND_MAIN_COL_START;i<=MASTERMIND_MAIN_COL_END;i++)
 
442
                if (board [cur_row * board_wid + i] == 
 
443
                                (board [(board_heit - 1) * board_wid + i] & 7))
 
444
                        nblack++;
 
445
        for (i=MASTERMIND_MAIN_COL_START;i<=MASTERMIND_MAIN_COL_END;i++)
 
446
        {
 
447
                for (j=MASTERMIND_MAIN_COL_START;j<=MASTERMIND_MAIN_COL_END;j++)
 
448
                        if (board [cur_row * board_wid + i] == 
 
449
                                        (board [(board_heit - 1) * board_wid + j] & 7)
 
450
                                        && !seen[j - MASTERMIND_MAIN_COL_START])
 
451
                        {
 
452
                                nwhite++;
 
453
                                seen[j - MASTERMIND_MAIN_COL_START] = 1;
 
454
                                break;
 
455
                        }
 
456
        }
 
457
        assert (nwhite >= nblack);
 
458
        nwhite -= nblack;
 
459
        *mp++ = 0; *mp++ = cur_row; *mp++ = (nblack ? nblack + 16 : 25);
 
460
        *mp++ = 1; *mp++ = cur_row; *mp++ = (nwhite ? nwhite + 20 : 25);
 
461
        if (nblack == 4 || cur_row == board_heit - 2)
 
462
                for (i=MASTERMIND_MAIN_COL_START;i<=MASTERMIND_MAIN_COL_END;i++)
 
463
                {
 
464
                        *mp++ = i; *mp++ = board_heit - 1; 
 
465
                        *mp++ = board [(board_heit - 1) * board_wid + i] & 7;
 
466
                }
 
467
        *mp++ = -1;
 
468
        if (movp) *movp = move;
 
469
        cur_row++;
 
470
        return 1;
 
471
}
 
472