1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/*
* Program: pgn-extract: a Portable Game Notation (PGN) extractor.
* Copyright (C) 1994-2001 David Barnes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* David Barnes may be contacted as D.J.Barnes@ukc.ac.uk
* http://www.cs.ukc.ac.uk/people/staff/djb/
*
*/
/* These colour values are used as modifiers of the Piece values to
* produce pieces of the appropriate colours.
* A coloured piece is formed by shifting the piece value and setting the
* bottom bit to either 0 (BLACK) or 1 (WHITE).
*/
typedef enum { BLACK, WHITE } Colour;
typedef enum {
OFF, EMPTY,
/* The order of these is important and used in several places.
* In particular, several for-loops iterate from PAWN to KING.
*/
PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING,
/* Must be last. */
NUM_PIECE_VALUES
} Piece;
/* Different classes of move determined by the lexical analyser. */
typedef enum { PAWN_MOVE, PAWN_MOVE_WITH_PROMOTION, ENPASSANT_PAWN_MOVE,
PIECE_MOVE, KINGSIDE_CASTLE, QUEENSIDE_CASTLE,
UNKNOWN_MOVE
} MoveClass;
/* Types for algebraic rank and column. */
typedef char Rank;
typedef char Col;
/* Define the base characters for ranks and columns. */
#define RANKBASE '1'
#define COLBASE 'a'
#define FIRSTRANK (RANKBASE)
#define LASTRANK (RANKBASE+BOARDSIZE-1)
#define FIRSTCOL (COLBASE)
#define LASTCOL (COLBASE+BOARDSIZE-1)
/* Convert the given rank to the correct index into a board. */
#define RankConvert(rank) ((FIRSTRANK <= (rank)) && ((rank) <= LASTRANK)?\
((rank)-RANKBASE+HEDGE):0)
/* Convert the given column to the correct index into a board. */
#define ColConvert(col) ((FIRSTCOL <= (col)) && ((col) <= LASTCOL)?\
((col)-COLBASE+HEDGE):0)
/* Convert a board index back to Rank or Col form. */
#define ToRank(r) ((r)+RANKBASE-HEDGE)
#define ToCol(c) ((c)+COLBASE-HEDGE)
#define COLOUR_OFFSET(colour) (((colour) == WHITE)? 1 : -1)
#define BOARDSIZE 8
/* Define the size of a hedge around the board.
* This should have a size of 2 to make calculation of Knight moves easier.
*/
#define HEDGE 2
/* Define a type for position hashing. */
typedef unsigned long HashCode;
typedef struct {
Piece board[HEDGE+BOARDSIZE+HEDGE][HEDGE+BOARDSIZE+HEDGE];
/* Who has the next move. */
Colour to_move;
/* The current move number. */
unsigned move_number;
/* Are the following castling options available? */
Boolean WKingCastle, WQueenCastle;
Boolean BKingCastle, BQueenCastle;
/* Keep track of where the two kings are, to make check-detection
* simple.
*/
Col WKingCol; Rank WKingRank;
Col BKingCol; Rank BKingRank;
/* Is EnPassant capture possible? If so then ep_rank and ep_col have
* the square on which this can be made.
*/
Boolean EnPassant;
Rank ep_rank;
Col ep_col;
HashCode hash_value;
} Board;
/* Define a type that can be used to create a list of possible source
* squares for a move.
*/
typedef struct move_pair {
Col from_col;
Rank from_rank;
Col to_col;
Rank to_rank;
struct move_pair *next;
} MovePair;
/* Conversion macros. */
#define PIECE_SHIFT 3
#define MAKE_COLOURED_PIECE(colour,piece) (((piece) << PIECE_SHIFT) | (colour))
#define W(piece) MAKE_COLOURED_PIECE(WHITE,piece)
#define B(piece) MAKE_COLOURED_PIECE(BLACK,piece)
/* Conversion macro, from one colour to another. */
#define OPPOSITE_COLOUR(colour) (!(colour))
#define EXTRACT_COLOUR(coloured_piece) ((coloured_piece) & 0x01)
#define EXTRACT_PIECE(coloured_piece) ((coloured_piece) >> PIECE_SHIFT)
|