{-------------------------------------------------------------------}
{
{    CHESSVOX - Programa de Xadrez Vox
{
{    Módulo de estruturas de dados
{
{    Autor: José Antonio Borges
{
{    Adaptação para o DOSVOX do TSCP
{         Tom Kerrigan's Simple Chess Program (TSCP)
{         Copyright 1997 Tom Kerrigan
{
{    Em setembro/2007
{
{-------------------------------------------------------------------}

unit data;

interface

uses defs;

{ the board representation }

var
    firstVar: byte;     (************** delimiting vars to save *****************)

    color: array [0..63] of integer;  { LIGHT, DARK, or EMPTY }
    piece: array [0..63] of integer;  { PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, or EMPTY }

    side: integer;    { the side to move }
    xside: integer;   { the side not to move }
    castle: integer;  { a bitfield with the castle permissions.
        if 1 is set, white can still castle kingside.
        2 is white queenside.
        4 is black kingside.
        8 is black queenside. }

    ep: integer;  { the en passant square.
                    if white moves e2e4, the en passant square is set to e3,
                    because that's where a pawn would move in an en passant capture }
    fifty: integer;  { the number of moves since a capture or pawn move, used
                       to handle the fifty-move-draw rule }
    hash: integer;  { a (more or less) unique number that corresponds to
                      the position }
    ply: integer;  { the number of half-moves (ply) since the root of the
                     search tree }
    hply: integer;  { h for history; the number of ply since the beginning
                      of the game }

    computer_side: integer;  { computer side when playing }
    last_play: string[10];   { computer last play }
    play_time: extended;     { play begin time }

{ gen_dat is some memory for move lists that are created by the move
   generators. The move list for ply n starts at first_move[n] and ends
   at first_move[n + 1]. }

    gen_dat: array [0..GEN_STACK-1] of gen_t;
    first_move: array [0..MAX_PLY-1] of integer;

{ the history heuristic array (used for move ordering) }
    history: array [0..63, 0..63] of integer;

{ we need an array of hist_t's so we can take back the
   moves we make }
    hist_dat: array [0..HIST_STACK-1] of hist_t;

{ the engine will search for max_time milliseconds or until it finishes
   searching max_depth ply. }
    max_time: integer;
    max_depth: integer;

{ the time when the engine starts searching, and when it should stop }
    start_time: extended;
    nodes: integer;  { the number of nodes we've searched }

{ a "triangular" PV array; for a good explanation of why a triangular
   array is needed, see "How Computers Play Chess" by Levy and Newborn. }

    pv: array [0..MAX_PLY-1, 0..MAX_PLY-1] of move;
    pv_length: array [0..MAX_PLY-1] of integer;
    follow_pv: boolean;

{ random numbers used to compute hash; see set_hash() in board.c }
    hash_piece: array [0..1, 0..5, 0..63] of integer;
              { indexed by piece [color][type][square] }
    hash_side: integer;
    hash_ep: array [0..63] of integer;

    lastVar: byte;   (************** delimiting vars to save *****************)

    debugging: boolean;
    playing: boolean;


{ Now we have the mailbox array, so called because it looks like a
   mailbox, at least according to Bob Hyatt. This is useful when we
   need to figure out what pieces can go where. Let's say we have a
   rook on square a4 (32) and we want to know if it can move one
   square to the left. We subtract 1, and we get 31 (h5). The rook
   obviously can't move to h5, but we don't know that without doing
   a lot of annoying work. Sooooo, what we do is figure out a4's
   mailbox number, which is 61. Then we subtract 1 from 61 (60) and
   see what mailbox[60] is. In this case, it's -1, so it's out of
   bounds and we can forget it. You can see how mailbox[] is used
   in attack() in board.c. }

const
    mailbox: array [0..119] of integer = (
	 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	 -1,  0,  1,  2,  3,  4,  5,  6,  7, -1,
	 -1,  8,  9, 10, 11, 12, 13, 14, 15, -1,
	 -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
	 -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
	 -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
	 -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
	 -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
	 -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
	 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    );

    mailbox64: array [0..63] of integer = (
	21, 22, 23, 24, 25, 26, 27, 28,
	31, 32, 33, 34, 35, 36, 37, 38,
	41, 42, 43, 44, 45, 46, 47, 48,
	51, 52, 53, 54, 55, 56, 57, 58,
	61, 62, 63, 64, 65, 66, 67, 68,
	71, 72, 73, 74, 75, 76, 77, 78,
	81, 82, 83, 84, 85, 86, 87, 88,
	91, 92, 93, 94, 95, 96, 97, 98
    );

{ slide, offsets, and offset are basically the vectors that
   pieces can move in. If slide for the piece is FALSE, it can
   only move one square in any one direction. offsets is the
   number of directions it can move in, and offset is an array
   of the actual directions. }

    slide: array [0..5] of boolean = (
	FALSE, FALSE, TRUE, TRUE, TRUE, FALSE
    );

    offsets: array [0..5] of integer = (
	0, 8, 4, 4, 8, 8
    );

    offset: array [0..5, 0..7] of integer = (
	( 0, 0, 0, 0, 0, 0, 0, 0 ),
	( -21, -19, -12, -8, 8, 12, 19, 21 ),
	( -11, -9, 9, 11, 0, 0, 0, 0 ),
	( -10, -1, 1, 10, 0, 0, 0, 0 ),
	( -11, -10, -9, -1, 1, 9, 10, 11 ),
	( -11, -10, -9, -1, 1, 9, 10, 11 )
    );


{ This is the castle_mask array. We can use it to determine
   the castling permissions after a move. What we do is
   logical-AND the castle bits with the castle_mask bits for
   both of the move's squares. Let's say castle is 1, meaning
   that white can still castle kingside. Now we play a move
   where the rook on h1 gets captured. We AND castle with
   castle_mask[63], so we have 1&14, and castle becomes 0 and
   white can't castle kingside anymore. }

    castle_mask: array [0..63] of integer = (
	 7, 15, 15, 15,  3, 15, 15, 11,
	15, 15, 15, 15, 15, 15, 15, 15,
	15, 15, 15, 15, 15, 15, 15, 15,
	15, 15, 15, 15, 15, 15, 15, 15,
	15, 15, 15, 15, 15, 15, 15, 15,
	15, 15, 15, 15, 15, 15, 15, 15,
	15, 15, 15, 15, 15, 15, 15, 15,
	13, 15, 15, 15, 12, 15, 15, 14
    );


{ the piece letters, for print_board() }
    piece_char: array [0..5] of char = (
	'P', 'C', 'B', 'T', 'D', 'R'
    );

{ the piece names }
    piece_name: array [0..6] of string[8] = (
	'XDPEAO', 'XDCAVALO', 'XDBISPO', 'XDTORRE', 'XDDAMA', 'XDREI', ''
    );


{ the initial board state }

    init_color: array [0..63] of integer = (
	1, 1, 1, 1, 1, 1, 1, 1,
	1, 1, 1, 1, 1, 1, 1, 1,
	6, 6, 6, 6, 6, 6, 6, 6,
	6, 6, 6, 6, 6, 6, 6, 6,
	6, 6, 6, 6, 6, 6, 6, 6,
	6, 6, 6, 6, 6, 6, 6, 6,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0
    );

    init_piece: array [0..63] of integer = (
	3, 1, 2, 4, 5, 2, 1, 3,
	0, 0, 0, 0, 0, 0, 0, 0,
	6, 6, 6, 6, 6, 6, 6, 6,
	6, 6, 6, 6, 6, 6, 6, 6,
	6, 6, 6, 6, 6, 6, 6, 6,
	6, 6, 6, 6, 6, 6, 6, 6,
	0, 0, 0, 0, 0, 0, 0, 0,
	3, 1, 2, 4, 5, 2, 1, 3
    );


implementation

end.


