/* Pepito v1.59  -- file: macros.h --
   Copyright (c) 2000-02 Carlos del Cacho

   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 2, 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; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Contact the author: guggenjaimito@yahoo.com
*/

//#define USE_ASSEMBLY

#ifdef _WIN64
#define VERSION_STRING          "Pepito v1.59.2 x64 JA"
#endif

#ifdef _WIN32
#define VERSION_STRING          "Pepito v1.59.2 x86 JA"
#endif

#ifdef LINUX
#define VERSION_STRING          "Pepito v1.59.2 Linux JA"
#endif




#define JAQUE_MATE        10000
#define TABLAS                0
#define DRAW_CONTEMPT         0

#define BUENA_LIBRO       0x2000000
#define MALA_LIBRO        0x80000000

#define PAWN_HASH_MASK    (PAWN_HASH_SIZE - 1)
#define MOV_STACK_SIZE    2500

#ifdef LINUX
#define CDECL
#endif

#define MIRA_LIBRO     1
#define NO_MIRA_LIBRO  0

#define Mask(a)                  ((entero64) 1 << a)
#define Max(A,B)                 ((A)>(B)?(A):(B))
#define Min(A,B)                 ((A)<(B)?(A):(B))
#define Abs(A)                    ((A)>0?(A):-(A))
#define MOD8(A)                   ((A) & 7)
#define DIV8(A)                   ((A) >> 3)
#define Distancia(A,B)       Max(  Abs(MOD8(A)-MOD8(B)), Abs(DIV8(A)-DIV8(B)))

#define CIERTO     1
#define FALSO      0

#define UNIT_PROF   64

#define  ELIGE_HASH            2
#define  GEN_JAQS              0
#define  ELIGE_JAQS            1
#define  ELIGE_JAQS_HIST      -1
#define  PRUEBA_NULL           3
#define  GEN_CAPS              4
#define  ELIGE_CAPS            5
#define  GEN_SEE               6
#define  ELIGE_CAPS_MVV_LVA    7
#define  ELIGE_CAPS_SEE        8
#define  KILLER_1              9
#define  KILLER_2             10
#define  OTRAS_CAPS           11
#define  GEN_NO_CAPS          12
#define  ELIGE_NO_CAPS        13

#define COLUMNA_0       ((entero64)0x101010101010101)
#define COLUMNA_1       ((entero64)0x202020202020202)
#define COLUMNA_2       ((entero64)0x404040404040404)
#define COLUMNA_3       ((entero64)0x808080808080808)
#define COLUMNA_4       ((entero64)0x1010101010101010)
#define COLUMNA_5       ((entero64)0x2020202020202020)
#define COLUMNA_6       ((entero64)0x4040404040404040)
#define COLUMNA_7       ((entero64)0x8080808080808080)

#define FILA_0          ((entero64)0xff)
#define FILA_1          ((entero64)0xff00)
#define FILA_2          ((entero64)0xff0000)
#define FILA_3          ((entero64)0xff000000)
#define FILA_4          ((entero64)0xff00000000)
#define FILA_5          ((entero64)0xff0000000000)
#define FILA_6          ((entero64)0xff000000000000)
#define FILA_7          ((entero64)0xff00000000000000)

#define REY_B_ENRQ_CORTO    0x0400U
#define REY_B_ENRQ_LARGO    0x0800U
#define REY_N_ENRQ_CORTO    0x1000U
#define REY_N_ENRQ_LARGO    0x2000U

#define SEVERAL_BOOK_MOVES  0x0010U
#define NO_BOOK_MOVES       0x0000U

#define PURGE_HASH_MV       1
#define PURGE_KILLER_1      2
#define PURGE_KILLER_2      4


#define MAXMOV                    500

//#define Lsb(num)   Msb(num ^ (num-1))
#define INFINITO          32767
#define MAX_PROF            (100+MAX_QUIESCE)
#define MAX_QUIESCE          30


#define MITAD_BLANCAS          ((entero64)0x0000000000000000ffffffffffffffff)
#define MITAD_NEGRAS           ~MITAD_BLANCAS
#define ENTRADA_VIEJA          ((entero64)0x1000000000000000)

#define BLANCAS                   1
#define NEGRAS                    0

#define ES_NEGRA                  8
#define VACIA                     0
#define PEON_B                    1
#define CABALLO_B                 2
#define ALFIL_B                   3
#define TORRE_B                   4
#define DAMA_B                    5
#define REY_B                     6

#define PEON_N                    7
#define CABALLO_N                 8
#define ALFIL_N                   9
#define TORRE_N                  10
#define DAMA_N                   11
#define REY_N                    12

#define REY_VAL                 5000
#define DAMA_VAL                 950
#define TORRE_VAL                480
#define ALFIL_VAL                300
#define CABALLO_VAL              300
#define PEON_VAL                 100

