Exemplo n.º 1
0
  inline Bitboard in_between(Index a, Index b) {
    // from https://chessprogramming.wikispaces.com/Square+Attacked+By#Obstructed
    // haven't taken the time to understand
    auto in_between_fn = [](Index sq1, Index sq2) {
      const Bitboard m1   = Bitboard(-1);
      const Bitboard a2a7 = Bitboard(0x0001010101010100);
      const Bitboard b2g7 = Bitboard(0x0040201008040200);
      const Bitboard h1b7 = Bitboard(0x0002040810204080); /* Thanks Dustin, g2b7 did not work for c1-a3 */
      Bitboard btwn, line, rank, file;
 
      btwn  = (m1 << sq1) ^ (m1 << sq2);
      file  =   (sq2 & 7) - (sq1   & 7);
      rank  =  ((sq2 | 7) -  sq1) >> 3 ;
      line  =      (   (file  &  7) - 1) & a2a7; /* a2a7 if same file */
      line += 2 * ((   (rank  &  7) - 1) >> 58); /* b1g1 if same rank */
      line += (((rank - file) & 15) - 1) & b2g7; /* b2g7 if same diagonal */
      line += (((rank + file) & 15) - 1) & h1b7; /* h1b7 if same antidiag */
      line *= btwn & -btwn; /* mul acts like shift by smaller square */
      return line & btwn;   /* return the bits on that line in-between */
    };

    static auto _in_between = [&]() {
      array2d<Bitboard, cardinality, cardinality> result;
      for (Index a: indices)
        for (Index b: indices)
          result[a][b] = in_between_fn(a, b);
      return result;
    }();
    return _in_between[a][b];
  }
Exemplo n.º 2
0
/*attacked() returns 1 if square 'target' is attacked by color 'color'
  and 0 otherwise*/
int attacked(const int target, const int color) {
	int c;
	unsigned __int64 all;
	all = Bitboard(BLACK) | Bitboard(WHITE);

	for (c = 0;c < 16;c++) {
			if (Active(color, c)) {
				assert(Name(color,0)==king);
				if (c>0) assert(Name(color,c)!=king);					
					
					if (Kind(color, c)&table_attack[target - Position(color, c) + 128]) {
							if (IsNoSlide(color, c))
								return 1;

							if ((all&(bit_ray[Position(color, c)][target])) == 0)
								return 1;
							}

					}

			}

	switch (color) {
			case BLACK:

				if (File(target) != FilaA && IsBPawn(target + UP_L))
					return 1;

				if (File(target) != FilaH && IsBPawn(target + UP_R))
					return 1;

				break;

			case WHITE:
				if (File(target) != FilaA && IsWPawn(target + DOWN_L))
					return 1;

				if (File(target) != FilaH && IsWPawn(target + DOWN_R))
					return 1;

				break;

			case EMPTY:
				printf("Bad color board detect in attacked(): %d",color);
				assert(0);
				break;

			default:
				printf("Bad color board detect in attacked(): %d",color);
				assert(0);

				break;
			}

	return 0;
	}
Exemplo n.º 3
0
  Bitboard operator ~ () const {
#if defined (HAVE_SSE2) || defined (HAVE_SSE4)
    Bitboard tmp;
    _mm_store_si128(&tmp.m_, _mm_andnot_si128(this->m_, _mm_set1_epi8(static_cast<char>(0xffu))));
    return tmp;
#else
    return Bitboard(~this->p(0), ~this->p(1));
#endif
  }
Exemplo n.º 4
0
ExtMove* generate(const Position& pos, ExtMove* mlist) {

	assert(Type == CAPTURES || Type == QUIETS || Type == NON_EVASIONS);
	assert(!pos.checkers());

	Color us = pos.side_to_move();

	Bitboard target = Type == CAPTURES     ?  pos.pieces(~us)
		: Type == QUIETS       ? ~pos.pieces()
		: Type == NON_EVASIONS ? ~pos.pieces(us) : Bitboard();

	return us == WHITE ? generate_all<WHITE, Type>(pos, mlist, target)
		: generate_all<BLACK, Type>(pos, mlist, target);
}
Exemplo n.º 5
0
/**
 * @return the Bitboard b, bitwise XOR with amount
 */
inline Bitboard operator^(Bitboard b,UINT_64 amount) {
	return Bitboard(b.bits.to_ulong() ^ amount);
}
Exemplo n.º 6
0
/**
 * @return the Bitboard a, bitwise OR with Bitboard b
 */
inline Bitboard operator|(Bitboard a,Bitboard b) {
	return Bitboard(a.bits | b.bits);
}
Exemplo n.º 7
0
/**
 * @return the bitwise complement of Bitboard b
 */
inline Bitboard operator~(Bitboard b) {
	return Bitboard(~b.bits);
}
Exemplo n.º 8
0
 */
inline bool operator==(Bitboard a,Bitboard b) {
	return a.bits == b.bits;
}
/**
 * @return whether Bitboard a does not equal Bitboard b
 */
inline bool operator!=(Bitboard a,Bitboard b) {
	return a.bits != b.bits;
}

/**
 * a Bitboard masking the A rank, e.g. to get a bitboard and ignore
 * the A rank, do calc_result = calc_result & NOT_A_MASK
 */
static const Bitboard NOT_A_MASK = Bitboard(0xfefefefefefefefeULL);
/**
 * a Bitboard masking the H rank, e.g. to get a bitboard and ignore
 * the A rank, do calc_result = calc_result & NOT_H_MASK
 */
static const Bitboard NOT_H_MASK = Bitboard(0x7f7f7f7f7f7f7f7fULL);

// implementations of Bitboard:: bit shifts below

inline Bitboard Bitboard::nortOne() {
	return *this << 8;
}

inline Bitboard Bitboard::eastOne() {
	return (*this << 1) & NOT_A_MASK;
}
Exemplo n.º 9
0
int ThreadPool::activeCount() const {
   return Bitboard(activeMask & availableMask).bitCount();
}
Exemplo n.º 10
0
/*
Riporta la scacchiera e le altre strutture dati alla situazione precedente
*/
void unmakemove() {
	MOVE m;
	unsigned char from, to, del;
	char was;
	assert(Name(WHITE,0)==king);
	assert(Name(BLACK,0)==king);
	Ply--;
	N_moves--;
	Change(Side);
	Change(Xside);

	Hash = BHash(N_moves);
	Cste = BCste(N_moves);
	Cstr = tree.history[N_moves].cast.castle_right;
	Enp = tree.history[N_moves].enp;
	tree.fifty = tree.history[N_moves].fifty;
	Material(Side) = tree.history[N_moves].material[Side];
	Material(Xside) = tree.history[N_moves].material[Xside];
	m.mi = tree.history[N_moves].m.mi;
	was = tree.history[N_moves].was;
	from = m.ms.from;
	to = m.ms.to;

	Num_piece(Side, was)++;
	Num_piece(Side, Piece(to))--;

	Piece(from) = Piece(to);
	if (Piece(from)!=was)Piece(from)=was;
	Color(from) = Color(to);
	Plist(from) = Plist(to);
	Position((Color(from)), (Plist(from))) = from;
	Piece(to) = no_piece;
	Color(to) = EMPTY;
	Plist(to) = no_list;
	Bitboard(Side) = BBitb(N_moves, Side);
	Pbitboard(Side) = BPBitb(N_moves, Side);
	Pbitboard(Xside) = BPBitb(N_moves, Xside);
	
	if (m.ms.flag & M_CAP) {
			del = tree.history[N_moves].del;
			Piece(del) = BCapP(N_moves);
			Color(del) = BCapC(N_moves);
			Plist(del) = BCapPos(N_moves);
			Active((Color(del)), (Plist(del))) = FREE;
			Position((Color(del)), (Plist(del))) = del;
			Num_piece(Xside, Piece(del))++;
			Bitboard(Xside) = BBitb(N_moves, Xside);
			assert(Name(Side,0)==king);
			assert(Name(Xside,0)==king);
	}
	assert(Name(Side,0)==king);
	assert(Name(Xside,0)==king);


	if (m.ms.flag & (M_OO | M_OOO)) {
			switch (m.ms.to) {
					case C8:
						from = D8;
						to = A8;
						break;
					case G8:
						from = F8;
						to = H8;
						break;
					case C1:
						from = D1;
						to = A1;
						break;
					case G1:
						from = F1;
						to = H1;
						break;
					default:
						puts("Bad castle request.");
						assert(0);
					}

			Piece(to) = rook;
			Color(to) = Side;
			Plist(to) = Plist(from);
			Position((Color(to)), (Plist(to))) = to;
			Piece(from) = no_piece;
			Color(from) = EMPTY;
			Plist(from) = no_list;
			}
	assert(Name(WHITE,0)==king);
	assert(Name(BLACK,0)==king);
	}
