~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/game.h

  • 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
#ifndef _GAME_H_
 
20
#define _GAME_H_
 
21
 
 
22
#include<glib.h>
 
23
 
 
24
/** \file game.h
 
25
  \brief Header file that must be included by all games.
 
26
 
 
27
  This is the only file that the games need to include.
 
28
*/
 
29
 
 
30
//! Both moves and positions are arrays of <tt>byte</tt>s
 
31
#ifndef byte 
 
32
#define byte gint8
 
33
#endif
 
34
 
 
35
//! Used in a two player game to represent whose move it is.
 
36
/* White is always the player that moves first. Internally they
 
37
 are always called white and black even if the game wants the user to
 
38
 see them as red and blue, or Bob and Sue etc.*/
 
39
typedef enum {WHITE, BLACK} Player;
 
40
 
 
41
//! Used for representing the type of user input in game_getmove() and game_getmove_kb()
 
42
/** This layer of abstraction exists so that to write a game it will not be necessary to have the g[dt]k headers */
 
43
typedef enum 
 
44
{
 
45
        GTKBOARD_BUTTON_PRESS = 1, 
 
46
        GTKBOARD_BUTTON_RELEASE, 
 
47
        GTKBOARD_MOTION_NOTIFY,
 
48
        GTKBOARD_LEAVE_NOTIFY,
 
49
        GTKBOARD_KEY_PRESS,
 
50
        GTKBOARD_KEY_RELEASE,
 
51
        GTKBOARD_GAME_START,
 
52
        GTKBOARD_HUMAN_MOVE,
 
53
        GTKBOARD_MACHINE_MOVE,
 
54
        GTKBOARD_HISTORY_MOVE
 
55
} GtkboardEventType;
 
56
 
 
57
//! Abstraction of a user event
 
58
typedef struct 
 
59
{
 
60
        //! Type of event
 
61
        GtkboardEventType type;
 
62
 
 
63
        //! (For mouse events) x coordinate of the *cell* -- ranges from 0 to board_wid
 
64
        int x;
 
65
 
 
66
        // y coordinate of the cell
 
67
        int y;
 
68
 
 
69
        //! Actual x coordinate
 
70
        int pixel_x;
 
71
 
 
72
        //! Actual y coordinate
 
73
        int pixel_y;
 
74
 
 
75
        //! The key that was pressed
 
76
        int key;
 
77
 
 
78
        //! The move (when type is GTKBOARD_{HUMAN,MACHINE,HISTORY}_MOVE)
 
79
        byte *move;
 
80
} GtkboardEvent;
 
81
 
 
82
//! Used for representing the result of game_who_won()
 
83
typedef enum 
 
84
{
 
85
        //! White won
 
86
        RESULT_WHITE, 
 
87
        //! Black won
 
88
        RESULT_BLACK, 
 
89
        //! Draw
 
90
        RESULT_TIE, 
 
91
        //! Game not over yet
 
92
        RESULT_NOTYET,
 
93
        //! User completed the game successfully (single player game)
 
94
        RESULT_WON,
 
95
        //! User failed to complete game (single player game)
 
96
   /**  eg: exhausted all rows in mastermind (mastermind_who_won()) */
 
97
        RESULT_LOST,
 
98
        //! Anything else
 
99
        RESULT_MISC
 
100
} ResultType;
 
101
 
 
102
//! The return type of game_event_handler()
 
103
typedef enum
 
104
{
 
105
        INPUT_ILLEGAL = -1,
 
106
        INPUT_NOTYET = 0,
 
107
        INPUT_LEGAL = 1
 
108
} InputType;
 
109
 
 
110
//! The move and all the info. associated with it
 
111
typedef struct
 
