Example #1
0
BOOL test_bittwiddles()
{
	BOOL ok = true;

	ok &= SQUARECOLOR(A1) == BLACK;
	ok &= SQUARECOLOR(H1) == WHITE;
	ok &= SQUARECOLOR(A2) == WHITE;
	ok &= SQUARECOLOR(E4) == WHITE;

	return ok;
}
Example #2
0
bool Evaluation::isDraw(ChessBoard& cb)
{
	int wp, bp;
	// No insufficient material if there are rooks, queens or pawns on the board
	if (queenlist[WHITE].size || queenlist[BLACK].size || rooklist[WHITE].size || rooklist[BLACK].size || pawnlist[WHITE].size || pawnlist[BLACK].size)
		return false;

	wp = knightlist[WHITE].size + bishoplist[WHITE].size;
	bp = knightlist[BLACK].size + bishoplist[BLACK].size;

	// King alone or only one piece is draw
	if ((wp + bp) < 2)
		return true;
	
	// All bishops of same color
	if (!knightlist[WHITE].size && !knightlist[BLACK].size)
	{
		typeColor w = 0, b = 0;
		typeSquare sq = 0;
		for (typeColor c = 0; c < 2; c++)
		{
			while (sq < bishoplist[WHITE].size)
			{
				if (SQUARECOLOR(bishoplist[WHITE].square[sq]) == WHITE)
					++w;
				else
					++b;
				++sq;
			}
		}
		if (!w || !b)
			return true;
	}

	// Only knights are draws.
	if (!bishoplist[WHITE].size && !bishoplist[BLACK].size)
		return true;

	// One bishop or knight on each side draws
	if (((knightlist[WHITE].size + bishoplist[WHITE].size)<2) &&
		((knightlist[BLACK].size + bishoplist[BLACK].size)<2))
		return true;

	// Two knight against bishop or knight can not win
	if ((wp == 2) && (bp == 1))
		if (knightlist[WHITE].size == 2)
			return true;
	if ((wp == 1) && (bp == 2))
		if (knightlist[BLACK].size == 2)
			return true;

	return false;
}
Example #3
0
inline void calc_piece_value(struct t_board *board, struct t_chess_eval *eval) {

    t_chess_color color, opponent;
    t_chess_square square;
    t_chess_piece piece;
    t_chess_piece piece_type;
    t_bitboard b;
    t_bitboard attack_squares;
    t_bitboard moves;
    int move_count;
    struct t_pawn_hash_record *pawn_record = eval->pawn_evaluation;

    for (color = WHITE; color <= BLACK; color++) {

        t_chess_value middlegame = 0;
        t_chess_value endgame = 0;

        opponent = OPPONENT(color);

        //=========================================================
        //-- Rooks first
        //=========================================================
        piece = PIECEINDEX(color, ROOK);
        eval->attacklist[piece] = 0;
        b = board->piecelist[piece];

        //-- Remove Rook and Queens (so we can easily evaluate rams)
        t_bitboard _all_pieces = board->all_pieces ^ board->pieces[color][QUEEN] ^ b;
        t_bitboard _not_occupied = ~(board->occupied[color] & _all_pieces);

        //-- Rooks on the 7th
        if ((b & rank_mask[color][6]) && (board->pieces[opponent][KING] & rank_mask[color][7])) {
            middlegame += MG_ROOK_ON_7TH;
            endgame += MG_ROOK_ON_7TH;
        }

        //-- Rooks on Open file
        if (b & pawn_record->open_file) {
			middlegame += popcount(b & pawn_record->open_file) * pawn_record->pawn_count[color] * MG_ROOK_ON_OPEN_FILE;
        }

        //-- Rooks on Semi-Open file
        if (b & pawn_record->semi_open_file[color]) {
			middlegame += popcount(b & pawn_record->semi_open_file[color]) * pawn_record->pawn_count[color] * MG_ROOK_ON_SEMI_OPEN_FILE;
        }

        //-- Loop around for all pieces
        while (b) {

            //-- Find the square it resides
            square = bitscan_reset(&b);

            //-- Generate moves
            moves = rook_magic_moves[square][((rook_magic[square].mask & _all_pieces) * rook_magic[square].magic) >> 52];
            eval->attacks[color][ROOK] |= moves;
            moves &= _not_occupied;

            //-- Mobility (along ranks)
            move_count = popcount(moves & square_rank_mask[square]);
            middlegame += horizontal_rook_mobility[MIDDLEGAME][move_count];
            endgame += horizontal_rook_mobility[ENDGAME][move_count];

            //-- Mobility (along files)
            move_count = popcount(moves & square_column_mask[square]);
            middlegame += vertical_rook_mobility[MIDDLEGAME][move_count];
            endgame += vertical_rook_mobility[ENDGAME][move_count];

            //-- King safety
            if (attack_squares = (moves & eval->king_zone[opponent])) {
                eval->king_attack_count[opponent]++;
                eval->king_attack_pressure[opponent] += popcount(attack_squares) * 40;
            }
			assert(eval->king_zone[opponent] != 0);

            // piece-square tables
            middlegame += piece_square_table[piece][MIDDLEGAME][square];
            endgame += piece_square_table[piece][ENDGAME][square];

        }

        //=========================================================
        //-- Queens
        //=========================================================
        piece = PIECEINDEX(color, QUEEN);
        eval->attacklist[piece] = 0;
        b = board->piecelist[piece];

        _all_pieces ^= board->pieces[color][BISHOP];
        _not_occupied = ~(board->occupied[color] & _all_pieces);

        while (b) {

            //-- Find the square it resides
            square = bitscan_reset(&b);

            //-- Rook-like Moves
            t_bitboard rook_moves = rook_magic_moves[square][((rook_magic[square].mask & _all_pieces) * rook_magic[square].magic) >> 52];
            eval->attacklist[piece] |= rook_moves;
			rook_moves &= _not_occupied;

            //-- Bishop-like moves
            t_bitboard bishop_moves = bishop_magic_moves[square][((bishop_magic[square].mask & _all_pieces) * bishop_magic[square].magic) >> 55];
            eval->attacklist[piece] |= bishop_moves;
			bishop_moves &= _not_occupied;

            //-- Mobility
            move_count = popcount((rook_moves & square_column_mask[square]) | bishop_moves);
			middlegame += move_count;

            //-- King safety
            if (attack_squares = ((rook_moves | bishop_moves) & eval->king_zone[opponent])) {
                eval->king_attack_count[opponent]++;
                eval->king_attack_pressure[opponent] += 80 * popcount(attack_squares);
            }

            //-- piece-square tables
            middlegame += piece_square_table[piece][MIDDLEGAME][square];
            endgame += piece_square_table[piece][ENDGAME][square];
        }

        //-- Interaction of double pawns & major pieces
        if (pawn_record->double_pawns[color]) {

            int double_pawn_count = popcount(pawn_record->double_pawns[color]);
            int major_piece_count = popcount(board->pieces[color][ROOK] | board->pieces[color][QUEEN]);

            switch (major_piece_count) {
            case 0:
                break;
            case 1:
                middlegame += (double_pawn_count * 12) - pawn_record->semi_open_double_pawns[color] * 30;
                endgame += (double_pawn_count * 12) - pawn_record->semi_open_double_pawns[color] * 25;
                break;
            case 2:
                middlegame += (double_pawn_count * 24) - pawn_record->semi_open_double_pawns[color] * 35;
                endgame += (double_pawn_count * 24) - pawn_record->semi_open_double_pawns[color] * 30;
                break;
            case 3:
                middlegame += (double_pawn_count * 30) - pawn_record->semi_open_double_pawns[color] * 40;
                endgame += (double_pawn_count * 30) - pawn_record->semi_open_double_pawns[color] * 35;
                break;
            case 4:
                middlegame += (double_pawn_count * 30) - pawn_record->semi_open_double_pawns[color] * 40;
                endgame += (double_pawn_count * 30) - pawn_record->semi_open_double_pawns[color] * 35;
                break;
            case 5:
                middlegame += (double_pawn_count * 30) - pawn_record->semi_open_double_pawns[color] * 40;
                endgame += (double_pawn_count * 30) - pawn_record->semi_open_double_pawns[color] * 35;
                break;
            }
        }

        //=========================================================
        //-- Bishops
        //=========================================================
        piece = PIECEINDEX(color, BISHOP);
        eval->attacklist[piece] = 0;
        b = board->piecelist[piece];

        //-- Bishop pair bonus
        if (b & (b - 1)) {
            middlegame += MG_BISHOP_PAIR;
            endgame += EG_BISHOP_PAIR;
        }

        //-- Remove Own Pieces (leave pawns)
		_all_pieces = board->all_pieces ^ board->pieces[color][KNIGHT] ^ board->pieces[color][QUEEN];
		_not_occupied = ~(board->occupied[color] & _all_pieces);

        while (b) {
            //-- Find the square it resides
            square = bitscan_reset(&b);

            //-- Generate moves
            moves = bishop_magic_moves[square][((bishop_magic[square].mask & _all_pieces) * bishop_magic[square].magic) >> 55];
            eval->attacklist[piece] |= moves;

			moves &= _not_occupied;

            //-- Mobility
            move_count = popcount(moves);
            middlegame += bishop_mobility[MIDDLEGAME][move_count];
            endgame += bishop_mobility[ENDGAME][move_count];

            //-- Trapped
            //middlegame -= trapped_bishop[MIDDLEGAME][move_count];
            //endgame -= trapped_bishop[ENDGAME][move_count];

            //-- King safety
            if (attack_squares = (moves & eval->king_zone[opponent])) {
                eval->king_attack_count[opponent]++;
                eval->king_attack_pressure[opponent] += 20 * popcount(attack_squares);
            }

            // piece-square tables
            middlegame += piece_square_table[piece][MIDDLEGAME][square];
            endgame += piece_square_table[piece][ENDGAME][square];
        }

        //=========================================================
        //-- Knights
        //=========================================================
        piece = PIECEINDEX(color, KNIGHT);
        eval->attacklist[piece] = 0;
        b = board->piecelist[piece];

        _not_occupied = ~board->occupied[color] & ~eval->attacks[opponent][PAWN];

        //-- Outposts
        t_bitboard knight_outpost = b & pawn_record->potential_outpost[color];
        while (knight_outpost) {

            square = bitscan_reset(&knight_outpost);
            t_chess_color square_color = SQUARECOLOR(square);

            //-- Can it be taken by a minor piece?
            if ((board->pieces[opponent][KNIGHT] == 0) && ((board->pieces[opponent][BISHOP] & color_square_mask[square_color]) == 0)) {
                middlegame += 25 - square_distance(square, board->king_square[opponent]);
                endgame += 10;
            }
            else {
                middlegame += 15 - square_distance(square, board->king_square[opponent]);
                endgame += 8;
            }
        }

        while (b) {
            //-- Find the square it resides
            square = bitscan_reset(&b);

            //-- Opponents King Tropism
            middlegame -= square_distance(square, board->king_square[opponent]) * 2;

            //-- Generate moves
            moves = knight_mask[square];
            eval->attacklist[piece] |= moves;

            //-- Connected to another knight
            if (moves & board->piecelist[piece]) {
                middlegame += MG_CONNECTED_KNIGHTS;
                endgame += EG_CONNECTED_KNIGHTS;
            }

            //-- King safety
            if (attack_squares = (moves & eval->king_zone[opponent])) {
                eval->king_attack_count[opponent]++;
                eval->king_attack_pressure[opponent] += 20 * popcount(attack_squares);
            }

            //-- Mobility (not including any squares attacked by enemy pawns)
            moves &= _not_occupied;
            move_count = popcount(moves);
            middlegame += knight_mobility[MIDDLEGAME][move_count];
            endgame += knight_mobility[ENDGAME][move_count];

            // piece-square tables
            middlegame += piece_square_table[piece][MIDDLEGAME][square];
            endgame += piece_square_table[piece][ENDGAME][square];
        }

        //=========================================================
        //-- King Attacks
        //=========================================================
        piece = PIECEINDEX(color, KING);
        eval->attacklist[piece] = king_mask[board->king_square[color]];

		//=========================================================
		//-- Blocked Central Pawns
		//=========================================================
		if (b = (central_kq_pawns[color] & board->pieces[color][PAWN])){
			b = ((b << 8) >> (color * 16)) & board->all_pieces;
			middlegame += -10 * popcount(b);
		}

        //-- Add to board scores
        eval->middlegame += middlegame * (1 - color * 2);
        eval->endgame += endgame * (1 - color * 2);

        //-- Create combined attacks
        eval->attacks[color][BLANK] = eval->attacks[color][PAWN] | eval->attacks[color][ROOK] | eval->attacks[color][BISHOP] | eval->attacks[color][KNIGHT] | eval->attacks[color][QUEEN] | eval->attacks[color][KING];

    }