Exemplo n.º 11
0
/*
check_condition() sets tree.check[Side][Ply] if king of side to move is in check
and it sets tree.verify[Ply] if it is in check or under 'x-ray' attack
*/
void check_condition() {
	int c, from, dir, target, tmp_incheck, tmp_xattack, num_pieces, prob_xattack;
	unsigned __int64 all;
	tmp_incheck = 0;
	tmp_xattack = 0;
	target = Position(Side, 0);
	all = Bitboard(BLACK) | Bitboard(WHITE);
	assert(Name(Side,0)==king);
	
	for (c = 0;c < 16;c++) {
			if (Active(Xside, c)) {
				assert(Name(Xside,0)==king);
				if (c>0) assert(Name(Xside,c)!=king);

				/*controlla se il pezzo puo' attaccare*/

					if (Kind(Xside, c)&table_attack[target - Position(Xside, c) + 128]) {
							/*se e' un pezzo no-slide è sotto scacco*/

							if (IsNoSlide(Xside, c)) {
									tmp_incheck++;
									break;
									}
							/*se e' un pezzo slide dobbiamo controllare*/
							if ((all&(bit_ray[Position(Xside, c)][target])) == 0) {
									tmp_incheck++;
									break;
									}

							from = Position(Xside, c);
							dir = direction[target - from + 128];
							num_pieces = 0;
							prob_xattack = 0;
							from += dir;

							while (from != target) {
									if (Piece(from) != no_piece) {
											num_pieces++;

											if (num_pieces == 1 && Color(from) == Side)
												prob_xattack = 1;

											if (num_pieces > 1)
												break;
											}

									from += dir;
									}

							if (num_pieces == 1 && prob_xattack == 1)
								tmp_xattack++;
							}

					}

			}

	switch (Xside) {
			case BLACK:

				if (File(target) != FilaA && IsBPawn(target + UP_L)) {
						tmp_incheck++;
						break;
						}

				if (File(target) != FilaH && IsBPawn(target + UP_R))
					tmp_incheck++;

				break;

			case WHITE:
				if (File(target) != FilaA && IsWPawn(target + DOWN_L)) {
						tmp_incheck++;
						break;
						}

				if (File(target) != FilaH && IsWPawn(target + DOWN_R))
					tmp_incheck++;

				break;

			case EMPTY:
				printf("Bad color board detect in checkcondition(): %d",Xside);
				assert(0);
				break;

			default:
				printf("Bad color board detect in checkcondition(): %d",Xside);
				assert(0);

				break;
			}
	/*E' sotto scacco?*/
	tree.check[Side][Ply] = tmp_incheck;

	/*Nella makemove() dobbiamo verificare la legalita'?*/
	tree.verify[Ply] = tmp_incheck + tmp_xattack;
	}