112
{
 
113
        //! The move. 
 
114
        /** This is a sequence of the form 
 
115
        [x_1, y_1, v_1, x_2, y_2, v_2, ... x_n, y_n, v_n, -1] where [x_i, y_i, v_i]
 
116
        says that the value of the square (x_i, y_i) should change to v_i. */
 
117
        byte *move;
 
118
 
 
119
        //! (Only client side) the rendering info. associated with this move
 
120
        int *rmove;
 
121
        //! Any game-specific custom information associated with this move.
 
122
        /** The purpose of having this is that it will be sent from UI to engine and engine to UI */
 
123
        gchar *custom;
 
124
 
 
125
        //! (Only client side) Help message
 
126
        gchar *help_message;
 
127
 
 
128
        //! The human-readable version of the move eg: "e4" in chess
 
129
        gchar *human_readable;
 
130
}MoveInfo;
 
131
 
 
132
//! the completion status of the game
 
133
/** 
 
134
  This is the type of #game_doc_about_status.
 
135
  At the moment it only matters if the status is STATUS_COMPLETE or not 
 
136
 */
 
137
typedef enum
 
138
{
 
139
        //! don't use this
 
140
        STATUS_NONE,
 
141
 
 
142
        //! unplayable
 
143
        STATUS_UNPLAYABLE,
 
144
 
 
145
        //! partial
 
146
        STATUS_PARTIAL,
 
147
 
 
148
        //! complete
 
149
        STATUS_COMPLETE
 
150
} CompletionStatus;
 
151
 
 
152
//! values of #game_file_label and #game_rank_label
 
153
typedef enum {
 
154
        FILERANK_LABEL_TYPE_NONE, 
 
155
        FILERANK_LABEL_TYPE_NUM,
 
156
        FILERANK_LABEL_TYPE_ALPHA,
 
157
        FILERANK_LABEL_TYPE_ALPHA_CAPS
 
158
} FILERANK_LABEL_TYPE;
 
159
 
 
160
#define FILERANK_LABEL_TYPE_MASK 0x3
 
161
 
 
162
//! if #game_file_label or #game_rank_label is ORed with this the order of file/rank labels will be reversed
 
163
#define FILERANK_LABEL_DESC (1 << 2)
 
164
 
 
165
//! The return value of game_eval() should be larger than GAME_EVAL_INFTY in absolute value to indicate that the game is over.
 
166
#define GAME_EVAL_INFTY (1.0e10)
 
167
 
 
168
//! Indicates whether the square (x, y) is legal
 
169
#define ISINBOARD(x,y) ((x)>=0 && (y)>=0 && (x)<board_wid && (y)< board_heit)
 
170
 
 
171
//! Home page for the game <tt>x</tt>
 
172
#define GAME_DEFAULT_URL(x) "http://gtkboard.sourceforge.net/games"
 
173
 
 
174
struct _Game;
 
175
 
 
176
//! The Game struct gives essential information about the game
 
177
/** Only information that <b>must</b> be provided by every game
 
178
 is declared here. Of course, there are many other variables and 
 
179
 functions that can be used to customize the game. These must be
 
180
 set in the function game_init(). The good thing is that you can
 
181
 get your game running first and only use new features as you need
 
182
 them.*/
 
183
typedef struct _Game
 
184
{
 
185
        //! The size of each square on the board in pixels
 
186
        int cell_size;
 
187
 
 
188
        //! The number of rows in the board
 
189
        int board_wid;
 
190
 
 
191
        //! The number of columns in the board
 
192
        int board_heit;
 
193
 
 
194
        //! The number of types of pieces that the game uses 
 
195
        /** (12 for chess (chess.c), for instance -- 6 white and 6 black). 
 
196
          The maximum value is 127.
 
197
         In several games, like mastermind (mastermind.c), the value of num_pieces
 
198
         is more than the actual number of pieces that the user 
 
199
         sees. This is because several logical pieces are mapped to the same
 
200
         image and the value of the piece is used to encode some state information
 
201
         about that square.*/
 
202
        int num_pieces;
 
203
 
 
204
        //! An array which gives the colors for the squares of the board
 
205
        char *colors;
 
206
 
 
207
        //! The initial position
 
208
        int * init_pos;
 
209
 
 
210
        //! An array of pixmaps representing the pieces
 
211
        char *** pixmaps;
 
212
 
 
213
        //! Name of the game
 
214
        char *name;
 
215
 
 
216
        //! Which group does this game belong to. 
 
217
        /** In the menu, the game will be nested within this group. Use NULL for no group. */
 
218
        char *group;
 
219
        
 
220
        //! A pointer to the function that will be called when initializing the game
 
221
        void (*game_init) (struct _Game *);
 
222
}Game;
 
