Ejemplo n.º 1
0
int Blind (smove move) {
	int sq_to = move.to;
	int sq_fr = move.from;
	int pc_fr = b.pieces[sq_fr];
	int pc_to = b.pieces[sq_to];
	int val = e.SORT_VALUE[pc_to];

	/* captures by pawn do not lose material */
	if (pc_fr == PAWN) return 1;

	/* Captures "lower takes higher" (as well as BxN) are good by definition. */
	if (e.SORT_VALUE[pc_to] >= e.SORT_VALUE[pc_fr] - 50)
		return 1;

	/* Make the first capture, so that X-ray defender show up*/
	clearSq(sq_fr);

	/* Captures of undefended pieces are good by definition */
	if (!isAttacked(!b.stm, sq_to)) {
		fillSq(b.stm, pc_fr, sq_fr);
		return 1;
	}
	
	fillSq(b.stm, pc_fr, sq_fr);
	return 0; // of other captures we know nothing, Jon Snow!
}
Ejemplo n.º 2
0
bool Board::isCheck(int checked_side) {
	int king_square = -1;
	for (int sq = 0; sq < 64; sq++) {
		if (color[sq] == checked_side && pieces[sq] == K) {
			king_square = sq;
			break;
		}
	}

	int checking_side = (checked_side == WHITE) ? BLACK : WHITE;
	return isAttacked(king_square, checking_side);
}
Ejemplo n.º 3
0
bool Board::invalidate()
{
  Figure::Color ocolor = Figure::otherColor(color_);

  int ki_pos = kingPos(color_);
  int oki_pos = kingPos(ocolor);

  state_ = Ok;

  if ( isAttacked(color_, oki_pos) )
  {
    state_ = Invalid;
    return false;
  }

  if ( isAttacked(ocolor, ki_pos) )
    state_ |= UnderCheck;

  verifyChessDraw();

  if ( drawState() )
    return true;

  int cnum = findCheckingFigures(ocolor, ki_pos);
  if ( cnum > 2 )
  {
    state_ = Invalid;
    return false;
  }
  else if ( cnum > 0 )
  {
    state_ |= UnderCheck;
  }

  verifyState();

  return true;
}
Ejemplo n.º 4
0
std::vector<move_t> Board::generateMoves() {
	std::vector<move_t> moves;
	int piece;
	int from, to;
	move_t move;
	for (int sq = 0; sq < 64; sq++) {
		if (color[sq] != side) continue;
		from = sq;
		piece = pieces[sq];
		
		// Pawns
		if (piece == P) {
			// move one square forward
			to = mailbox[mailbox64[sq] - 10];
			if (to != -1 && color[to] == EMPTY) {
				// promotes on back rank
				if (sq/8 == 1) {
					for (Piece piece : {N, B, R, Q}) {
						move = {from, to, piece, 4};
						moves.push_back(move);
					}
				} else {
					move = {from, to, _, 0};
					moves.push_back(move);
				}
				
				// moves two squares from second rank
				if (sq/8 == 6) {
					to = mailbox[mailbox64[sq] - 20];
					if (to != -1 && color[to] == EMPTY) {
						move = {from, to, _, 16};
						moves.push_back(move);
					}
				}
			}

			// capture diagonally
			for (int offset : {-9, -11}) {
				to = mailbox[mailbox64[sq] + offset];
				if (to == -1 || color[to] != xside) continue;
				
				// promotes on back rank
				if (sq/8 == 1) {
					for (Piece piece : {N, B, R, Q}) {
						move = {from, to, piece, 5};
						moves.push_back(move);
					}
				} else if (to == ep) {
					move = {from, to, _, 8};
					moves.push_back(move);
				} else {
					move = {from, to, _, 1};
					moves.push_back(move);
				}				
			}
		}

		// other pieces
		else {
			for (int offset : offsets[piece]) {
				for (int i = 1;; i++) {
					to = mailbox[mailbox64[sq] + i*offset];
					if (to == -1) break; // can't move off board
					if (color[to] == side) break; // can't capture own piece
					if (color[to] == xside) {
						move = {from, to, _, 1};
						moves.push_back(move);
						break; // can't slide past a capture
					}
					move = {from, to, _, 0};
					moves.push_back(move);
					if (!slide[piece]) break; // stop if piece can't slide
				}
			}
		}

		// castling
		if (piece == K && side_castle) {
			if (side == WHITE) {
				// kingside
				if ((side_castle & 1) && color[61] == EMPTY && color[62] == EMPTY &&
					!isAttacked(60, xside) && !isAttacked(61, xside) && !isAttacked(62, xside)) {
					to = 62; // g1
					move = {from, to, _, 2};
					moves.push_back(move);
				}

				// queenside
				if ((side_castle & 2) && color[57] == EMPTY && color[58] == EMPTY &&
					color[59] == EMPTY && !isAttacked(58, xside) && !isAttacked(59, xside) &&
					!isAttacked(60, xside)) {
					to = 58; // c1
					move = {from, to, _, 2};
					moves.push_back(move);
				}
			} else {
				// queenside
				if ((side_castle & 2) && color[60] == EMPTY && color[61] == EMPTY &&
					color[62] == EMPTY && !isAttacked(59, xside) && !isAttacked(60, xside) &&
					!isAttacked(61, xside)) {
					to = 61; // c8
					move = {from, to, _, 2};
					moves.push_back(move);
				}

				// kingside
				if ((side_castle & 1) && color[57] == EMPTY && color[58] == EMPTY &&
					!isAttacked(57, xside) && !isAttacked(58, xside) && !isAttacked(59, xside)) {
					to = 57; // g8
					move = {from, to, _, 2};
					moves.push_back(move);
				}
			}
		}
	}

	return moves;
}
Ejemplo n.º 5
0
bool Position::inCheck() {
	int kingSquare;
	if (toMove == WHITE) kingSquare = whiteKing;
	else kingSquare = blackKing;
	return isAttacked(kingSquare);
}
Ejemplo n.º 6
0
int movegen(int index)
{
 
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// This is KENNY's pseudo-legal bitmap move generator,
	// using magic multiplication instead of rotated bitboards.
	// There is no check if a move leaves the king in check
	// The first free location in moveBuffer[] is supplied in index,
	// and the new first free location is returned
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
	unsigned char opponentSide;
	unsigned int from, to;
	BitMap tempPiece, tempMove;
	BitMap targetBitmap, freeSquares;
	Move move;
 
	move.clear();
	opponentSide = !board.nextMove;
	freeSquares = ~board.occupiedSquares;
 
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// Black to move
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
	if (board.nextMove) // black to move
	{
		targetBitmap = ~board.blackPieces; // we cannot capture one of our own pieces!
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Black Pawns
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(BLACK_PAWN);
		tempPiece = board.blackPawns;
		while (tempPiece)   
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = BLACK_PAWN_MOVES[from] & freeSquares;                // normal moves
			if (RANKS[from] == 7 && tempMove)                               
			tempMove |= (BLACK_PAWN_DOUBLE_MOVES[from] & freeSquares);  // add double moves
			tempMove |= BLACK_PAWN_ATTACKS[from] & board.whitePieces;       // add captures
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				if ((RANKS[to]) == 1)                                       // add promotions
				{
					move.setProm(BLACK_QUEEN);   board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(BLACK_ROOK);    board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(BLACK_BISHOP);  board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(BLACK_KNIGHT);  board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(EMPTY);      
				}
				else
				{
					board.moveBuffer[index++].moveInt = move.moveInt;
				}
				tempMove ^= BITSET[to];
			}
			// add en-passant captures:
			if (board.epSquare)   // do a quick check first
			{
				if (BLACK_PAWN_ATTACKS[from] & BITSET[board.epSquare])
				{
					if (board.whitePawns & BITSET[board.epSquare + 8])  // final check to protect against same color capture during null move
					{
						move.setProm(BLACK_PAWN);
						move.setCapt(WHITE_PAWN);
						move.setTosq(board.epSquare);
						board.moveBuffer[index++].moveInt = move.moveInt;
					}
				}
			}
			tempPiece ^= BITSET[from];
			move.setProm(EMPTY);
		}                         
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Black Knights
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(BLACK_KNIGHT);
		tempPiece = board.blackKnights;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = KNIGHT_ATTACKS[from] & targetBitmap;
			while (tempMove)          
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Black Bishops
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(BLACK_BISHOP);
		tempPiece = board.blackBishops;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = BISHOPMOVES(from);   // see Macro's
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Black Rooks
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(BLACK_ROOK);
		tempPiece = board.blackRooks;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = ROOKMOVES(from);   // see Macro's
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Black Queens
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(BLACK_QUEEN);
		tempPiece = board.blackQueens;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = QUEENMOVES(from);   // see Macro's
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
		tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Black King
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(BLACK_KING);
		tempPiece = board.blackKing;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = KING_ATTACKS[from] & targetBitmap;
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
 
			//     Black 0-0 Castling:
			if (board.castleBlack & CANCASTLEOO)
			{
				if (!(maskFG[1] & board.occupiedSquares))
				{
					if (!isAttacked(maskEG[BLACK_MOVE], WHITE_MOVE))
					{
						board.moveBuffer[index++].moveInt = BLACK_OO_CASTL;   // predefined unsigned int
					}
				}
			}
			//     Black 0-0-0 Castling:
			if (board.castleBlack & CANCASTLEOOO)
			{
				if (!(maskBD[1] & board.occupiedSquares))
				{
					if (!isAttacked(maskCE[BLACK_MOVE], WHITE_MOVE))
					{
						board.moveBuffer[index++].moveInt = BLACK_OOO_CASTL; // predefined unsigned int
					}
				}
			}
			tempPiece ^= BITSET[from];
			move.setProm(EMPTY);
		}
	}
 
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// White to move
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
	else 
	{
		targetBitmap = ~board.whitePieces; // we cannot capture one of our own pieces!
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// White Pawns
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(WHITE_PAWN);
		tempPiece = board.whitePawns;
		while (tempPiece)   
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = WHITE_PAWN_MOVES[from] & freeSquares;                // normal moves
			if (RANKS[from] == 2 && tempMove)                               
			tempMove |= (WHITE_PAWN_DOUBLE_MOVES[from] & freeSquares);  // add double moves
			tempMove |= WHITE_PAWN_ATTACKS[from] & board.blackPieces;       // add captures
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				if ((RANKS[to]) == 8)                                       // add promotions
				{
					move.setProm(WHITE_QUEEN);   board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(WHITE_ROOK);    board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(WHITE_BISHOP);  board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(WHITE_KNIGHT);  board.moveBuffer[index++].moveInt = move.moveInt;
					move.setProm(EMPTY);      
				}
				else
				{
					board.moveBuffer[index++].moveInt = move.moveInt;
				}
				tempMove ^= BITSET[to];
			}
			// add en-passant captures:
			if (board.epSquare)   // do a quick check first
			{
				if (WHITE_PAWN_ATTACKS[from] & BITSET[board.epSquare])
				{
					if (board.blackPawns & BITSET[board.epSquare - 8])  // final check to protect against same color capture during null move
					{
						move.setProm(WHITE_PAWN);
						move.setCapt(BLACK_PAWN);
						move.setTosq(board.epSquare);
						board.moveBuffer[index++].moveInt = move.moveInt;
					}
				}
			}
			tempPiece ^= BITSET[from];
			move.setProm(EMPTY);
		}                         
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// White Knights
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(WHITE_KNIGHT);
		tempPiece = board.whiteKnights;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = KNIGHT_ATTACKS[from] & targetBitmap;
			while (tempMove)          
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// White Bishops
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(WHITE_BISHOP);
		tempPiece = board.whiteBishops;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = BISHOPMOVES(from);   // see Macro's
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// White Rooks
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(WHITE_ROOK);
		tempPiece = board.whiteRooks;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = ROOKMOVES(from);   // see Macro's
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// White Queens
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(WHITE_QUEEN);
		tempPiece = board.whiteQueens;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = QUEENMOVES(from);   // see Macro's
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
			tempPiece ^= BITSET[from];
		}
 
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// White king
		// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		move.setPiec(WHITE_KING);
		tempPiece = board.whiteKing;
		while (tempPiece)
		{
			from = firstOne(tempPiece);
			move.setFrom(from);
			tempMove = KING_ATTACKS[from] & targetBitmap;
			while (tempMove)
			{
				to = firstOne(tempMove);
				move.setTosq(to);
				move.setCapt(board.square[to]);
				board.moveBuffer[index++].moveInt = move.moveInt;
				tempMove ^= BITSET[to];
			}
 
			//     White 0-0 Castling:
			if (board.castleWhite & CANCASTLEOO)
			{
				if (!(maskFG[0] & board.occupiedSquares))
				{
					if (!isAttacked(maskEG[WHITE_MOVE], BLACK_MOVE))
					{
						board.moveBuffer[index++].moveInt = WHITE_OO_CASTL; // predefined unsigned int
					}
				}
			}
 
			//     White 0-0-0 Castling:
			if (board.castleWhite & CANCASTLEOOO)
			{
				if (!(maskBD[0] & board.occupiedSquares))
				{
					if (!isAttacked(maskCE[WHITE_MOVE], BLACK_MOVE))
					{
						board.moveBuffer[index++].moveInt = WHITE_OOO_CASTL; // predefined unsigned int
					}
				}
			}
			tempPiece ^= BITSET[from];
			move.setProm(EMPTY);
		}
	}     
	return index;
}