Exemplo n.º 12
0
Arquivo: data.cpp Projeto: mkd/chess0
// dataInit()
//
// Initialization of global data at program startup.
// This function should be called only once (or else the mirrored data will be 
// mirrored back again!!)
void dataInit()
{
    unsigned char CHARBITSET[8];
    int i, square, rank, file, arank, afile, state, slide, diaga1h8, diaga8h1, attackbit;
    unsigned char state6Bit, state8Bit, attack8Bit;
    Move move;


    board.searchDepth = AI_SEARCH_DEPTH; // default for startup
    board.maxTime = TIME_PER_MOVE * 1000; // default for startup, milliseconds


    // BITSET has only one bit set:
    BITSET[0] = 0x1;
    for (i = 1; i < 64 ; i++)
        BITSET[i] = BITSET[i-1] << 1;


    // BOARDINDEX is used to translate [file][rank] to [square],
    // Note that file is from 1..8 and rank from 1..8 (not starting from 0)
    for (rank = 0 ; rank < 9; rank++)
        for (file = 0 ; file < 9; file++)
            BOARDINDEX[file][rank] = (rank-1) * 8 + file - 1;


    // PIECEVALUES are used in quiesence move ordering only:
    for (i = 0; i < 16 ; i++) PIECEVALUES[i] = 0;
    PIECEVALUES[WHITE_PAWN] = PAWN_VALUE;
    PIECEVALUES[WHITE_KNIGHT] = KNIGHT_VALUE;
    PIECEVALUES[WHITE_BISHOP] = BISHOP_VALUE;
    PIECEVALUES[WHITE_ROOK] = ROOK_VALUE;
    PIECEVALUES[WHITE_QUEEN] = QUEEN_VALUE;
    PIECEVALUES[WHITE_KING] = KING_VALUE;  
    PIECEVALUES[BLACK_PAWN] = PAWN_VALUE;
    PIECEVALUES[BLACK_KNIGHT] = KNIGHT_VALUE;
    PIECEVALUES[BLACK_BISHOP] = BISHOP_VALUE;
    PIECEVALUES[BLACK_ROOK] = ROOK_VALUE;
    PIECEVALUES[BLACK_QUEEN] = QUEEN_VALUE;
    PIECEVALUES[BLACK_KING] = KING_VALUE;


    // initialize MS1BTABLE, used in lastOne (see bitops.cpp)
    for (i = 0; i < 256; i++)
    {
        MS1BTABLE[i] = (
                (i > 127) ? 7 :
                (i >  63) ? 6 :
                (i >  31) ? 5 :
                (i >  15) ? 4 :
                (i >   7) ? 3 :
                (i >   3) ? 2 :
                (i >   1) ? 1 : 0 );
    }


    //  initialize rank, file and diagonal 6-bit masking Bitboards, to get the
    //  occupancy state, used in the movegenerator (see movegen.ccp)
    for (square = 0; square < 64; square++)
    {
        RANKMASK[square] = 0x0;
        FILEMASK[square] = 0x0;
        DIAGA8H1MASK[square] = 0x0;
        DIAGA1H8MASK[square] = 0x0;
        FILEMAGIC[square] = 0x0;
        DIAGA8H1MAGIC[square] = 0x0;
        DIAGA1H8MAGIC[square] = 0x0;
    }


    for (file = 1; file < 9; file++)
    {
        for (rank = 1; rank < 9; rank++)
        {
            // initialize 6-bit rank mask, used in the movegenerator (see movegen.ccp)
            RANKMASK[BOARDINDEX[file][rank]]  = BITSET[BOARDINDEX[2][rank]] | BITSET[BOARDINDEX[3][rank]] | BITSET[BOARDINDEX[4][rank]] ;
            RANKMASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[5][rank]] | BITSET[BOARDINDEX[6][rank]] | BITSET[BOARDINDEX[7][rank]] ;


            // initialize 6-bit file mask, used in the movegenerator (see movegen.ccp)
            FILEMASK[BOARDINDEX[file][rank]]  = BITSET[BOARDINDEX[file][2]] | BITSET[BOARDINDEX[file][3]] | BITSET[BOARDINDEX[file][4]] ;
            FILEMASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[file][5]] | BITSET[BOARDINDEX[file][6]] | BITSET[BOARDINDEX[file][7]] ;


            // initialize diagonal magic multiplication numbers, used in the movegenerator (see movegen.ccp)
            diaga8h1 = file + rank; // from 2 to 16, longest diagonal = 9
            DIAGA8H1MAGIC[BOARDINDEX[file][rank]] = _DIAGA8H1MAGICS[diaga8h1 - 2];


            // initialize 6-bit diagonal mask, used in the movegenerator (see movegen.ccp)
            DIAGA8H1MASK[BOARDINDEX[file][rank]] = 0x0;

            // lower half, diagonals 2 to 9
            if (diaga8h1 < 10)
            {
                for (square = 2 ; square < diaga8h1-1 ; square ++)
                    DIAGA8H1MASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[square][diaga8h1-square]];
            }
            // upper half, diagonals 10 to 16
            else
            {
                for (square = 2 ; square < 17 - diaga8h1 ; square ++)
                    DIAGA8H1MASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[diaga8h1+square-9][9-square]];
            }


            // initialize diagonal magic multiplication numbers, used in the movegenerator (see movegen.ccp)
            diaga1h8 = file - rank; // from -7 to +7, longest diagonal = 0
            DIAGA1H8MAGIC[BOARDINDEX[file][rank]] = _DIAGA1H8MAGICS[diaga1h8+7];


            // initialize 6-bit diagonal mask, used in the movegenerator (see movegen.ccp)
            DIAGA1H8MASK[BOARDINDEX[file][rank]] = 0x0;

            // lower half, diagonals 0 to 7
            if (diaga1h8 > -1)
            {
                for (square = 2 ; square < 8 - diaga1h8 ; square ++)
                {
                    DIAGA1H8MASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[diaga1h8 + square][square]];
                }
            }
            else
            {
                for (square = 2 ; square < 8 + diaga1h8 ; square ++)
                {
                    DIAGA1H8MASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[square][square - diaga1h8]];
                }
            }


            // initialize file magic multiplication numbers, used in the movegenerator (see movegen.ccp)
            FILEMAGIC[BOARDINDEX[file][rank]] = _FILEMAGICS[file-1];

        }
    }


    // Now initialize the GEN_SLIDING_ATTACKS array, used to generate the sliding
    //     attack bitboards.
    //     unsigned char GEN_SLIDING_ATTACKS[8 squares][64 states] holds the attacks
    //     for any file, rank or diagonal - it is going to be usefull when generating the
    //     RANK_ATTACKS[64][64], FILE_ATTACKS[64][64], DIAGA8H1_ATTACKS[64][64] and
    //     DIAGA1H8_ATTACKS[64][64] arrays

    // initialize CHARBITSET, this array is equivalant to BITSET for bitboards:
    // 8 chars, each with only 1 bit set.
    CHARBITSET[0] = 1;
    for (square = 1; square <= 7; square++) 
    {
        CHARBITSET[square] = CHARBITSET[square-1] << 1;
    }


    // loop over rank, file or diagonal squares
    for (square = 0; square <= 7; square++)
    {
        // loop of occupancy states
        // state6Bit represents the 64 possible occupancy states of a rank,
        // except the 2 end-bits, because they don't matter for calculating attacks
        for (state6Bit = 0; state6Bit < 64; state6Bit++)      
        {
            state8Bit = state6Bit << 1; // create an 8-bit occupancy state
            attack8Bit = 0;
            if (square < 7)
            {
                attack8Bit |= CHARBITSET[square + 1];
            }
            slide = square + 2;

            while (slide <= 7) // slide in '+' direction
            {
                if ((~state8Bit) & (CHARBITSET[slide - 1]))
                    attack8Bit |= CHARBITSET[slide];
                else
                    break;

                slide++;
            }

            if (square > 0)
            {
                attack8Bit |= CHARBITSET[square - 1];
            }
            slide = square - 2;

            while (slide >= 0) // slide in '-' direction
            {
                if ((~state8Bit) & (CHARBITSET[slide + 1]))
                    attack8Bit |= CHARBITSET[slide];
                else
                    break;

                slide--;
            }

            GEN_SLIDING_ATTACKS[square][state6Bit] = attack8Bit;
        }
    }


    // initialize all attack Bitboards, used in the movegenerator (see movegen.ccp)
    for (square = 0; square < 64; square++)
    {
        KNIGHT_ATTACKS[square] = 0x0;
        KING_ATTACKS[square] = 0x0;
        WHITE_PAWN_ATTACKS[square] = 0x0;
        WHITE_PAWN_MOVES[square] = 0x0;
        WHITE_PAWN_DOUBLE_MOVES[square] = 0x0;
        BLACK_PAWN_ATTACKS[square] = 0x0;
        BLACK_PAWN_MOVES[square] = 0x0;
        BLACK_PAWN_DOUBLE_MOVES[square] = 0x0;   
        for (state = 0; state < 64; state++)
        {
            RANK_ATTACKS[square][state] = 0x0;
            FILE_ATTACKS[square][state] = 0x0;
            DIAGA8H1_ATTACKS[square][state] = 0x0;
            DIAGA1H8_ATTACKS[square][state] = 0x0;
        }
    }


    // white pawn attacks
    for (square = 0; square < 64; square++)
    {
        file = FILES[square]; rank = RANKS[square];
        afile = file - 1; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            WHITE_PAWN_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            WHITE_PAWN_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];
    }


    // white pawn moves
    for (square = 0; square <64; square++)
    {
        file = FILES[square]; rank = RANKS[square];
        afile = file; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            WHITE_PAWN_MOVES[square] |= BITSET[BOARDINDEX[afile][arank]];       

        if (rank == 2)
        {
            afile = file; arank = rank + 2;
            if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
                WHITE_PAWN_DOUBLE_MOVES[square] |= BITSET[BOARDINDEX[afile][arank]];
        }
    }


    // black pawn attacks
    for (square = 0; square < 64; square++)
    {
        file = FILES[square]; rank = RANKS[square];
        afile = file - 1; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            BLACK_PAWN_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            BLACK_PAWN_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];
    }


    // black pawn moves
    for (square = 0; square < 64; square++)
    {
        file = FILES[square]; rank = RANKS[square];
        afile = file; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            BLACK_PAWN_MOVES[square] |= BITSET[BOARDINDEX[afile][arank]];

        if (rank == 7)
        {
            afile = file; arank = rank - 2;
            if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
                BLACK_PAWN_DOUBLE_MOVES[square] |= BITSET[BOARDINDEX[afile][arank]];
        }
    }


    // knight attacks
    for (square = 0; square < 64; square++)
    {
        file = FILES[square];
        rank = RANKS[square];
        afile = file - 2; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file - 1; arank = rank + 2;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank + 2;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 2; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 2; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank - 2;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file - 1; arank = rank - 2;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file - 2; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KNIGHT_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];
    }


    // king attacks
    for (square = 0; square < 64; square++)
    {
        file = FILES[square]; rank = RANKS[square];
        afile = file - 1; arank = rank;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file - 1; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank + 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file + 1; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];

        afile = file - 1; arank = rank - 1;

        if ((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
            KING_ATTACKS[square] |= BITSET[BOARDINDEX[afile][arank]];
    }


    //  RANK attacks (ROOKS and QUEENS):
    //  use unsigned char GEN_SLIDING_ATTACKS[8 squares][64 states]
    //  to initialize Bitboard RANK_ATTACKS[64 squares][64 states]
    for (square = 0; square < 64; square++)
    {
        for (state6Bit = 0; state6Bit < 64; state6Bit++)
        {
            RANK_ATTACKS[square][state6Bit] = 0;
            RANK_ATTACKS[square][state6Bit] |=
                Bitboard(GEN_SLIDING_ATTACKS[FILES[square]-1][state6Bit]) << (RANKSHIFT[square] - 1);
        }
    }


    //  FILE attacks (ROOKS and QUEENS):
    //  use unsigned char GEN_SLIDING_ATTACKS[8 squares][64 states]
    //  to initialize Bitboard FILE_ATTACKS[64 squares][64 states]
    //
    //  Occupancy transformation is as follows:
    //
    //   occupancy state bits of the file:               occupancy state bits in GEN_SLIDING_ATTACKS:
    //
    //        . . . . . . . . MSB                           LSB         MSB
    //        . . . . . A . .                    =>         A B C D E F . .                            
    //        . . . . . B . .
    //        . . . . . C . .
    //        . . . . . D . .
    //        . . . . . E . .
    //        . . . . . F . .
    //    LSB . . . . . . . .
    //
    //  The reverse transformation is as follows:
    //
    //   attack bits in GEN_SLIDING_ATTACKS:             attack bits in the file:
    //
    //        LSB         MSB                               . . . . . m . . MSB
    //        m n o p q r s t                    =>         . . . . . n . .
    //                                                      . . . . . o . .
    //                                                      . . . . . p . .
    //                                                      . . . . . q . .
    //                                                      . . . . . r . .
    //                                                      . . . . . s . .
    //                                                 LSB  . . . . . t . .
    //
    for (square = 0; square < 64; square++)
    {
        for (state6Bit = 0; state6Bit < 64; state6Bit++)
        {
            FILE_ATTACKS[square][state6Bit] = 0x0;

            // check to see if attackbit'-th  bit is set in GEN_SLIDING_ATTACKS, for this combination of square/occupancy state
            for (attackbit = 0; attackbit < 8; attackbit++) // from LSB to MSB
            {
                //  conversion from 64 board squares to the 8 corresponding positions in the GEN_SLIDING_ATTACKS array: "8-RANKS[square]"
                if (GEN_SLIDING_ATTACKS[8-RANKS[square]][state6Bit] & CHARBITSET[attackbit])
                {
                    // the bit is set, so we need to update FILE_ATTACKS accordingly:
                    // conversion of square/attackbit to the corresponding 64 board FILE: FILES[square]
                    // conversion of square/attackbit to the corresponding 64 board RANK: 8-attackbit
                    file = FILES[square];
                    rank = 8 - attackbit;
                    FILE_ATTACKS[square][state6Bit] |=  BITSET[BOARDINDEX[file][rank]];
                }
            }
        }
    }


    //  DIAGA8H1_ATTACKS attacks (BISHOPS and QUEENS)
    for (square = 0; square < 64; square++)
    {
        for (state6Bit = 0; state6Bit < 64; state6Bit++)
        {
            DIAGA8H1_ATTACKS[square][state6Bit] = 0x0;
            for (attackbit = 0; attackbit < 8; attackbit++) // from LSB to MSB
            {
                //  conversion from 64 board squares to the 8 corresponding positions in the GEN_SLIDING_ATTACKS array: MIN((8-RANKS[square]),(FILES[square]-1))
                if (GEN_SLIDING_ATTACKS[(8-RANKS[square]) < (FILES[square]-1) ? (8-RANKS[square]) : (FILES[square]-1)][state6Bit] & CHARBITSET[attackbit])
                {
                    // the bit is set, so we need to update FILE_ATTACKS accordingly:
                    // conversion of square/attackbit to the corresponding 64 board file and rank:
                    diaga8h1 = FILES[square] + RANKS[square]; // from 2 to 16, longest diagonal = 9
                    if (diaga8h1 < 10)
                    {
                        file = attackbit + 1;
                        rank = diaga8h1 - file;
                    }
                    else
                    {
                        rank = 8 - attackbit;
                        file = diaga8h1 - rank;
                    }
                    if ((file > 0) && (file < 9) && (rank > 0) && (rank < 9))
                    {
                        DIAGA8H1_ATTACKS[square][state6Bit] |=  BITSET[BOARDINDEX[file][rank]];
                    }
                }
            }
        }
    }


    //  DIAGA1H8_ATTACKS attacks (BISHOPS and QUEENS)
    for (square = 0; square < 64; square++)
    {
        for (state6Bit = 0; state6Bit < 64; state6Bit++)
        {
            DIAGA1H8_ATTACKS[square][state6Bit] = 0x0;
            for (attackbit = 0; attackbit < 8; attackbit++) // from LSB to MSB
            {
                //  conversion from 64 board squares to the 8 corresponding positions in the GEN_SLIDING_ATTACKS array: MIN((8-RANKS[square]),(FILES[square]-1))
                if (GEN_SLIDING_ATTACKS[(RANKS[square]-1) < (FILES[square]-1) ? (RANKS[square]-1) : (FILES[square]-1)][state6Bit] & CHARBITSET[attackbit])
                {
                    // the bit is set, so we need to update FILE_ATTACKS accordingly:
                    // conversion of square/attackbit to the corresponding 64 board file and rank:
                    diaga1h8 = FILES[square] - RANKS[square]; // from -7 to 7, longest diagonal = 0
                    if (diaga1h8 < 0)
                    {
                        file = attackbit + 1;
                        rank = file - diaga1h8;
                    }
                    else
                    {
                        rank = attackbit + 1;
                        file = diaga1h8 + rank;
                    }
                    if ((file > 0) && (file < 9) && (rank > 0) && (rank < 9))
                    {
                        DIAGA1H8_ATTACKS[square][state6Bit] |=  BITSET[BOARDINDEX[file][rank]];
                    }
                }
            }
        }
    }


    // Masks for castling, index 0 is for white, 1 is for black
    maskEG[0] = BITSET[E1] | BITSET[F1] | BITSET[G1];
    maskEG[1] = BITSET[E8] | BITSET[F8] | BITSET[G8];

    maskFG[0] = BITSET[F1] | BITSET[G1];
    maskFG[1] = BITSET[F8] | BITSET[G8];

    maskBD[0] = BITSET[B1] | BITSET[C1] | BITSET[D1];
    maskBD[1] = BITSET[B8] | BITSET[C8] | BITSET[D8];

    maskCE[0] = BITSET[C1] | BITSET[D1] | BITSET[E1];
    maskCE[1] = BITSET[C8] | BITSET[D8] | BITSET[E8];


    // the 4 castling moves can be predefined
    move.clear();
    move.setCapture(EMPTY);
    move.setPiece(WHITE_KING);
    move.setPromo(WHITE_KING);
    move.setFrom(E1);
    move.setTosq(G1);
    WHITE_OO_CASTL = move.moveInt;
    move.setTosq(C1);
    WHITE_OOO_CASTL = move.moveInt;

    move.setPiece(BLACK_KING);
    move.setPromo(BLACK_KING);
    move.setFrom(E8);
    move.setTosq(G8);
    BLACK_OO_CASTL = move.moveInt;
    move.setTosq(C8);
    BLACK_OOO_CASTL = move.moveInt;


    // initialize evaluation data & Bitboards
    BLACK_SQUARES = 0;
    for (i = 0; i < 64; i++)
    {
        if ((i + RANKS[i]) % 2) BLACK_SQUARES ^= BITSET[i];
    }
    WHITE_SQUARES = ~BLACK_SQUARES;


    // clear Bitboards
    for (i = 0; i < 64; i++)
    {
        PASSED_WHITE[i] = 0;
        PASSED_BLACK[i] = 0;
        ISOLATED_WHITE[i] = 0;
        ISOLATED_BLACK[i] = 0;
        BACKWARD_WHITE[i] = 0;
        BACKWARD_BLACK[i] = 0;
        KINGSHIELD_STRONG_W[i] = 0;
        KINGSHIELD_STRONG_B[i] = 0;
        KINGSHIELD_WEAK_W[i] = 0;
        KINGSHIELD_WEAK_B[i] = 0;
    }


    for (i = 0; i < 64; i++)
    {
        // passed white
        for (rank = RANKS[i] + 1; rank < 8; rank++)
        {
            // 3 files
            if (FILES[i] - 1 > 0) PASSED_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i] - 1][rank]];
            PASSED_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i]][rank]];
            if (FILES[i] + 1 < 9 ) PASSED_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i] + 1][rank]];
        }

        // isolated white
        for (rank = 2; rank < 8; rank++)
        {
            // 2 files
            if (FILES[i] - 1 > 0) ISOLATED_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i] - 1][rank]];
            if (FILES[i] + 1 < 9 ) ISOLATED_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i] + 1][rank]];
        }

        // backward white
        for (rank = 2; rank <= RANKS[i]; rank++)
        {
            // 2 files
            if (FILES[i] - 1 > 0) BACKWARD_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i] - 1][rank]];
            if (FILES[i] + 1 < 9 ) BACKWARD_WHITE[i] ^= BITSET[BOARDINDEX[FILES[i] + 1][rank]];
        }
    }


    // pawn shield Bitboards for king safety, only if the king is on the first 3 ranks
    for (i = 0; i < 24; i++)
    {
        // KINGSHIELD_STRONG_W & KINGSHIELD_WEAK_W
        KINGSHIELD_STRONG_W[i] ^= BITSET[i + 8];
        KINGSHIELD_WEAK_W[i] ^= BITSET[i + 16];
        if (FILES[i] > 1)
        {
            KINGSHIELD_STRONG_W[i] ^= BITSET[i + 7];
            KINGSHIELD_WEAK_W[i] ^= BITSET[i + 15];
        }
        if (FILES[i] < 8)
        {
            KINGSHIELD_STRONG_W[i] ^= BITSET[i + 9];
            KINGSHIELD_WEAK_W[i] ^= BITSET[i + 17];
        }
        if (FILES[i]== 1)
        {
            KINGSHIELD_STRONG_W[i] ^= BITSET[i + 10];
            KINGSHIELD_WEAK_W[i] ^= BITSET[i + 18];
        }
        if (FILES[i]== 8)
        {
            KINGSHIELD_STRONG_W[i] ^= BITSET[i + 6];
            KINGSHIELD_WEAK_W[i] ^= BITSET[i + 14];
        }
    }


    // DISTANCE array, distance is measured as max of (rank,file)-difference
    for (i = 0 ; i < 64; i++)
    {
        for (square = 0 ; square < 64; square++)
        {
            if (abs(RANKS[i] - RANKS[square]) > abs(FILES[i] - FILES[square]))
                DISTANCE[i][square] = abs(RANKS[i] - RANKS[square]);
            else
                DISTANCE[i][square] = abs(FILES[i] - FILES[square]);
        }
    }


    // Initialize MIRRORed data:
    // Data is supplied as mirrored for WHITE, so it's ready for BLACK to use
    for (square = 0; square < 64; square++)
    {
        PAWNPOS_B[square] = PAWNPOS_W[square];
        KNIGHTPOS_B[square] = KNIGHTPOS_W[square];
        BISHOPPOS_B[square] = BISHOPPOS_W[square];
        ROOKPOS_B[square] = ROOKPOS_W[square];
        QUEENPOS_B[square] = QUEENPOS_W[square];
        KINGPOS_B[square] = KINGPOS_W[square];
        KINGPOS_ENDGAME_B[square] = KINGPOS_ENDGAME_W[square];
    }


    // Complete missing mirrored data
    for (i = 0; i < 64; i++)
    {
        PAWNPOS_W[i] = PAWNPOS_B[MIRROR[i]];
        KNIGHTPOS_W[i] = KNIGHTPOS_B[MIRROR[i]];
        BISHOPPOS_W[i] = BISHOPPOS_B[MIRROR[i]];
        ROOKPOS_W[i] = ROOKPOS_B[MIRROR[i]];
        QUEENPOS_W[i] = QUEENPOS_B[MIRROR[i]];
        KINGPOS_W[i] = KINGPOS_B[MIRROR[i]];
        KINGPOS_ENDGAME_W[i] = KINGPOS_ENDGAME_B[MIRROR[i]];

        for (square = 0; square < 64; square ++)
        {
            // PASSED_BLACK Bitboards (mirror of PASSED_WHITE //  Bitboards)
            if (PASSED_WHITE[i] & BITSET[square]) PASSED_BLACK[MIRROR[i]] |= BITSET[MIRROR[square]];

            // ISOLATED_BLACK Bitboards (mirror of ISOLATED_WHITE
            // Bitboards)
            if (ISOLATED_WHITE[i] & BITSET[square]) ISOLATED_BLACK[MIRROR[i]] |= BITSET[MIRROR[square]];

            //  BACKWARD_BLACK Bitboards (mirror of BACKWARD_WHITE
            //  Bitboards):
            if (BACKWARD_WHITE[i] & BITSET[square]) BACKWARD_BLACK[MIRROR[i]] |= BITSET[MIRROR[square]];

            //  KINGSHIELD_STRONG_B Bitboards (mirror of KINGSHIELD_STRONG_W Bitboards):
            if (KINGSHIELD_STRONG_W[i] & BITSET[square]) KINGSHIELD_STRONG_B[MIRROR[i]] |= BITSET[MIRROR[square]];

            //  KINGSHIELD_WEAK_B Bitboards (mirror of KINGSHIELD_WEAK_W Bitboards):
            if (KINGSHIELD_WEAK_W[i] & BITSET[square]) KINGSHIELD_WEAK_B[MIRROR[i]] |= BITSET[MIRROR[square]];
        }
    }

    NOMOVE.moveInt = 0;
    KEY.init();


    //  HEADINGS and RAYS, used in SEE
    for (i = 0 ; i < 64; i++)
    {
        RAY_W[i]  = 0;
        RAY_NW[i] = 0;
        RAY_N[i]  = 0;
        RAY_NE[i] = 0;
        RAY_E[i]  = 0;
        RAY_SE[i] = 0;
        RAY_S[i]  = 0;
        RAY_SW[i] = 0;
        for (square = 0 ; square < 64; square ++)
        {
            HEADINGS[i][square] = 0;
        }
    }


    for (rank = 1 ; rank < 9; rank++)
        for (file = 1 ; file < 9; file++)
        {
            i = BOARDINDEX[file][rank];         

            // WEST:
            for (afile = file - 1 ; afile > 0; afile--)
            {
                HEADINGS[i][BOARDINDEX[afile][rank]] = WEST;
                RAY_W[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[afile][rank]];
            }

            // NORTHWEST:
            for (afile = file - 1, arank = rank + 1 ; (afile > 0) && (arank < 9); afile--,  arank++) 
            {
                HEADINGS[i][BOARDINDEX[afile][arank]] = NORTHWEST;
                RAY_NW[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[afile][arank]];
            }

            // NORTH:
            for (arank = rank + 1 ; arank < 9; arank++) 
            {
                HEADINGS[i][BOARDINDEX[file][arank]] = NORTH;
                RAY_N[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[file][arank]];
            }

            // NORTHEAST:
            for (afile = file + 1, arank = rank + 1 ; (afile < 9) && (arank < 9); afile++,  arank++) 
            {
                HEADINGS[i][BOARDINDEX[afile][arank]] = NORTHEAST;
                RAY_NE[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[afile][arank]];
            }

            // EAST:
            for (afile = file + 1 ; afile < 9; afile++) 
            {
                HEADINGS[i][BOARDINDEX[afile][rank]] = EAST;
                RAY_E[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[afile][rank]];
            }

            // SOUTHEAST:
            for (afile = file + 1, arank = rank - 1 ; (afile < 9) && (arank > 0); afile++,  arank--) 
            {
                HEADINGS[i][BOARDINDEX[afile][arank]] = SOUTHEAST;
                RAY_SE[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[afile][arank]];
            }

            // SOUTH:
            for (arank = rank - 1 ; arank > 0; arank--) 
            {
                HEADINGS[i][BOARDINDEX[file][arank]] = SOUTH;
                RAY_S[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[file][arank]];
            }

            // SOUTHWEST:
            for (afile = file - 1, arank = rank - 1 ; (afile > 0) && (arank > 0); afile--,  arank--) 
            {
                HEADINGS[i][BOARDINDEX[afile][arank]] = SOUTHWEST;
                RAY_SW[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[afile][arank]];
            }
        }


    // required for running test suites, to prevent 
    // writing escape characters to a file
    TO_CONSOLE = 1;

    // Winboard parameters:
    XB_NONE = 2;  // not 0 or 1
    XB_ANALYZE = 3;   // not 0, 1, or 2
    XB_MODE = false;
    XB_POST = true;
    XB_PONDER = false;
    XB_DO_PENDING = false;
    XB_NO_TIME_LIMIT = false;
}
Exemplo n.º 13
0
/*verifica che la mossa è una mossa possibile*/
int verify_move(const MOVE m) {
	unsigned __int64 all;
	all = Bitboard(BLACK) | Bitboard(WHITE);

	if (Color(m.ms.from) != Side)
		return 0;
	if (Piece(m.ms.to) == king)
		return 0;
	if (Piece(m.ms.from) == out_board || Piece(m.ms.from) == no_piece)
		return 0;

	switch (Piece(m.ms.from)) {
			case no_piece:
				return 0;
			case wpawn:
				if (m.ms.piece != wpawn && ((m.ms.flag & M_PRO)==0))
					return 0;
				if (Plist(m.ms.from)==0)
					return 0;
				if (Active(Side,Plist(m.ms.from))==CAPTURED)
					return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from)
					return 0;

				if (m.ms.flag & M_PAW) {
						if (m.ms.flag & M_CAP) {
								if (m.ms.flag & M_ENP) {
										if (Piece(m.ms.to + DOWN) != bpawn)
											return 0;
										if (Active(Xside,Plist(m.ms.to + DOWN))==CAPTURED)
											return 0;
										if (Position(Xside,Plist(m.ms.to + DOWN))!=(m.ms.to + DOWN))
											return 0;
										if (Rank(m.ms.from) != Riga5)
											return 0;
										return 1;
										}
								if (Plist(m.ms.to)==0) return 0;
								if (Active(Xside,Plist(m.ms.to))==CAPTURED) return 0;
								if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;

								if (Color(m.ms.to) != Xside)
									return 0;

								if (Piece(m.ms.to) == king)
									return 0;

								if (m.ms.to == m.ms.from + UP_R || m.ms.to == m.ms.from + UP_L)
									return 1;

								if (m.ms.flag & M_PRO && Rank(m.ms.from) != Riga7)
									return 0;

								return 1;
								}

						if (Color(m.ms.to) != EMPTY)
							return 0;

						if (m.ms.flag & M_DBP) {
								if (Rank(m.ms.from) != Riga2)
									return 0;

								if (Color(m.ms.to + DOWN) != EMPTY)
									return 0;

								return 1;
								}

						if (m.ms.to == m.ms.from + UP)
							return 1;

						return 0;
						}

				return 0;
			case bpawn:

				if (m.ms.piece != bpawn && ((m.ms.flag & M_PRO)==0))
					return 0;
				if (Plist(m.ms.from)==0) return 0;

				if (Active(Side,Plist(m.ms.from))==0) return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from) return 0;

				if (m.ms.flag & M_PAW) {
						if (m.ms.flag & M_CAP) {
								if (m.ms.flag & M_ENP) {
										if (Piece(m.ms.to + UP) != wpawn)
											return 0;
										if (Active(Xside,Plist(m.ms.to + UP))==CAPTURED)
											return 0;
										if (Position(Xside,Plist(m.ms.to + UP))!=(m.ms.to + UP))
											return 0;

										if (Rank(m.ms.from) != Riga4)
											return 0;

										return 1;
										}

								if (Plist(m.ms.to)==0) return 0;
								if (Active(Xside,Plist(m.ms.to))==0) return 0;
								if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;


								if (Color(m.ms.to) != Xside)
									return 0;

								if (Piece(m.ms.to) == king)
									return 0;

								if (m.ms.to == m.ms.from + DOWN_R || m.ms.to == m.ms.from + DOWN_L)
									return 1;

								if (m.ms.flag & M_PRO && Rank(m.ms.from) != Riga2)
									return 0;

								return 1;
								}

						if (Color(m.ms.to) != EMPTY)
							return 0;

						if (m.ms.flag & M_DBP) {
								if (Rank(m.ms.from) != Riga7)
									return 0;

								if (Color(m.ms.to + UP) != EMPTY)
									return 0;

								return 1;
								}

						if (m.ms.to == m.ms.from + DOWN)
							return 1;

						return 0;
						}

				return 0;
			case knight:
				if (m.ms.piece != knight)
					return 0;

				if (Plist(m.ms.from)==0)
					return 0;
				if (Active(Side,Plist(m.ms.from))==0) 
					return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from) 
					return 0;
				if ((m.ms.flag == M_STD) && Color(m.ms.to) != EMPTY)
					return 0;
				if ((m.ms.flag & M_CAP) && Color(m.ms.to) != Xside)
					return 0;
				if ((m.ms.flag & M_CAP) && Piece(m.ms.to) == king)
					return 0;

				if (m.ms.flag & M_CAP) {
					if (Plist(m.ms.to)==0) return 0;
					if (Active(Xside,Plist(m.ms.to))==0) return 0;
					if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;
					}


				if (bitn&table_attack[m.ms.to - m.ms.from + 128])
					return 1;

				return 0;

			case bishop:
				if (m.ms.piece != bishop)
					return 0;

				if (Plist(m.ms.from)==0) return 0;
				if (Active(Side,Plist(m.ms.from))==0) return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from) return 0;

				if ((m.ms.flag == M_STD) && Color(m.ms.to) != EMPTY)
					return 0;

				if (m.ms.flag & M_CAP && Color(m.ms.to) != Xside)
					return 0;
				if ((m.ms.flag & M_CAP) && Piece(m.ms.to) == king)
									return 0;
				if (m.ms.flag & M_CAP) {
					if (Plist(m.ms.to)==0) return 0;
					if (Active(Xside,Plist(m.ms.to))==0) return 0;
					if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;
					}

				if (bitb&table_attack[m.ms.to - m.ms.from + 128]) {
						if ((all&(bit_ray[m.ms.from][m.ms.to])) == 0)
							return 1;
						}

				return 0;
			case rook:

				if (m.ms.piece != rook)
					return 0;

				if (Plist(m.ms.from)==0) return 0;
				if (Active(Side,Plist(m.ms.from))==0) return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from) return 0;

				if ((m.ms.flag == M_STD) && Color(m.ms.to) != EMPTY)
					return 0;

				if ((m.ms.flag & M_CAP) && Color(m.ms.to) != Xside)
					return 0;
				if ((m.ms.flag & M_CAP) && Piece(m.ms.to) == king)
									return 0;
				if (m.ms.flag & M_CAP) {
					if (Plist(m.ms.to)==0) return 0;
					if (Active(Xside,Plist(m.ms.to))==0) return 0;
					if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;
					}

				if (bitr&table_attack[m.ms.to - m.ms.from + 128]) {
						if ((all&(bit_ray[m.ms.from][m.ms.to])) == 0)
							return 1;
						}

				return 0;
			case queen:

				if (m.ms.piece != queen)
					return 0;

				if (Plist(m.ms.from)==0) return 0;
				if (Active(Side,Plist(m.ms.from))==0) return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from) return 0;

				if ((m.ms.flag == M_STD) && Color(m.ms.to) != EMPTY)
					return 0;

				if ((m.ms.flag & M_CAP) && Color(m.ms.to) != Xside)
					return 0;

				if ((m.ms.flag & M_CAP) && Piece(m.ms.to) == king)
									return 0;
				if (m.ms.flag & M_CAP) {
					if (Plist(m.ms.to)==0) return 0;
					if (Active(Xside,Plist(m.ms.to))==0) return 0;
					if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;
					}

				if (bitq&table_attack[m.ms.to - m.ms.from + 128]) {
						if ((all&(bit_ray[m.ms.from][m.ms.to])) == 0)
							return 1;
						}

				return 0;
			case king:

				if (m.ms.piece != king)
					return 0;

				if (Plist(m.ms.from)!=0) return 0;
				if (Active(Side,Plist(m.ms.from))==0) return 0;
				if (Position(Side,Plist(m.ms.from))!=m.ms.from) return 0;

				if (m.ms.flag & M_KNG) {
						if (m.ms.flag & M_CAP) {
							
								if (Plist(m.ms.to)==0) return 0;
								if (Active(Xside,Plist(m.ms.to))==0) return 0;
								if (Position(Xside,Plist(m.ms.to))!=m.ms.to) return 0;
					
								if (Color(m.ms.to) != Xside)
									return 0;
								if (Piece(m.ms.to) == king)
									return 0;
								}

						else if (Color(m.ms.to) != EMPTY)
							return 0;

						if (bitk&table_attack[m.ms.to - m.ms.from + 128])
							return 1;

						return 0;
						}

				if (Side == BLACK) {
						if ((m.ms.flag&M_OO) && (Cstr&cas_boo) && IsEmpty(F8) && IsEmpty(G8))
							return 1;

						if ((m.ms.flag&M_OOO) && (Cstr&cas_booo) && IsEmpty(B8) && IsEmpty(C8) && IsEmpty(D8))
							return 1;
						}

				else {
						if ((m.ms.flag&M_OO) && (Cstr&cas_woo) && IsEmpty(F1) && IsEmpty(G1))
							return 1;

						if ((m.ms.flag&M_OOO) && (Cstr&cas_wooo) && IsEmpty(B1) && IsEmpty(C1) && IsEmpty(D1))
							return 1;
						}

				return 0;
			default:
				puts("Unexpected piece name.");
				assert(0);
			}

	return 0;
	}