223
 
 
224
//! How to render a square
 
225
typedef enum 
 
226
{
 
227
        //! Just use the default pixmap
 
228
        RENDER_NONE, 
 
229
        //! Draw a colored border around the square. See #game_highlight_colors
 
230
        RENDER_HIGHLIGHT1, RENDER_HIGHLIGHT2, RENDER_HIGHLIGHT3,
 
231
        //! Shade the square. Not yet implemented
 
232
        RENDER_SHADE1, RENDER_SHADE2, RENDER_SHADE3,
 
233
        //! Make the square look like a button
 
234
        RENDER_BUTTONIZE,
 
235
        //! Hide the square (show the background color)
 
236
        RENDER_HIDE,
 
237
        //! Use a different pixmap. 
 
238
        /** The pixmap must be specified in the 8-15th bits, 
 
239
          i.e, if you want to use the pixmap of the piece p,
 
240
          then you must set the render value to p << 8 | RENDER_REPLACE */
 
241
        RENDER_REPLACE,
 
242
} RenderType;
 
243
 
 
244
//! A struct describing a position in a game.
 
245
typedef struct
 
246
{
 
247
        //! Which game is going on
 
248
        Game *game;
 
249
        
 
250
        //! An array representing the pieces of each square.
 
251
        /** The size of the array is #board_wid * #board_heit.
 
252
          For each pair (x, y), board[y * board_wid + x] is a value between 0
 
253
          and num_pieces inclusive which gives the piece at the square (x, y).
 
254
          0 always indicates an empty square. The origin of the coordinates is
 
255
          at the bottom left. */
 
256
        byte *board;
 
257
 
 
258
        //! Additional information about how to render the square
 
259
        /** For example, highlight, shade, hide etc. See #RenderType*/
 
260
        /* A note on why this is int* while board is byte*: the latter will
 
261
         be used by the engine, and so size is important. But render can be 
 
262
         big because it will be used only by the engine which will have only
 
263
         once instance of Pos*/
 
264
        int *render;
 
265
 
 
266
        //! Which player has the move. 
 
267
        Player player;
 
268
 
 
269
        //! State information required to completely describe the position
 
270
        /** Some games are <i>stateful</i>, which means that the position can not
 
271
          be completely described by the state of the board alone. 
 
272
          In chess (chess.c), for example, we need to keep track of whether
 
273
          either player can castle, etc. The variable state points to a 
 
274
          struct which is defined by the game. It is modified using the function
 
275
          game_newstate().*/
 
276
        void *state;
 
277
 
 
278
        //! Client-side state information () (currently unused)
 
279
        void *ui_state;
 
280
 
 
281
        //! The number of moves that have been made to reach the current position.
 
282
        /** In two-player games, it represents the number of ply.*/
 
283
        int num_moves;
 
284
 
 
285
        //! (engine only) If this position has been generated during search, how deep from the root node is it.
 
286
        int search_depth;
 
287
}Pos;
 
288
 
 
289
//! If you have implemented more than one evaluation function then you put them in an array of structs of type HeurTab. Its unlikely that you'll need to know about this. See #game_htab for more details.
 
290
typedef struct
 
291
{
 
292
        //! The user-visible name of the evaluation function.
 
293
        char *name;
 
294
 
 
295
        //! A pointer to the function. See game_eval().
 
296
        float (*eval_fun) (Pos *, int);
 
297
 
 
298
        //! A description of the function so that the user can know what its about.
 
299
        char *comment;
 
300
 
 
301
        //! Currently unused.
 
302
        char *args;
 
303
}HeurTab;
 
