Added playmode command 'C' to set a clock. When the clock runs out the
[cboard.git] / libchess / chess.h
blob50355a192bcdc1b9099cf68a2ad2ddd76436a4e2
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2002-2006 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef CHESS_H
20 #define CHESS_H
22 #define PGN_TIME_FORMAT "%Y.%m.%d"
23 #define MAX_PGN_LINE_LEN 255
24 #define MAX_SAN_MOVE_LEN 7
25 #define MAX_PGN_NAG 5
27 #define VALIDRANK VALIDFILE
28 #define VALIDFILE(f) (f >= 1 && f <= 8)
29 #define RANKTOBOARD ROWTOBOARD
30 #define FILETOBOARD COLTOBOARD
31 #define RANKTOINT ROWTOINT
32 #define FILETOINT COLTOINT
33 #define ROWTOBOARD(r) (8 - r)
34 #define COLTOBOARD(c) (c - 1)
35 #define ROWTOINT(r) (r - '0')
36 #define COLTOINT(c) (c - ('a' - 1))
37 #define VALIDROW(r) (r >= '1' && r <= '8')
38 #define VALIDCOL(c) (c >= 'a' && c <= 'h')
39 #define INTTORANK(r) (r + '0')
40 #define INTTOFILE(f) (f + ('a' - 1))
42 #define SET_FLAG(var, f) (var |= f)
43 #define CLEAR_FLAG(var, f) (var &= ~(f))
44 #define TOGGLE_FLAG(var, f) (var ^= (f))
45 #define TEST_FLAG(var, f) (var & f)
47 enum {
48 OPEN_SQUARE, PAWN, BISHOP, ROOK, KNIGHT, QUEEN, KING, MAX_PIECES
51 enum {
52 WHITE, BLACK
55 /* Game flags. */
56 #define GF_PERROR 0x01 /* Parse error for this game. */
57 #define GF_DELETE 0x02 /* Flagged for deletion ('x' command). */
58 #define GF_MODIFIED 0x04 /* Modified tags or history. */
59 #define GF_ENPASSANT 0x08 /* For En Passant validation. */
60 #define GF_GAMEOVER 0x010 /* End of game. */
61 #define GF_WK_CASTLE 0x020
62 #define GF_WQ_CASTLE 0x040
63 #define GF_BK_CASTLE 0x080
64 #define GF_BQ_CASTLE 0x0100
65 #define GF_BLACK_OPENING 0x0200
68 * The chess board.
70 typedef struct {
71 unsigned char icon; // The piece.
72 unsigned char valid: 1, // != 0 if this square is a valid move for the
73 // selected piece.
74 enpassant: 1;
75 } BOARD[8][8];
78 * PGN Roster tags.
80 typedef struct tags {
81 char *name; // Tag name.
82 char *value; // Tag value.
83 } TAG;
86 * Move history.
88 * g.hp is the pointer to the current history which may be .rav for
89 * Recursive Annotated Variations. The depth of recursion is kept track of in
90 * g.ravlevel.
92 typedef struct history {
93 char *move; // The SAN move text.
94 char *comment; // Annotation for this move.
95 unsigned char nag[MAX_PGN_NAG]; // Numeric Annotation Glyph. FIXME
96 struct history **rav; // Variation of the current move.
97 } HISTORY;
100 * Keeps game state history for the root move.
102 typedef struct {
103 char *fen; // Game board state.
104 unsigned short flags;
105 unsigned short hindex;
106 HISTORY **hp; // Pointer to the root move.
107 } RAV;
110 * This is an array of 'games' structures. One for each game in a file, or
111 * the current game.
113 typedef struct games {
114 TAG **tag; // Roster tags.
115 HISTORY **history; // Move history for this game.
116 HISTORY **hp; // History pointer pointing to the location
117 // in *history used mainly for RAV.
118 RAV *rav; // Saved game states for the root move of RAV.
119 int ravlevel; // An index to *rav.
120 unsigned short hindex; // Current move in *hp.
121 unsigned short flags; // Game flags.
122 unsigned char side: 1, // This playing side. BLACK or WHITE.
123 turn: 1, // BLACK or WHITE.
124 mode: 2; // MODE_[HISTORY/EDIT/PLAY]
125 unsigned short ply; // Move count.
126 void *data; /* User data associated with this game. Must
127 * be freed by the user. */
128 } GAME;
131 * Global GAME array. pgn_new_game() appends to this array.
133 GAME *game;
136 * 'gindex' and 'gtotal' are the current and total number of games in 'game'.
138 int gindex, gtotal;
141 * Library configuration flags. These will affect all games.
143 typedef enum {
145 * When pgn_write() is called to write a game, write reduced PGN format.
146 * This will only write the seven tag roster and move text skipping any
147 * annotation.
149 PGN_REDUCED,
152 * The number of full moves to write per line. If 0 then pgn_write() will
153 * write as many as possible within 80 columns.
155 PGN_MPL,
158 * Normally when a parse error occurs in a game the game is flagged with
159 * GF_PERROR and the rest of the game is discarded and processing of the
160 * next game is done. When set and a parse error occurs the rest of the
161 * entire file will be discarded.
163 PGN_STOP_ON_ERROR,
166 * After PGN_PROGRESS amount of bytes have been read from a file, call
167 * PGN_PROGRESS_FUNC.
169 PGN_PROGRESS,
170 PGN_PROGRESS_FUNC,
171 } pgn_config_flag;
174 * The prototype of the PGN_PROGRESS_FUNC function pointer.
176 typedef void (pgn_progress)(long size, long offset);
179 * Sets config flag 'f' to 'val'. Returns E_PGN_OK on success or E_PGN_ERR if
180 * 'f' is an invalid flag or 'val' is an invalid value.
182 int pgn_config_set(pgn_config_flag f, void *);
185 * Returns the value accociated with 'f' or NULL if 'f' is invalid.
187 void *pgn_config_get(pgn_config_flag f);
190 * Returns E_PGN_OK if 'filename' is a recognized compressed filetype or
191 * E_PGN_ERR if not.
193 int pgn_is_compressed(const char *filename);
196 * Returns a file pointer associated with 'filename' or NULL on error with
197 * errno set to indicate the error. If compressed file support was enabled at
198 * compile time and the filetype is supported and the utility is installed
199 * then the file will be decompressed.
201 FILE *pgn_open(const char *filename);
204 * Parses a file whose file pointer is 'fp'. 'fp' may have been returned by
205 * pgn_open(). If 'fp' is NULL then a single empty game will be allocated. If
206 * there is a parsing error E_PGN_PARSE is returned, if there was a memory
207 * allocation error E_PGN_ERR is returned, otherwise E_PGN_OK is returned and
208 * the global 'gindex' is set to the last parsed game in the file and the
209 * global 'gtotal' is set to the total number of games in the file. The file
210 * will be closed when the parsing is done.
212 int pgn_parse(FILE *fp);
215 * Allocates a new game and increments 'gtotal'. 'gindex' is then set to the
216 * new game. Returns E_PGN_ERR if there was a memory allocation error or
217 * E_PGN_OK on success.
219 int pgn_new_game();
222 * Writes a PGN formatted game 'g' to the file pointed to by 'fp'. See
223 * 'pgn_config_flag' for output options. Returns E_PGN_ERR if there was a
224 * memory allocation or write error and E_PGN_OK on success.
226 int pgn_write(FILE *fp, GAME g);
229 * Frees all games in the global 'game' array. Returns nothing.
231 void pgn_free_all(void);
234 * Frees a single game 'g'. Returns nothing.
236 void pgn_free(GAME g);
239 * Adds a tag 'name' with value 'value' to the pointer to array of TAG
240 * pointers 'dst'. If a duplicate tag 'name' was found then the existing tag
241 * is updated to the new 'value'. Returns E_PGN_ERR if there was a memory
242 * allocation error or E_PGN_OK on success.
244 int pgn_tag_add(TAG ***dst, char *name, char *value);
247 * Returns the total number of tags in 't' or 0 if 't' is NULL.
249 int pgn_tag_total(TAG **t);
252 * Finds a tag 'name' in the structure array 't'. Returns the location in the
253 * array of the found tag or E_PGN_ERR if the tag could not be found.
255 int pgn_tag_find(TAG **t, const char *name);
258 * Sorts a tag array. The first seven tags are in order of the PGN standard so
259 * don't sort'em. Returns nothing.
261 void pgn_tag_sort(TAG **t);
264 * Frees a TAG array. Returns nothing.
266 void pgn_tag_free(TAG **);
269 * It initializes the board (b) to the FEN tag (if found) and sets the
270 * castling and enpassant info for the game 'g'. If 'fen' is set it should be
271 * a fen tag and will be parsed rather than the game 'g'.tag FEN tag. Returns
272 * E_PGN_OK on success or if there was both a FEN and SetUp tag with the SetUp
273 * tag set to 0. Returns E_PGN_PARSE if there was a FEN parse error, E_PGN_ERR
274 * if there was no FEN tag or there was a SetUp tag with a value of 0. Returns
275 * E_PGN_OK on success.
277 int pgn_board_init_fen(GAME *g, BOARD b, char *fen);
280 * Creates a FEN tag from the current game 'g', history move (g.hindex) and
281 * board 'b'. Returns a FEN tag.
283 char *pgn_game_to_fen(GAME g, BOARD b);
286 * Resets or initializes a new game board 'b'. Returns nothing.
288 void pgn_board_init(BOARD b);
291 * Valididate move 'mp' against the game state 'g' and game board 'b' and
292 * update board 'b'. 'mp' is updated to SAN format for moves which aren't
293 * (a2a4 or e8Q for example). Returns E_PGN_PARSE if there was a move text
294 * parsing error, E_PGN_INVALID if the move is invalid, E_PGN_AMBIGUOUS if the
295 * move is invalid with ambiguities or E_PGN_OK if * successful.
297 int pgn_parse_move(GAME *g, BOARD b, char **mp);
300 * Like pgn_parse_move() but don't modify game flags in 'g' or board 'b'.
302 int pgn_validate_move(GAME *g, BOARD b, char **mp);
305 * Returns the total number of moves in 'h' or 0 if there are none.
307 int pgn_history_total(HISTORY **h);
310 * Returns the history ply 'n' from 'h'. If 'n' is out of range then NULL is
311 * returned.
313 HISTORY *pgn_history_by_n(HISTORY **h, int n);
316 * Appends move 'm' to game 'g' history pointer. The history pointer may be a
317 * in a RAV so g->rav.hp is also updated to the new (realloc()'ed) pointer. If
318 * not in a RAV then g->history will be updated. Returns E_PGN_ERR if
319 * realloc() failed or E_PGN_OK on success.
321 int pgn_history_add(GAME *g, const char *m);
324 * Deallocates all of the history data from position 'start' in the array 'h'.
325 * Returns nothing.
327 void pgn_history_free(HISTORY **h, int start);
330 * Resets the game 'g' using board 'b' up to history move (g.hindex) 'n'.
331 * Returns E_PGN_OK on success or E_PGN_PARSE if there was a FEN tag but the
332 * parsing of it failed. Or returns E_PGN_INVALID if somehow the move failed
333 * validation while resetting.
335 int pgn_board_update(GAME *g, BOARD b, int n);
338 * Updates the game 'g' using board 'b' to the next 'n'th history move.
339 * Returns nothing.
341 void pgn_history_prev(GAME *g, BOARD b, int n);
344 * Updates the game 'g' using board 'b' to the previous 'n'th history move.
345 * Returns nothing.
347 void pgn_history_next(GAME *g, BOARD b, int n);
350 * Converts the character piece 'p' to an integer. Returns the integer
351 * associated with 'p' or E_PGN_ERR if 'p' is invalid.
353 int pgn_piece_to_int(int p);
356 * Converts the integer piece 'n' to a character whose turn is 'turn'. WHITE
357 * piece are uppercase and BLACK pieces are lowercase. Returns the character
358 * associated with 'n' or E_PGN_ERR if 'n' is an invalid piece.
360 int pgn_int_to_piece(char turn, int n);
363 * Toggles g->turn. Returns nothing.
365 void pgn_switch_turn(GAME *);
368 * Toggles g->side and switches the White and Black roster tags. Returns
369 * nothing.
371 void pgn_switch_side(GAME *g);
374 * Clears the enpassant flag for all positions on board 'b'. Returns nothing.
376 void pgn_reset_enpassant(BOARD b);
379 * Clears the valid move flag for all positions on board 'b'. Returns nothing.
381 void pgn_reset_valid_moves(BOARD b);
384 * Sets valid moves from game 'g' using board 'b'. The valid moves are for the
385 * piece on the board 'b' at 'rank' and 'file'. Returns nothing.
387 void pgn_find_valid_moves(GAME g, BOARD b, int rank, int file);
390 * Returns the version string of the library.
392 char *pgn_version(void);
395 * Errors returned from the above functions.
397 typedef enum {
398 E_PGN_ERR = -1,
399 E_PGN_OK,
400 E_PGN_PARSE,
401 E_PGN_AMBIGUOUS,
402 E_PGN_INVALID,
403 E_MAX_PGN_ERRORS
404 } pgn_error;
406 #endif