Exemplo n.º 14
0
/**
 * @return the Bitboard a, bitwise XOR with Bitboard b
 */
inline Bitboard operator^(Bitboard a,Bitboard b) {
	return Bitboard(a.bits ^ b.bits);
}
Exemplo n.º 15
0
#include "common.hpp"
#include "bitboard.hpp"

const Bitboard SetMaskBB[SquareNum] = {
  Bitboard(UINT64_C(1) << 0,                 0),  // 0 , I9
  Bitboard(UINT64_C(1) << 1,                 0),  // 1 , I8
  Bitboard(UINT64_C(1) << 2,                 0),  // 2 , I7
  Bitboard(UINT64_C(1) << 3,                 0),  // 3 , I6
  Bitboard(UINT64_C(1) << 4,                 0),  // 4 , I5
  Bitboard(UINT64_C(1) << 5,                 0),  // 5 , I4
  Bitboard(UINT64_C(1) << 6,                 0),  // 6 , I3
  Bitboard(UINT64_C(1) << 7,                 0),  // 7 , I2
  Bitboard(UINT64_C(1) << 8,                 0),  // 8 , I1
  Bitboard(UINT64_C(1) << 9,                 0),  // 9 , H9
  Bitboard(UINT64_C(1) << 10,                 0),  // 10, H8
  Bitboard(UINT64_C(1) << 11,                 0),  // 11, H7
  Bitboard(UINT64_C(1) << 12,                 0),  // 12, H6
  Bitboard(UINT64_C(1) << 13,                 0),  // 13, H5
  Bitboard(UINT64_C(1) << 14,                 0),  // 14, H4
  Bitboard(UINT64_C(1) << 15,                 0),  // 15, H3
  Bitboard(UINT64_C(1) << 16,                 0),  // 16, H2
  Bitboard(UINT64_C(1) << 17,                 0),  // 17, H1
  Bitboard(UINT64_C(1) << 18,                 0),  // 18, G9
  Bitboard(UINT64_C(1) << 19,                 0),  // 19, G8
  Bitboard(UINT64_C(1) << 20,                 0),  // 20, G7
  Bitboard(UINT64_C(1) << 21,                 0),  // 21, G6
  Bitboard(UINT64_C(1) << 22,                 0),  // 22, G5
  Bitboard(UINT64_C(1) << 23,                 0),  // 23, G4
  Bitboard(UINT64_C(1) << 24,                 0),  // 24, G3
  Bitboard(UINT64_C(1) << 25,                 0),  // 25, G2
  Bitboard(UINT64_C(1) << 26,                 0),  // 26, G1
Exemplo n.º 16
0
#pragma once
#include "bitboard.h"
const Bitboard Bitboard::LINE_MASK[8] =
{
	Bitboard(0xffffULL << 0, 0),
	Bitboard(0xffffULL << 16, 0),
	Bitboard(0xffffULL << 32, 0),
	Bitboard(0xffffULL << 48, 0),
	Bitboard(0, 0xffffULL << 0),
	Bitboard(0, 0xffffULL << 16),
	Bitboard(0, 0xffffULL << 32),
	Bitboard(0, 0xffffULL << 48),

};
const Bitboard Bitboard::BB_MASK[SQUARE_MAX] =
{
	Bitboard(1ULL << 0, 0),
	Bitboard(1ULL << 1, 0),
	Bitboard(1ULL << 2, 0),
	Bitboard(1ULL << 3, 0),
	Bitboard(1ULL << 4, 0),
	Bitboard(1ULL << 5, 0),
	Bitboard(1ULL << 6, 0),
	Bitboard(1ULL << 7, 0),
	Bitboard(1ULL << 8, 0),
	Bitboard(1ULL << 9, 0),
	Bitboard(1ULL << 10, 0),
	Bitboard(1ULL << 11, 0),
	Bitboard(1ULL << 12, 0),
	Bitboard(1ULL << 13, 0),
	Bitboard(1ULL << 14, 0),
Exemplo n.º 17
0
/*
Aggiorna la scacchiera e le altre strutture dati eseguendo la mossa
La verifica di legalita' viene effettuata quando:
-la mossa è una mossa di re
-il re è sotto scacco
-il re è sotto attacco x-ray
*/
int makemove(const MOVE m, const unsigned char s) {

	unsigned char from=0; /*da dove parte il pezzo*/
	unsigned char to=0; /*dove copiare il pezzo*/
	char was=0; /*cosa era il pezzo?*/
	char wh=0;
	unsigned char del=0; /*dove cancellare*/

	assert(Name(WHITE,0)==king);
	assert(Name(BLACK,0)==king);

	

	if (Piece(m.ms.to)==king) return 0;

	/*copia la chiave hash per l'unmake()*/
	BHash(N_moves) = Hash;

	/*copia la castle_exe per l'unmake()*/
	BCste(N_moves) = Cste;

	/*copia la bitboard per l'unmake()*/
	BBitb(N_moves, Side) = Bitboard(Side);


	/*Controlla che l'arrocco sia legale e sposta la torre
*/
	if (m.ms.flag & (M_OO | M_OOO)) {
			if (tree.check[Side][Ply])
				return 0;

			switch (m.ms.to) {
					case C8:

						if (attacked(C8, WHITE) || attacked(D8, WHITE))
							return 0;
						from = A8;
						to = D8;
						Cste |= cas_booo;
						break;

					case G8:
						if (attacked(F8, WHITE) || attacked(G8, WHITE))
							return 0;
						from = H8;
						to = F8;
						Cste |= cas_boo;
						break;

					case C1:
						if (attacked(C1, BLACK) || attacked(D1, BLACK))
							return 0;
						from = A1;
						to = D1;
						Cste |= cas_wooo;
						break;

					case G1:
						if (attacked(F1, BLACK) || attacked(G1, BLACK))
							return 0;
						from = H1;
						to = F1;
						Cste |= cas_woo;
						break;

					default:
						puts("Bad castle request.");
						assert(0);
					}
			/*sposta torre aggiornando la chiave hash*/
			UpdateHash(from);

			Piece(to) = Piece(from);

			Color(to) = Color(from);

			Plist(to) = Plist(from);

			Position((Color(to)), (Plist(to))) = to;

			Piece(from) = no_piece;

			Color(from) = EMPTY;

			Plist(from) = no_list;

			UpdateHash(to);

			SetBB(Side, to);

			DelBB(Side, from);
			}
	/*sposta il pezzo*/
	from = m.ms.from;

	to = m.ms.to;

	was = Piece(from);

	wh = Plist(from);
	assert(was>=0);
	assert(was<=king);

	assert(Name(Side,0)==king);
	assert(Name(Xside,0)==king);
	if (wh>0){
		assert(Name(Side,wh)!=king);
	}

	

	/*Se la mossa e' una cattura cancella il pezzo dalla casella di arrivo*/
	if (m.ms.flag & M_CAP) {
			del = to;

			/*se è una cattura en passant aggiustiamo casella*/
			if (m.ms.flag & M_ENP) {
					if (Side)
						del += DOWN;
					else
						del += UP;
			}

			

			BCapP(N_moves) = Piece(del);
			BCapPos(N_moves) = Plist(del);
			BCapC(N_moves) = Xside;
			BBitb(N_moves, Xside) = Bitboard(Xside);
			Active(Xside, (Plist(del))) = CAPTURED;
			Piece(del) = no_piece;
			Color(del) = EMPTY;
			Plist(del) = no_list;
			DelBB(Xside, del);
			}

	Piece(to) = Piece(from);
	if (m.ms.piece!=was)Piece(to)=m.ms.piece;
	Color(to) = Side;
	Plist(to) = wh;
	Position((Side), (wh)) = to;
	Piece(from) = no_piece;
	Color(from) = EMPTY;
	Plist(from) = no_list;
	SetBB(Side, to);
	DelBB(Side, from);
	/*effettuato il minimo indispensabile verifica, se opportuno, la legalità della mossa*/
	
	assert(Name(Side,0)==king);
	assert(Name(Xside,0)==king);
	if (wh>0){
		assert(Name(Side,wh)!=king);
	}
	

	if ( tree.verify[Ply] || tree.check[Side][Ply] || (m.ms.flag & M_KNG) ||(m.ms.flag & M_ENP)) {
			if (in_check(Side)) {
					/*unmake() locale*/
					Piece(from) = Piece(to);
					if (Piece(from)!=was)Piece(from)=was;
					Color(from) = Side;
					Plist(from) = wh;
					Position((Side), (wh)) = from;
					Piece(to) = no_piece;
					Color(to) = EMPTY;
					Plist(to) = no_list;
					Bitboard(Side) = BBitb(N_moves, Side);

					if (m.ms.flag & M_CAP) {
							Piece(del) = BCapP(N_moves);
							Color(del) = BCapC(N_moves);
							Plist(del) = BCapPos(N_moves);
							Active((Xside), (Plist(del))) = FREE;
							Position((Xside), (Plist(del))) = del;
							Bitboard(Xside) = BBitb(N_moves, Xside);
							assert(Name(Side,0)==king);
							assert(Name(Xside,0)==king);
							if (Plist(del)>0){
								assert(Name(Xside,Plist(del))!=king);
								}
							}
					assert(Name(Side,0)==king);
					assert(Name(Xside,0)==king);
					if (wh>0){
						assert(Name(Side,wh)!=king);
						}
					return 0;
					}

			}
	/*Selectivity*/
	if (s && ((!in_check(Xside)) || ((m.ms.flag& M_CAP)==0))) {
		/*unmake() locale*/
					Piece(from) = Piece(to);
					if (Piece(from)!=was)Piece(from)=was;
					Color(from) = Side;
					Plist(from) = wh;
					Position((Side), (wh)) = from;
					Piece(to) = no_piece;
					Color(to) = EMPTY;
					Plist(to) = no_list;
					Bitboard(Side) = BBitb(N_moves, Side);

					if (m.ms.flag & M_CAP) {
							Piece(del) = BCapP(N_moves);
							Color(del) = BCapC(N_moves);
							Plist(del) = BCapPos(N_moves);
							Active((Xside), (Plist(del))) = FREE;
							Position((Xside), (Plist(del))) = del;
							Bitboard(Xside) = BBitb(N_moves, Xside);
							assert(Name(Side,0)==king);
							assert(Name(Xside,0)==king);
							if (Plist(del)>0){
								assert(Name(Xside,Plist(del))!=king);
								}
							}
					assert(Name(Side,0)==king);
					assert(Name(Xside,0)==king);
					if (wh>0){
						assert(Name(Side,wh)!=king);
						}
					return 0;
		}
	/*back up per l'unmakemove()
	i dati per la cattura e la hash della posizione sono gia' memorizzati*/
	tree.history[N_moves].m.mi = m.mi;
	tree.history[N_moves].cast.castle_right = Cstr;
	tree.history[N_moves].enp = Enp;
	tree.history[N_moves].fifty = tree.fifty;
	tree.history[N_moves].was = was;
	tree.history[N_moves].material[Side] = Material(Side);
	tree.history[N_moves].material[Xside] = Material(Xside);
	BPBitb(N_moves, Side) = Pbitboard(Side);
	BPBitb(N_moves, Xside) = Pbitboard(Xside);

	/*aggiorna diritti arrocco*/
	UpdateHashCastle(Cstr);
	Cstr &= castle_mask[b256to64[from]] & castle_mask[b256to64[to]];
	UpdateHashCastle(Cstr);

	Hash ^= zobrist_enp[b256to64[Enp]];
	Enp = 0;
	tree.fifty++;
	/*se irreversibile...*/

	if (m.ms.flag&(M_PAW | M_CAP)) {
			tree.fifty = 0;
			

			if (m.ms.flag&M_DBP) {
					if (Side)
						Enp = to + DOWN;
					else
						Enp = to + UP;
					}

			if (m.ms.flag&M_PAW) {
					DelPBB(Side, from);

					if ((m.ms.flag&M_PRO) == 0)
						SetPBB(Side, to);
					}

			if (m.ms.flag&M_CAP) {
					tree.history[N_moves].del = del;
					Hash ^= zobrist[Xside][BCapP(N_moves)][b256to64[del]];
					Material(Xside) -= piece_value[BCapP(N_moves)];
					Num_piece(Xside, BCapP(N_moves))--;
					Pbitboard(Xside) &= (~(bit_square[del]));
					}

			Material(Side) -= piece_value[was];
			Material(Side) += piece_value[m.ms.piece];
			Num_piece(Side, was)--;
			Num_piece(Side, m.ms.piece)++;
			}

	Hash ^= zobrist_enp[b256to64[Enp]];

	Hash ^= zobrist[Side][was][b256to64[from]];
	Hash ^= zobrist[Side][m.ms.piece][b256to64[to]];
	Hash ^= zobrist_side;



	Ply++;
	N_moves++;

	Change(Side);
	Change(Xside);

	assert(Name(WHITE,0)==king);
	assert(Name(BLACK,0)==king);

	return 1;

	}