304
 
 
305
typedef struct
 
306
{
 
307
        //! The name to show in the Levels menu
 
308
        char *name;
 
309
 
 
310
        //! Pointer to the Game (Each level is treated as a separate Game)
 
311
        Game *game;
 
312
}GameLevel;
 
313
 
 
314
//! A pointer to the game's evaluation function. 
 
315
/** Only for two player games. It <b>must</b> be implemented if you want
 
316
  the computer to be able to play the game. */
 
317
extern ResultType (*game_eval) (Pos *pos, Player player, float *eval);
 
318
 
 
319
//! A pointer to the game's incremental evaluation function. 
 
320
/** Only for two player games. This is an advanced feature: if you feel
 
321
 that being forced to look at the whole board for each call to game_eval
 
322
 is inefficient, you can write an incremental evaluation function which
 
323
 takes a position and the move being made and returns the <i>difference</i> in
 
324
 the eval of the original and final positions. Note that you still need
 
325
 to implement game_eval even if you implement this function. Since
 
326
 premature optimization is the root of all evil, it is highly recommended
 
327
 that you get your game working and stable before you think of implementing
 
328
 this function :)*/
 
329
extern ResultType (*game_eval_incr) (Pos *pos, byte *move, float *eval);
 
330
 
 
331
//! Should we use the incr eval function
 
332
extern gboolean (*game_use_incr_eval) (Pos *pos);
 
333
 
 
334
//! A function to search and return the best move - for games for which minimax is not appropriate
 
335
extern void (*game_search) (Pos *pos, byte **move);
 
336
 
 
337
//! A pointer to the game's move generation function.
 
338
/** Only for two player games. It <b>must</b> be implemented if you want
 
339
  the computer to be able to play the game. 
 
340
 
 
341
 It returns a list of moves possible in a given position. See move.h
 
342
 for documentation of the MOVLIST format. Plot4's movegen function 
 
343
 (plot4_movegen()) is a good example of a simple movegen function.
 
344
 
 
345
 The move list (array) should be malloc'd inside this function 
 
346
 and will be freed by the caller.
 
347
 */
 
348
extern byte * (*game_movegen) (Pos *);
 
349
 
 
350
 
 
351
//! This takes a mouse click and returns the move that it corresponds to.
 
352
/**     @param pos 
 
353
        @param x x coordinate of the square that was clicked
 
354
        @param y y coordinate of the square that was clicked
 
355
        @param type type of event
 
356
        @param to_play whose turn is it
 
357
        @param movp a pointer to store the move in if the move is valid
 
358
        @param returns: >0 if move is valid, 0 if more information is needed, -1 if move is illegal // TODO: there should be an enum for this
 
359
 
 
360
        pentaline_getmove() is a good example of a minimal getmove function.
 
361
 
 
362
 */
 
363
extern int (*game_getmove) (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte ** movp, int **renderp);
 
364
 
 
365
//! The all-in-one function that makes game_getmove and game_getmove_kb deprecated
 
366
/** */
 
367
extern InputType (*game_event_handler) (Pos *pos, GtkboardEvent *event, MoveInfo *move_info_p);
 
368
 
 
369
//! Takes a keypress and returns the move that it corresponds to.
 
370
/**     @param pos
 
371
        @param key the key that the user pressed
 
372
        @param to_play
 
373
        @param movp a pointer to the move. The game must allocate memory for this (statically).
 
374
        @param rmovp pointer to rendering change
 
375
*/
 
376
extern int (*game_getmove_kb) (Pos *pos, int key, byte ** movp, int **rmovp);
 
377
 
 
378
//! Checks if the game is over, and if so, who has won
 
379
/** This function is called after every move, both for single player and two player games. 
 
380
 @param scorep pointer to the "score". If game_who_won sets this, the score will be displayed in the score field of the statusbar.
 
381
*/
 
382
extern ResultType (*game_who_won) (Pos *pos, Player player, char ** scorep);
 