#define E_CORTO_B                  1
#define E_LARGO_B                  2
#define E_CORTO_N                  4
#define E_LARGO_N                  8
#define ALGUN_ENROQUE            0xf

#define LIM_INF_NULL               0
#define LIM_SUP                    1
#define LIM_INF                    2
#define EXACTO                     3
#define LAZY_BOUND                 4


#define AtaquesCaballo(A)      (ATAQUES_CABALLO[A])

#define AtaquesAlfil(A)        (ATAQUES_ALFIL_45[A][255 &                  \
                               (Rotado45 >> SHIFT_45[A])]                  \
                               | ATAQUES_ALFIL_315[A][255 & (Rotado315 >>  \
                               SHIFT_315[A])])

#define AtaquesTeoricosAlfil(A)        (ATAQUES_ALFIL_45[A][0] | ATAQUES_ALFIL_315[A][0])

#define AtaquesTorre(A)       (ATAQUES_TORRE_FIL[A][255 &                  \
                              ((Blancas|Negras) >> 8*DIV8(A))]             \
                              | ATAQUES_TORRE_COL[A][255 & (Rotado90 >>    \
                              8*MOD8(A))])

#define AtaquesTorreCol(A)    (ATAQUES_TORRE_COL[A][255 & (Rotado90 >>    \
                              8*MOD8(A))])
#define AtaquesTeoricosTorre(A)    (ATAQUES_TORRE_FIL[A][0] | ATAQUES_TORRE_COL[A][0])

#define AtaquesDama(A)        (AtaquesAlfil(A) | AtaquesTorre(A))
#define AtaquesRey(A)         ATAQUES_REY[A]
#define AtaquesPeonB(A)       ATAQUES_PEON_B[A]
#define AtaquesPeonN(A)       ATAQUES_PEON_N[A]


#define TBalance     (Material(Turno)-Material(!Turno))

#define Turno                     tab.pos.turno
#define Movimientos               tab.pos.mov
#define Tablero                   tab.pos.tab
#define Piezas                    tab.pos.piezas
#define PiezasB                   tab.pos.piezas[1]
#define PiezasN                   tab.pos.piezas[0]
#define NumPeonesB                tab.pos.peones[1]
#define NumPeonesN                tab.pos.peones[0]
#define NumPeones                 tab.pos.peones
#define ColgadasB                 tab.pos.colgadas[1]
#define ColgadasN                 tab.pos.colgadas[0]
#define Colgadas                  tab.pos.colgadas
#define EnrocadoB                 tab.pos.enrocadoB
#define EnrocadoN                 tab.pos.enrocadoN
#define PosPieza(a)               tab.pos.pos_piezas[a]
#define PeonesN                   tab.pos.pos_piezas[PEON_N]
#define PeonesB                   tab.pos.pos_piezas[PEON_B]
#define AlfilesN                  tab.pos.pos_piezas[ALFIL_N]
#define AlfilesB                  tab.pos.pos_piezas[ALFIL_B]
#define CaballosN                 tab.pos.pos_piezas[CABALLO_N]
#define CaballosB                 tab.pos.pos_piezas[CABALLO_B]
#define TorresN                   tab.pos.pos_piezas[TORRE_N]
#define TorresB                   tab.pos.pos_piezas[TORRE_B]
#define DamasN                    tab.pos.pos_piezas[DAMA_N]
#define DamasB                    tab.pos.pos_piezas[DAMA_B]
#define ReyN                      tab.pos.pos_piezas[REY_N]
#define ReyB                      tab.pos.pos_piezas[REY_B]
#define PiezasColor(a)            tab.pos.piezascolor[a]
#define Negras                    tab.pos.piezascolor[0]
#define Blancas                   tab.pos.piezascolor[1]
#define Rotado315                 tab.pos.rotado315
#define Rotado45                  tab.pos.rotado45
#define Rotado90                  tab.pos.rotado90
#define PosReyB                   tab.pos.reyblanco
#define PosReyN                   tab.pos.reynegro
#define Enroque                   tab.pos.pos_status
#define PosStatus                 tab.pos.pos_status
#define HashGlob                  tab.pos.hash_global
#define HashPeones                tab.pos.hash_peones
#define MaterialB                 tab.pos.material[1]
#define MaterialN                 tab.pos.material[0]
#define Material(a)               tab.pos.material[a]
#define AlPaso                    tab.pos.alpaso
#define Historial                 tab.hist
#define HistHeuristic             tab.history
#define NumJug                    tab.pos.num_jug
#define RNumJug                   tab.rnum_jug
#define RTurno                    tab.rturno
#define QuedaTiempo               tab.queda_tiempo
#define MaxProf                   tab.profmax
#define ValorJug                  tab.valor_jug
#define JugStack                  tab.jug_stack
#define Zobrist(a,b)              ZOBRIST[a-1][b]