383
 
 
384
//! Pointer to function which sets the game's initial position.
 
385
/** In some games such as maze (maze.c), the initial position is not constant but randomly generated. Such functions use game_set_init_pos. The function is expected to set the value of pos->board.*/
 
386
extern void (*game_set_init_pos) (Pos *pos);
 
387
 
 
388
//! Sets the initial state of the rendering hints
 
389
extern void (*game_set_init_render) (Pos *pos);
 
390
 
 
391
//! The rendering hints associated with the move
 
392
extern void (*game_get_render) (Pos *pos, byte *move, int **rmovp);
 
393
 
 
394
//! Returns the pixmap for a piece.
 
395
/** In many games, the pixmaps are generated at runtime (see aaball.c). Such games use this function. The second argument color is 0 or 1 depending on whether the piece will be shown on a light square or a dark square. If your pixmap is antialiased you need this.*/
 
396
extern char ** (*game_get_pixmap) (int piece, int color);
 
397
 
 
398
//! Same as game_get_pixmap() but returns a rgbmap instead of pixmap.
 
399
extern guchar * (*game_get_rgbmap) (int piece, int color);
 
400
 
 
401
//! Pointer to animation callback which will be called periodically
 
402
extern int (*game_animate) (Pos *pos, byte ** movp);
 
403
 
 
404
//! Pointer to function which will compute the new state from the current position and the move
 
405
/** The returned state should be a pointer to a statically declared structure. */
 
406
extern void * (*game_newstate) (Pos *pos, byte * move);
 
407
 
 
408
//! Called at the end of every game.
 
409
extern void (*game_free) ();
 
410
 
 
411
//! The default value of game_set_init_pos()
 
412
//extern void game_set_init_pos_def (Pos *);
 
413
 
 
414
//! This is called after each move the user completes
 
415
/** The user may have made some clicks which do not complete a move and then
 
416
 clicked the back button, for example. Then the game must forget the saved clicks.*/
 
417
extern void (*game_reset_uistate) ();
 
418
 
 
419
//! Globals for convenience.
 
420
extern int board_wid, board_heit, cell_size, num_pieces;
 
421
 
 
422
//! Are we a single player game or a two-player game? DEFAULT: FALSE.
 
423
extern int game_single_player;
 
424
 
 
425
//! Is the user allowed to undo move and still get on the highscores (only for single player games; default: FALSE)
 
426
extern gboolean game_allow_undo;
 
427
 
 
428
//! Determines how frequently to call the game's animation callback function (game_animate()). Default: 0.
 
429
extern int game_animation_time;
 
430
 
 
431
//! Whether or not to consider animations "moves". Default: TRUE.
 
432
extern gboolean game_animation_use_movstack;
 
433
 
 
434
//! Are we a stateful game. Default: FALSE
 
435
extern gboolean game_stateful;
 
436
 
 
437
//! Should the lines between the rows and columns be drawn. Default: FALSE.
 
438
/** Example of game which draws boundaries: pentaline (pentaline.c)
 
439
    Example of game which doesn't draw boundaries: memory (memory.c) */
 
440
extern gboolean game_draw_cell_boundaries;
 
441
 
 
442
//! Colors to use for highlighting squares.
 
443
extern char *game_highlight_colors;
 
444
 
 
445
//! Should we allow the user to move back and forward in the game. Default: TRUE
 
446
/** You should not set this to FALSE unless you have a compelling reason to do so.
 
447
  Don't worry about the user cheating and getting a highscore that they don't deserve -- if the user ever clicks back, highscores will be disabled for that game :-) Currently only tetris (tetris.c) sets this to FALSE, because of some complex client-server related issues.*/
 
448
extern gboolean game_allow_back_forw;
 
449
 
 
450
//! Should the user's clock start ticking as soon as the game is selected. Default: FALSE.
 
451
/** Doesn't make a lot of sense for two player games. In games like maze (maze.c), the user can solve the maze without even making a move, so it would be unfair to let them look at the maze without starting the clock. */
 
452
extern gboolean game_start_immediately;
 
453
 
 
454
//! (Only for two player games) Is Settings->Flip Board active. For single player games it is always inactive.
 
455
extern gboolean game_allow_flip;
 
456
 
 
457
//! How to display names of rows and columns. This should be of type FILERANK_LABEL_TYPE, optionally ORed with FILERANK_LABEL_DESC
 
458
extern gboolean game_file_label, game_rank_label;
 
459
        
 
460
//! Size of the Pos::state structure
 
461
/** For stateful games, you need to specify the size of the state structure (as defined by the sizeof operator.) */
 
462
extern int game_state_size;
 
463
 
 
464
extern GameLevel *game_levels;
 
465
 
 
466
//! Array of structs representing evaluation functions.
 
467
extern HeurTab *game_htab;
 
468
 
 
469
//! The text to be shown in the About dialog for the game (Help->GameName->About).
 
470
extern gchar *game_doc_about;
 
471
//! The text to be shown in the Rules dialog for the game (Help->GameName->Rules).
 
472
extern gchar *game_doc_rules;
 
473
//! The text to be shown in the Strategy dialog for the game (Help->GameName->Strategy).
 
474
extern gchar *game_doc_strategy;
 
475
//! The text to be shown in the History dialog for the game (Help->GameName->History).
 
476
extern gchar *game_doc_history;
 
477
 
 
478
//! Completion status of the game
 
479
extern CompletionStatus game_doc_about_status;
 
480
 
 
481
//! User visible labels for white and black
 
482
extern gchar *game_white_string, *game_black_string;
 
483
 
 
484
 
 
485
//! Background image for the board
 
486
extern char ** game_bg_pixmap;
 
487
 
 
488
 
 
489
//! The columns that will be shown in the highscores.
 
490
/** SCORE_FIELD_NONE acts as a NULL terminator for the #game_score_fields array.
 
491
 Note that highscores make sense only for single player games.*/
 
492
typedef enum {
 
493
        SCORE_FIELD_NONE, 
 
494
        SCORE_FIELD_RANK, SCORE_FIELD_USER, SCORE_FIELD_SCORE, SCORE_FIELD_TIME, SCORE_FIELD_DATE, 
 
495
        SCORE_FIELD_MISC1, SCORE_FIELD_MISC2
 
496
} SCORE_FIELD;
 
497
 
 
498
//! Used to override the default highscore columns.
 
499
/** By default, the columns shown in the highscores are User, Score, Time and Date. This sequence can be overridden by specifying a game_score_fields array terminated by #SCORE_FIELD_NONE. #SCORE_FIELD_MISC1 and #SCORE_FIELD_MISC2 are used to specify some field which is none of the 5 available by default. The MISC functionality is currently unimplemented */
 
500
extern SCORE_FIELD * game_score_fields;
 
501
 
 
502
//! The names of the column titles in the highscores.
 
503
/** If you set #game_score_fields you also have to set game_score_field_names which gives the titles to use for the respective columns. */
 
504
extern gchar **game_score_field_names;
 
505
 
 
506
//! Pointer to the comparison function used to order highscores.
 
507
/** Highscores work by applying the comparison function on the 
 
508
  score string returned by game_who_won(). Three defaults are 
 
509
  availble (see below), one of which will likely fit what you want.
 
510
  If not you can write your own function and set this pointer to it.*/
 
511
extern int (*game_scorecmp) (gchar *, int, gchar*, int);
 
512
 
 
513
//! Default highscore comparison function: decreasing order of Score field.
 
514
extern int (*game_scorecmp_def_dscore) (gchar *, int, gchar*, int);
 
515
//! Default highscore comparison function: increasing order of Score field.
 
516
extern int (*game_scorecmp_def_iscore) (gchar *, int, gchar*, int);
 
517
//! Default highscore comparison function: increasing order of Time field.
 
518
extern int (*game_scorecmp_def_time) (gchar *, int, gchar*, int);
 
519
 
 
520
#endif