#define Mueve_Ficha(pieza,desde,hacia)   Tablero[hacia] = pieza;                                    \
                                         Tablero[desde] = VACIA;                                    \
                                         HashGlob ^= Zobrist(pieza,desde) ^ Zobrist(pieza,hacia);   \
                                         PiezasColor(Turno) ^= MASK[desde] ^ MASK[hacia];           \
                                         PosPieza(pieza) ^= MASK[desde] ^ MASK[hacia];              \
                                         Rotado90 ^= (MASK[ROTADO_90[desde]]|                       \
                                         MASK[ROTADO_90[hacia]]);                                   \
                                         Rotado45 ^= (MASK[ROTADO_45[desde]]|                       \
                                         MASK[ROTADO_45[hacia]]);                                   \
                                         Rotado315 ^= (MASK[ROTADO_315[desde]]|                     \
                                         MASK[ROTADO_315[hacia]]);                                  \

#define Mueve_NH_Ficha(pieza,desde,hacia)  Tablero[hacia] = pieza;                                    \
                                           Tablero[desde] = VACIA;                                    \
                                           PiezasColor(Turno) ^= MASK[desde] ^ MASK[hacia];           \
                                           PosPieza(pieza) ^= MASK[desde] ^ MASK[hacia];              \
                                           Rotado90 ^= (MASK[ROTADO_90[desde]]|                       \
                                           MASK[ROTADO_90[hacia]]);                                   \
                                           Rotado45 ^= (MASK[ROTADO_45[desde]]|                       \
                                           MASK[ROTADO_45[hacia]]);                                   \
                                           Rotado315 ^= (MASK[ROTADO_315[desde]]|                     \
                                           MASK[ROTADO_315[hacia]]);                                  \


#define Elimina_Ficha(ficha,pos)      PosPieza(ficha) ^= MASK[pos];                     \
                                      Rotado90 ^= MASK[ROTADO_90[pos]];                 \
                                      Rotado45 ^= MASK[ROTADO_45[pos]];                 \
                                      Rotado315 ^= MASK[ROTADO_315[pos]];               \
                                      HashGlob = HashGlob ^ Zobrist(ficha,pos)

#define Elimina_NH_Ficha(ficha,pos)   PosPieza(ficha) ^= MASK[pos];                     \
                                      Rotado90 ^= MASK[ROTADO_90[pos]];                 \
                                      Rotado45 ^= MASK[ROTADO_45[pos]];                 \
                                      Rotado315 ^= MASK[ROTADO_315[pos]]

#define HASH_E_CORTO_B       ((entero64)0x20d6151fffffffff)
#define HASH_E_LARGO_B       ((entero64)0x501ffc837f203fd2)
#define HASH_E_CORTO_N       ((entero64)0xb97aee2c6d)
#define HASH_E_LARGO_N       ((entero64)0x2aac0000fbad2c84)

#define MASK_F1G1        ((entero64)0x6000000000000000)
#define MASK_B1C1D1      ((entero64)0xe00000000000000)
#define MASK_F8G8        ((entero64)0x60)
#define MASK_B8C8D8      ((entero64)0xe)

#define CAPTURA         0xf000
#define PROMOCION       0xf0000
#define AL_PASO         0x100000
#define ENROQUE_CORTO   0x200000
#define ENROQUE_LARGO   0x400000
#define PEON_DE_2       0x800000

#define PRI_BOOK          0x030
#define SEC_BOOK          0x300

#define ONE_PRI_BOOK_TRY  0x010
#define ONE_SEC_BOOK_TRY  0x100

#define   MASCA_CHICLE            0x10000L

#define TWO_LEVEL_TABLE

#ifdef TWO_LEVEL_TABLE
#define HASH_INDEX_MASK  ((HASH_SIZE - 1) ^ 1)
#else
#define HASH_INDEX_MASK  (HASH_SIZE - 1)
#endif

#define WSCASTLEZONE	(Mask(F1)|Mask(G1)|Mask(H1)|Mask(F2)|Mask(G2)|Mask(H2)|	\
					     Mask(F3)|Mask(G3)|Mask(H3))

#define WLCASTLEZONE	(Mask(A1)|Mask(B1)|Mask(C1)|Mask(A2)|Mask(B2)|Mask(C2)|	\
					     Mask(A3)|Mask(B3)|Mask(C3))

#define BLCASTLEZONE	(Mask(A6)|Mask(B6)|Mask(C6)|Mask(A7)|Mask(B7)|Mask(C7)|	\
					     Mask(A8)|Mask(B8)|Mask(C8))

#define BSCASTLEZONE	(Mask(F6)|Mask(G6)|Mask(H6)|Mask(F7)|Mask(G7)|Mask(H7)|	\
					     Mask(F8)|Mask(G8)|Mask(H8))


#define TRIGGER_CHECK       1
#define TRIGGER_REPCHECK    2
#define TRIGGER_RECAP       4
#define TRIGGER_PPUSH       8
#define TRIGGER_THRT       16
#define TRIGGER_CSTRIKE    32
