
void Board::GenKnightMoves(MoveList *list, BitBoard piece_target, BitBoard pieces) {
	// init
	BitBoard movers, moves;
	register uint from,to;

	// knight moves
	movers = piece[KNIGHT] & pieces;
	while(movers) {		
		from = ExtractFirstBit(movers);
		moves = KNIGHT_ATT(from) & piece_target;		
		while(moves) {			
			to = ExtractFirstBit(moves);					
			list->AddKnightMove(from,to,type[to]);
		}
	}
}

void Board::GenRookMoves(MoveList *list, BitBoard rook_target, BitBoard pieces) {
	// init
	BitBoard movers, moves;
	register uint from,to;
	
	// rook and queen moves
	movers = (piece[ROOK]|piece[QUEEN]) & pieces;
	while(movers) {		
		from = ExtractFirstBit(movers);
		moves = ROOK_ATT(from) & rook_target;
		while(moves) {			
			to = ExtractFirstBit(moves);			
			list->AddPieceMove(from,to,type[to], type[from]);			
		}
	}
}

void Board::GenBishopMoves(MoveList *list, BitBoard bishop_target, BitBoard pieces) {
	// init
	BitBoard movers, moves;
	register uint from,to;

	// bishop and queen moves
	movers = (piece[BISHOP]|piece[QUEEN]) & pieces;
	while(movers) {		
		from = ExtractFirstBit(movers);
		moves = BISHOP_ATT(from) & bishop_target;		
		while(moves) {			
			to = ExtractFirstBit(moves);			
			list->AddPieceMove(from,to,type[to], type[from]);			
		}
	}
}

// GenPawnCaptures()

void Board::GenKingMoves(MoveList *list, BitBoard king_target) {
	// init
	register uint to;
	BitBoard moves, enemy = Occupied(stm^1),	
	enemy_rooks = (piece[ROOK]|piece[QUEEN]) & enemy,
	enemy_bishops = (piece[BISHOP]|piece[QUEEN]) & enemy;
		
	moves = KING_ATT(ksq[stm]) & king_target;	
	while(moves) {
		to = ExtractFirstBit(moves);
				 
		if(Pawn[stm][to] & (piece[PAWN]|piece[BISHOP]) & enemy)     continue;
		if(Knight[to] & piece[KNIGHT] & enemy)						continue;
		if(King[to] & (piece[KING]|piece[QUEEN]) & enemy)           continue;
		if(enemy_bishops) if(BISHOP_ATT(to) & enemy_bishops)		continue;
		if(enemy_rooks)   if(ROOK_ATT(to) & enemy_rooks)			continue;

		list->AddKingMove(ksq[stm],to,type[to]);		
	}
}

// GenPawnCaptures()

void Board::GenPawnCaptures(MoveList *list, BitBoard pawn_target, BitBoard pawns) {
	// init	
	BitBoard movers, right_forward, left_forward;
	register sint32 from, to, sign;	
	movers = piece[PAWN] & pawns;
			
	if(stm == WHITE) {
		sign = -1;	
		pawn_target &= ~Rank_8; // (~Rank_8) : prune promotes
		left_forward = BIT_UP_LEFT(movers) & pawn_target;
		right_forward = BIT_UP_RIGHT(movers) & pawn_target;			
	} else { // Black side to move
		sign = 1;	
		pawn_target &= ~Rank_1;
		left_forward = BIT_DOWN_RIGHT(movers) & pawn_target;
		right_forward = BIT_DOWN_LEFT(movers) & pawn_target;			
	}
	// left-forward capture
	while(left_forward) {		
		to = ExtractFirstBit(left_forward);			
		from = to + 7*sign;		
		list->AddPawnCapture(from, to, type[to]);		
	}
	// right-forward capture
	while(right_forward) {		
		to = ExtractFirstBit(right_forward);			
		from = to + 9*sign;
		list->AddPawnCapture(from, to, type[to]);		
	}
}

// GenPawnPromotes()

void Board::GenPawnPromotes(MoveList *list, BitBoard pawn_target, BitBoard pawns) {
	// init	
	BitBoard movers, right_forward, left_forward, one_forward, enemy;
	register sint32 from, to, sign;	
	movers = piece[PAWN] & pawns; // pawns : (nonpinned)
	enemy = Occupied(stm^1) & pawn_target;
		
	if(stm == WHITE) {
		sign = -1;			
		left_forward = BIT_UP_LEFT(movers) & Rank_8 & enemy;  // Rank_8 : promotes only
		right_forward = BIT_UP_RIGHT(movers) & Rank_8 & enemy;	
		one_forward = BIT_UP(movers) & Rank_8 & ~occupied & pawn_target;	
	} else { // Black side to move
		sign = 1;		
		left_forward = BIT_DOWN_RIGHT(movers) & Rank_1 & enemy;
		right_forward = BIT_DOWN_LEFT(movers) & Rank_1 & enemy;	
		one_forward = BIT_DOWN(movers) & Rank_1 & ~occupied & pawn_target;
	}
	// left-forward capture
	while(left_forward) {		
		to = ExtractFirstBit(left_forward);	
		from = to + 7*sign;
		list->AddPromoteCapture(from,to,PROM_QUEEN,type[to]);
		list->AddPromoteCapture(from,to,PROM_KNIGHT,type[to]);
		list->AddPromoteCapture(from,to,PROM_ROOK,type[to]);
		list->AddPromoteCapture(from,to,PROM_BISHOP,type[to]);		
	}
	// right-forward capture
	while(right_forward) {		
		to = ExtractFirstBit(right_forward);	
		from = to + 9*sign;
		list->AddPromoteCapture(from,to,PROM_QUEEN,type[to]);
		list->AddPromoteCapture(from,to,PROM_KNIGHT,type[to]);
		list->AddPromoteCapture(from,to,PROM_ROOK,type[to]);
		list->AddPromoteCapture(from,to,PROM_BISHOP,type[to]);		
	}
	// pawns one forward				
	while(one_forward) {		
		to = ExtractFirstBit(one_forward);		
		from = to + 8*sign;		
		list->AddPromoteStraight(from,to,PROM_QUEEN);
		list->AddPromoteStraight(from,to,PROM_KNIGHT);
		list->AddPromoteStraight(from,to,PROM_ROOK);
		list->AddPromoteStraight(from,to,PROM_BISHOP);		
	}
}

// GenPawnQuiet()

void Board::GenPawnQuiet(MoveList *list, BitBoard pawn_target, BitBoard pawns) {
	// init	
	BitBoard movers, one_forward, two_forward;
	register sint32 from, to, sign;		
	movers = piece[PAWN] & pawns;
		
	if(stm == WHITE) {				
		one_forward = BIT_UP(movers) & pawn_target & (~Rank_8);		
		two_forward = BIT_TWO_UP(movers) & pawn_target & Rank_4;
		two_forward &= ~BIT_UP(occupied);
		sign = -1;
	} else { // Black side to move				
		one_forward = BIT_DOWN(movers) & pawn_target & (~Rank_1);		
		two_forward = BIT_TWO_DOWN(movers) & pawn_target & Rank_5;
		two_forward &= ~BIT_DOWN(occupied);
		sign = 1;
	}
	// pawns one forward				
	while(one_forward) {		
		to = ExtractFirstBit(one_forward);		
		from = to + 8*sign;
		list->AddOneForward(from,to);		
	}
	// pawns two forward
	while(two_forward) {		
		to = ExtractFirstBit(two_forward);
		from = to + 16*sign;
		list->AddTwoForward(from,to);	
	}
}

// GenEPCaptures()

void Board::GenEPCaptures(MoveList *list, BitBoard pawn_target, BitBoard pawns) {
	if(!ep_file)	return; // early exit

	// init
	BitBoard occupied_tmp, enemy_rooks, moves;	
	register sint32 from, to;

	enemy_rooks = (piece[ROOK] | piece[QUEEN]) & Occupied(stm^1);		 
	to = h5_h2[stm] + ep_file;
	if(!(BIT(to) & pawn_target))									return;
	
	moves = Pawn[stm^1][to] & piece[PAWN] & pawns;			
	while(moves) {				
		from = ExtractFirstBit(moves);
		occupied_tmp = occupied ^ (BIT(from)|BIT(h4_h3[stm] + ep_file));
		if(ATT_RANK(ksq[stm], occupied_tmp) & enemy_rooks)			continue;
		list->AddEnPassant(from, to);
	}	
}

void Board::GenCastleMoves(MoveList *list) {
		
	register uint sntm = stm^1; 
	if(CanCastle(stm)) {		
		if(CanCastleShort(stm) && !(ShortCastleAttackedSquares[stm] & occupied))
			if( !IsAttacked(sntm, f1_f8[stm]) && !IsAttacked(sntm, g1_g8[stm])) 
					list->AddShortCastle(stm);
		if(CanCastleLong(stm)  && !((LongCastleAttackedSquares[stm] & occupied)))
			if( !IsAttacked(sntm, c1_c8[stm]) && !IsAttacked(sntm, d1_d8[stm])) 
				list->AddLongCastle(stm);
	} 
}

// FindPinned()

void Board::FindPinned(BitBoard checkers, BitBoard *pinned_rooks, BitBoard *pinned_bishops) {

	// init
	BitBoard enemy_bishops, enemy_rooks, me, enemy, possibly_pinned, pinners;
	uint pinned_square, my_king = ksq[stm], tmp;
	me = Occupied(stm);
	enemy = Occupied(stm^1);
	enemy_bishops = (piece[BISHOP]|piece[QUEEN]) & enemy & ~checkers;
	enemy_rooks = (piece[ROOK]|piece[QUEEN]) & enemy & ~checkers;
	*pinned_rooks = 0;   // all squares between my king and all pinners + pinners [rook direction]
	*pinned_bishops = 0; // -//-//- [bishop direction]

	// 1. bishops or queens	
	if(BISHOP_ATT_PSEUDO(my_king) & enemy_bishops) {		
		possibly_pinned = BISHOP_ATT(my_king) & me & InnerSquares; // heuristic
		while(possibly_pinned) {
			pinned_square = ExtractFirstBit(possibly_pinned);	
			pinners = BISHOP_ATT(pinned_square) & Line[pinned_square][my_king] & enemy_bishops;
			*pinned_bishops |= pinners;
			while(pinners) {
				tmp = ExtractFirstBit(pinners);
				*pinned_bishops |= Between[my_king][tmp];
			}
		}
	}
	// 2. rooks or queens	
	if(ROOK_ATT_PSEUDO(my_king) & enemy_rooks) {		
		possibly_pinned = ROOK_ATT(my_king) & me & NotCornerSquares; // heuristic
		while(possibly_pinned) {
			pinned_square = ExtractFirstBit(possibly_pinned);	
			pinners = ROOK_ATT(pinned_square) & Line[pinned_square][my_king] & enemy_rooks;
			*pinned_rooks |= pinners;
			while(pinners) {
				tmp = ExtractFirstBit(pinners);
				*pinned_rooks |= Between[my_king][tmp];
			}
		}
	}	
}

// GenCaptures()
// we are not in check
// we have found our pinned pieces yet;
// now generate legal captures by pinned and nonpinned pieces

void Board::GenCaptures(MoveList *list, BitBoard pinned_rooks, BitBoard pinned_bishops, BitBoard capture_mask) {

	// init
	BitBoard me,
		pawns, opp, 
		all, pinned;
	all = AllSquares;
	me = Occupied(stm);	
	opp = Occupied(stm^1) & capture_mask;
	pinned = pinned_bishops | pinned_rooks;

	// king moves	
	GenKingMoves(list, opp);

	// pawn moves
	pawns = piece[PAWN] & me;
	GenPawnCaptures(list, opp, pawns & ~pinned);
	GenPawnPromotes(list, all, pawns & ~pinned);
	if(capture_mask & piece[PAWN])		GenEPCaptures(list, all, pawns & ~pinned); 
	if(pawns = piece[PAWN] & me & pinned_bishops) {// pinned
		GenPawnCaptures(list, opp & pinned_bishops, pawns);
		GenPawnPromotes(list, opp & pinned_bishops, pawns);
		if(capture_mask & piece[PAWN])	GenEPCaptures(list, pinned_bishops, pawns); 
	}

	// regular moves
	GenKnightMoves(list, opp, me & ~pinned);
	GenBishopMoves(list, opp, me & ~pinned);
	GenRookMoves(list, opp, me & ~pinned);
	if(pinned_bishops) 		GenBishopMoves(list, opp & pinned_bishops, me & pinned_bishops);
	if(pinned_rooks) 		GenRookMoves(list, opp & pinned_rooks, me & pinned_rooks);

	if(true && DEBUG && (capture_mask == AllSquares)) {
		MoveList dml[1];
		GenLegalCapturesDebug(dml);
		ASSERT(dml->Size() == list->Size());
		if(dml->Size() != list->Size()) {
			printf("true %d this %d stm %d\n", dml->Size(), list->Size(), stm);
			Print();			
			dml->Print();
			printf("***\n");
			list->Print();
			
			dml->Clear();
			GenLegalMoves(dml);
			printf("***\n");
			dml->Print();
		}
	}
}

// GenQuietMoves()
// we are not in check and we have found our pinned pieces yet;
// now generate legal noncapturing moves by pinned and nonpinned pieces 

void Board::GenQuietMoves(MoveList *list, BitBoard pinned_rooks, BitBoard pinned_bishops) {
	
	// init
	BitBoard pawns, me, opp, empty, pinned;
	me = Occupied(stm);
	opp = Occupied(stm^1);	
	empty = ~occupied;
	pinned = pinned_bishops | pinned_rooks;

	// king moves	
	GenKingMoves(list, empty);
	GenCastleMoves(list);

	// pawn moves
	pawns = piece[PAWN] & me & ~pinned;
	GenPawnQuiet(list, empty, pawns);	
	if(pawns = piece[PAWN] & me & pinned_rooks) {// pinned
		GenPawnQuiet(list, empty & pinned_rooks, pawns & pinned_rooks);
	}

	// regular moves
	GenKnightMoves(list, empty, me & ~pinned);
	GenBishopMoves(list, empty, me & ~pinned);
	GenRookMoves(list, empty, me & ~pinned);
	if(pinned_bishops) 		GenBishopMoves(list, empty & pinned_bishops, me & pinned_bishops);
	if(pinned_rooks) 		GenRookMoves(list, empty & pinned_rooks, me & pinned_rooks);

	if(true && DEBUG) {
		MoveList dml[1];
		GenQuietMovesDebug(dml);
		ASSERT(dml->Size() == list->Size());
	}
}

// GenEvasions()
// generates all capturing and noncapturing evasions

void Board::GenEvasions(MoveList *list, BitBoard pinned_rooks, BitBoard pinned_bishops, BitBoard checkers, uint in_check) {

	// init
	uint attacker, my_king;
	BitBoard me, opp, pawns, 
		pinned, king_target, 
		target, movers, between,
		slide_checkers;	
	const BitBoard rank_6_3[] = {Rank_6, Rank_3};
	me = Occupied(stm);
	opp = Occupied(stm^1);	
	pinned = pinned_bishops | pinned_rooks;
	between = 0;

	// king moves (always)
	my_king = ksq[stm];
	king_target = ~me;	
	slide_checkers = checkers & ~(piece[PAWN]|piece[KNIGHT]);
	while(slide_checkers) {
		attacker = ExtractFirstBit(slide_checkers);
		king_target &= (~BehindKing[my_king][attacker]);
		between = Between[my_king][attacker];
		king_target &= (~between);		
	}	
	GenKingMoves(list, king_target);

	// single check
	// pieces target - squares between ksq and attacker (+ attacker)
	if(in_check == 1) {		
		target = between | checkers;
		movers =  me & ~pinned;

		// pawn moves
		pawns = piece[PAWN] & me & ~pinned;	
		GenPawnQuiet(list, between, pawns);			
		GenPawnCaptures(list, checkers, pawns);
		GenPawnPromotes(list, target, pawns);	
		stm == WHITE ? checkers = BIT_UP(checkers) : checkers = BIT_DOWN(checkers);
		GenEPCaptures(list, checkers & CONTACT_FILES_BB(my_king) & rank_6_3[stm], pawns);

		// regular moves		
		GenKnightMoves(list, target, movers);
		GenBishopMoves(list, target, movers);
		GenRookMoves(list, target, movers);
	}	
	
	if(true && DEBUG) {
		MoveList dml[1];
		GenEvasions(dml);
		if(dml->Size() != list->Size()) {
			printf("true %d this %d stm %d epfile %d\n", dml->Size(), list->Size(), stm, ep_file);
			Print();			
			dml->Print();
			printf("***\n");
			list->Print();
			ASSERT(false);
			
			dml->Clear();
			GenLegalMoves(dml);
			printf("***\n");
			dml->Print();
		}
	}
}

void GenChecks(MoveList *list) {
}

//-----------//
// old block //
//-----------//

// GenLegalMoves()

void Board::GenLegalMoves(MoveList *list) {

	// init

	register uint from,to;
	register BitBoard tmp;		
	BitBoard enemy_bishops, enemy_rooks;
	BitBoard enemy = Occupied(stm^1);
	BitBoard me = Occupied(stm);
	BitBoard my_king = piece[KING] & me;	
	BitBoard king_attack_1, king_attack_2;   // for two perpendicular directions
	BitBoard king_attacker;
	BitBoard possibly_pinned;
	BitBoard checker;	
	BitBoard moves;
	BitBoard black_list = 0; // our pinned pieces
	BitBoard target = 0;      // if check, only moves by pieces instead of king to this squares are true
	BitBoard extra_target = 0;  // one square in same line but on an other side of king
	BitBoard contact_target = 0;  // for contact check, our king can eat
	BitBoard movers;
	BitBoard not_pinned;
	uint in_check = 0;	
	uint pinned_square = 0;
	uint pinned_piece;	
	uint my_king_sq = ksq[stm];
	const uint last_rank_co[] = {7,0};	
	const uint h5_h4[] = {h5,h4};	
	bool ep_check = false;	

	// debug
	uint enemy_sq;
	BitBoard enemy_attack;

	// pawns, knight checks
	// (king checks unreal)
	
	if (tmp = Knight[my_king_sq] & piece[KNIGHT] & enemy) {
		in_check++;
		target |= tmp;
	}	
	if(tmp = Pawn[stm][my_king_sq] & piece[PAWN] & enemy) {       
		in_check++;
		contact_target |= tmp;
		if (ep_file) {			
			if(stm == WHITE) {	
				if(Pawn[BLACK][h4 + ep_file] & my_king) // we are under check by pawn
					ep_check = true;
			} else { // BLACK
				if(Pawn[WHITE][h3 + ep_file] & my_king) 					
					ep_check = true;
			}
		}					
	}

	// bishops or queens
	
	enemy_bishops = (piece[BISHOP] | piece[QUEEN]) & enemy;
	if(enemy_bishops) {

		king_attack_1 = ATT_R45(my_king_sq , occupied_rr45);
		king_attack_2 = ATT_L45(my_king_sq , occupied_rl45);

		// is it a check?

		if(king_attacker = king_attack_1 & enemy_bishops) {
			in_check++;
			contact_target |= king_attacker;
			//target |= (king_attack_1 & ATT_R45(ExtractFirstBit(king_attacker) , occupied_rr45)); //not sure	
			enemy_sq = ExtractFirstBit(king_attacker);
			enemy_attack = ATT_R45(enemy_sq , occupied_rr45);
			target |= king_attack_1 & enemy_attack;
			extra_target |= ((King[my_king_sq] & king_attack_1) ^ (target|BIT(enemy_sq))) & King[my_king_sq];
		}
		if(king_attacker = king_attack_2 & enemy_bishops) {
			in_check++;
			contact_target |= king_attacker;
			//target |= (king_attack_2 & ATT_L45(ExtractFirstBit(king_attacker) , occupied_rl45)); //not sure	
			enemy_sq = ExtractFirstBit(king_attacker);
			enemy_attack = ATT_L45(enemy_sq , occupied_rl45);
			target |= king_attack_2 & enemy_attack;
			extra_target |= ((King[my_king_sq] & king_attack_2) ^ (target|BIT(enemy_sq))) & King[my_king_sq];
		}		

		// searching for all our pieces around our king

		possibly_pinned = king_attack_1 & InnerSquares & me; // heuristic
		while(possibly_pinned) {				// 2 opposite directions => max. 2 pinned pieces
			pinned_square = ExtractFirstBit(possibly_pinned);		    
			if(checker = (moves = ATT_R45(pinned_square , occupied_rr45)) & enemy_bishops) {			
				
				pinned_piece = type[pinned_square];
				black_list |= BIT(pinned_square);

				if(pinned_piece == BISHOP || pinned_piece == QUEEN) {
								
					moves = (moves|my_king) ^ my_king; //moves ^= my_king; (faster but is it true?)
					while(moves) {
						
						to = ExtractFirstBit(moves);
						list->AddPieceMove(pinned_square,to,type[to],pinned_piece);						
					}
				} else if(pinned_piece == PAWN) {     // may be our pawn can kill enemy bishop/queen				
					
					to = ExtractFirstBit(checker);
					if (Pawn[stm^1][to] & BIT(pinned_square)) { 
						if (Rank(to)!=last_rank_co[stm]) {							
							list->AddPawnCapture(pinned_square,to,type[to]);
						} else {
							list->AddPromoteCapture(pinned_square,to,PROM_QUEEN,type[to]);
							list->AddPromoteCapture(pinned_square,to,PROM_KNIGHT,type[to]);
							list->AddPromoteCapture(pinned_square,to,PROM_ROOK,type[to]);
							list->AddPromoteCapture(pinned_square,to,PROM_BISHOP,type[to]);
						}
					} else if(ep_file) {	
						if(Pawn[stm^1][h5_h2[stm]+ep_file] & BIT(pinned_square)
						&& (ATT_R45(h5_h2[stm]+ep_file, occupied_rr45) & enemy_bishops)) {
							from = pinned_square;
							to = h5_h2[stm]+ep_file;
							list->AddEnPassant(from,to);
						}
					}
				}	
			}
		}
		// other direction
		possibly_pinned = king_attack_2 & InnerSquares & me;
		while(possibly_pinned) {
			pinned_square = ExtractFirstBit(possibly_pinned);
			if(checker = (moves = ATT_L45(pinned_square , occupied_rl45)) & enemy_bishops) {			
				
				pinned_piece = type[pinned_square];
				black_list |= BIT(pinned_square);

				if(pinned_piece == BISHOP || pinned_piece == QUEEN) {
								
					moves = (moves|my_king) ^ my_king; 
					while(moves) {
						
						to = ExtractFirstBit(moves);
						list->AddPieceMove(pinned_square,to,type[to],pinned_piece);						
					}
				} else if(pinned_piece == PAWN) {   				
					
					to = ExtractFirstBit(checker);
					if (Pawn[stm^1][to] & BIT(pinned_square)) {
						if (Rank(to)!=last_rank_co[stm]) {
							list->AddPawnCapture(pinned_square,to,type[to]);
						} else {
							list->AddPromoteCapture(pinned_square,to,PROM_QUEEN,type[to]);
							list->AddPromoteCapture(pinned_square,to,PROM_KNIGHT,type[to]);
							list->AddPromoteCapture(pinned_square,to,PROM_ROOK,type[to]);
							list->AddPromoteCapture(pinned_square,to,PROM_BISHOP,type[to]);
						}
					} else if(ep_file) {						
						if(Pawn[stm^1][h5_h2[stm]+ep_file] & BIT(pinned_square)
						&& (ATT_L45(h5_h2[stm]+ep_file, occupied_rl45) & enemy_bishops)) {
							from = pinned_square;
							to = h5_h2[stm]+ep_file;
							list->AddEnPassant(from,to);
						}
					}
				}	
			}
		}		
	}

	// rooks or queens
	
	enemy_rooks = (piece[ROOK] | piece[QUEEN]) & enemy;
	if(enemy_rooks) {

		king_attack_1 = ATT_RANK(my_king_sq, occupied);
		king_attack_2 = ATT_FILE(my_king_sq, occupied_rl90);

		// is it a check?

		if(king_attacker = king_attack_1 & enemy_rooks) {			
			in_check++;
			contact_target |= king_attacker;				
			enemy_sq = ExtractFirstBit(king_attacker);
			ASSERT(enemy_sq < 64);
			enemy_attack = ATT_RANK(enemy_sq, occupied);
			target |= king_attack_1 & enemy_attack;
			extra_target |= ((King[my_king_sq] & king_attack_1) ^ (target|BIT(enemy_sq))) & King[my_king_sq];
		}
		if(king_attacker = king_attack_2 & enemy_rooks) {
			in_check++;
			contact_target |= king_attacker;				
			enemy_sq = ExtractFirstBit(king_attacker);
			ASSERT(enemy_sq < 64);
			enemy_attack = ATT_FILE(enemy_sq, occupied_rl90);
			target |= enemy_attack & king_attack_2;			
			extra_target |= ((King[my_king_sq] & king_attack_2) ^ (target|BIT(enemy_sq))) & King[my_king_sq];			
		}		

		// searching for all our pieces around our king

		possibly_pinned = king_attack_1 & NotCornerSquares & me;
		while(possibly_pinned) {
			pinned_square = ExtractFirstBit(possibly_pinned);
			if(checker = (moves = ATT_RANK(pinned_square , occupied)) & enemy_rooks) {			
				
				pinned_piece = type[pinned_square];
				black_list |= BIT(pinned_square);

				if(pinned_piece == ROOK || pinned_piece == QUEEN) {
								
					moves = (moves|my_king) ^ my_king; //moves ^= my_king; (faster but is it true?)
					while(moves) {
						
						to = ExtractFirstBit(moves);
						list->AddPieceMove(pinned_square,to,type[to],pinned_piece);						
					}				
				}
			}
		}
		// other direction - vertical
		possibly_pinned = king_attack_2 & NotCornerSquares & me;
		while(possibly_pinned) {
			pinned_square = ExtractFirstBit(possibly_pinned);				
			if(checker = (moves = ATT_FILE(pinned_square , occupied_rl90)) & enemy_rooks) {			
				
				pinned_piece = type[pinned_square];
				black_list |= BIT(pinned_square);

				if(pinned_piece == ROOK || pinned_piece == QUEEN) {
							
					moves = (moves|my_king) ^ my_king; 
					while(moves) {
						
						to = ExtractFirstBit(moves);
						list->AddPieceMove(pinned_square,to,type[to],pinned_piece);						
					}
				} else if(pinned_piece == PAWN) {  // our pawn may move forward  				
					
					if (stm==WHITE) {
						if(moves = BIT_UP(BIT(pinned_square)) & ~occupied) {								
							to = ExtractFirstBit(moves);
							list->AddOneForward(to-8,to);						
						// may be two steps forward?
							if(moves = BIT_TWO_UP(BIT(pinned_square)) & Rank_4 & ~occupied) {						
								to = ExtractFirstBit(moves);
								list->AddTwoForward(to-16,to);
							}
						}
					}
					else {
						if(moves = BIT_DOWN(BIT(pinned_square)) & ~occupied) {	
							to = ExtractFirstBit(moves);		
							list->AddOneForward(to+8,to);
						
							if(moves = BIT_TWO_DOWN(BIT(pinned_square)) & Rank_5 & ~occupied) {	
								to = ExtractFirstBit(moves);		
								list->AddTwoForward(to+16,to);
							}
						}
					}					
				}	
			}
		}
	}

	// all checks now detected and
	// we have a 'black_list' of our pinned pieces

	// use 'black_list'
	not_pinned = (me | black_list) ^ black_list; // need faster

	// check?

	if(in_check) {

		// our pin_moves are not legal
		list->Clear();
		if(in_check == 1) {
			if(!ep_check) 	
				goto regular_moves;
			goto ep_captures;
		} else  
			goto king_moves;				    
	}

	// casteling

	if (CanCastle(stm)) {
		const BitBoard ShortCastleAttackedSquares[] = {(F1|G1), (F8|G8)};
		const BitBoard LongCastleAttackedSquares[] = {(B1|C1|D1), (B8|C8|D8)};		
		const uint f1_f8[] = {f1, f8};
		const uint g1_g8[] = {g1, g8};
		const uint c1_c8[] = {c1, c8};
		const uint d1_d8[] = {d1, d8};	
		register uint sntm = stm^1; 
		if (CanCastleShort(stm) && !(ShortCastleAttackedSquares[stm] & occupied))
			if ( !IsAttacked(sntm, f1_f8[stm]) && !IsAttacked(sntm, g1_g8[stm])) // ? && !IsAttackedBy(stm^1 ,e1_e8[stm]) - need it?
					list->AddShortCastle(stm);
		if (CanCastleLong(stm)  && !((LongCastleAttackedSquares[stm] & occupied)))
				if ( !IsAttacked(sntm, c1_c8[stm]) && !IsAttacked(sntm, d1_d8[stm])) // ? && !IsAttacked(stm^1 ,e1_e8[stm]) - need it?
					list->AddLongCastle(stm);
	} 

	//ep_captures

ep_captures:

	if (ep_file) {
		BitBoard occupied_tmp;		
		if(ep_check)
			if(BIT(h4_h3[stm] + ep_file) != contact_target) // is ^ instead of != faster? 
				goto regular_moves;	
		to = h5_h2[stm] + ep_file;
		moves = Pawn[stm^1][to] & piece[PAWN] & not_pinned;			
		while(moves) {				
			from = ExtractFirstBit(moves);
			occupied_tmp = occupied ^ (BIT(from)|BIT(h4_h3[stm] + ep_file));
			if (ATT_RANK(my_king_sq, occupied_tmp) & enemy_rooks)
				continue;
			list->AddEnPassant(from, to);
		}
	}

	//regular_moves

regular_moves:

	// some preparations
	contact_target |= target; // hack	
	
	// knight moves
	movers = piece[KNIGHT] & not_pinned;
	while (movers) {		
		from = ExtractFirstBit(movers);
		moves = KNIGHT_ATT(from) & ~me;
		
		while(moves) {
			tmp = moves;
			to = ExtractFirstBit(moves);
			if(in_check) 				
				if(!((tmp ^ moves) & contact_target))
					continue;			
			list->AddKnightMove(from,to,type[to]);
		}
	}
	// bishop moves
	movers = piece[BISHOP] & not_pinned;
	while (movers) {		
		from = ExtractFirstBit(movers);
		moves = BISHOP_ATT(from) & ~me;
		
		while(moves) {
			tmp = moves;
			to = ExtractFirstBit(moves);
			if(in_check) 
				if(!((tmp ^ moves) & contact_target))
					continue;
			list->AddBishopMove(from,to,type[to]);			
		}
	}
	// rook moves
	movers = piece[ROOK] & not_pinned;
	while (movers) {		
		from = ExtractFirstBit(movers);
		moves = ROOK_ATT(from) & ~me;		

		while(moves) {
			tmp = moves;
			to = ExtractFirstBit(moves);
			if(in_check) 
				if(!((tmp ^ moves) & contact_target))
					continue;
			list->AddRookMove(from,to,type[to]);			
		}
	}
	// queen moves
	movers = piece[QUEEN] & not_pinned;
	while (movers) {		
		from = ExtractFirstBit(movers);
		moves = QUEEN_ATT(from) & ~me;        

		while(moves) {
			tmp = moves;
			to = ExtractFirstBit(moves);
			if(in_check) 
				if(!((tmp ^ moves) & contact_target))
					continue;
			list->AddQueenMove(from,to,type[to]);
		}
	}

	// pawn moves
	// init
	movers = piece[PAWN] & not_pinned;
	BitBoard right_forward,
		     left_forward,
			 one_forward,
			 two_forward;	
	int sign;
	if(stm == WHITE) {
		left_forward = BIT_UP_LEFT(movers) & enemy;
		right_forward = BIT_UP_RIGHT(movers) & enemy;		
		one_forward = BIT_UP(movers) & ~occupied;
		two_forward = BIT_UP(one_forward) & ~occupied & Rank_4;
		sign = -1;
	}
	else { // Black side to move
		left_forward = BIT_DOWN_RIGHT(movers) & enemy;
		right_forward = BIT_DOWN_LEFT(movers) & enemy;			
		one_forward = BIT_DOWN(movers) & ~occupied;
		two_forward = BIT_DOWN(one_forward) & ~occupied & Rank_5;
		sign = 1;
	}

	// left-forward capture
	while(left_forward) {
		tmp = left_forward;
		to = ExtractFirstBit(left_forward);
		if(in_check && (!((tmp ^ left_forward) & contact_target)))	continue;
	
		from = to + 7*sign;
		if (Rank(to) != last_rank_co[stm]) {
			list->AddPawnCapture(from, to, type[to]);
		} else {
			list->AddPromoteCapture(from,to,PROM_QUEEN,type[to]);
			list->AddPromoteCapture(from,to,PROM_KNIGHT,type[to]);
			list->AddPromoteCapture(from,to,PROM_ROOK,type[to]);
			list->AddPromoteCapture(from,to,PROM_BISHOP,type[to]);
		}
	}

	// right-forward capture
	while(right_forward) {
		tmp = right_forward;
		to = ExtractFirstBit(right_forward);
		if(in_check && (!((tmp ^ right_forward) & contact_target)))	continue;
	
		from = to + 9*sign;
		if (Rank(to) != last_rank_co[stm]) {
			list->AddPawnCapture(from, to, type[to]);
		} else {
			list->AddPromoteCapture(from,to,PROM_QUEEN,type[to]);
			list->AddPromoteCapture(from,to,PROM_KNIGHT,type[to]);
			list->AddPromoteCapture(from,to,PROM_ROOK,type[to]);
			list->AddPromoteCapture(from,to,PROM_BISHOP,type[to]);
		}
	}

	// pawns one forward				
	while(one_forward) {
		tmp = one_forward;
		to = ExtractFirstBit(one_forward);
		if(in_check && (!((tmp ^ one_forward) & contact_target)))		continue; 			
		
		from = to + 8*sign;
		if (Rank(to) != last_rank_co[stm]) {
			list->AddOneForward(from,to);
		} else {
			list->AddPromoteStraight(from,to,PROM_QUEEN);
			list->AddPromoteStraight(from,to,PROM_KNIGHT);
			list->AddPromoteStraight(from,to,PROM_ROOK);
			list->AddPromoteStraight(from,to,PROM_BISHOP);
		}
	}

	// pawns two forward
	while(two_forward) {	
		tmp = two_forward;
		to = ExtractFirstBit(two_forward);
		if(in_check && (!((tmp ^ two_forward) & contact_target)))	 continue; 

		from = to + 16*sign;
		list->AddTwoForward(from,to);	
	}

	//king_moves

king_moves:

	moves = KING_ATT(my_king_sq) & ~me & ~target & ~extra_target;	
	while(moves) {
		to = ExtractFirstBit(moves);
		// some hacks: (example event: q---K-NR and move e1-f1)		
		 
		if(Pawn[stm][to] & (piece[PAWN]|piece[BISHOP]) & enemy)     continue;
		if(Knight[to] & piece[KNIGHT] & enemy)						continue;
		if(King[to] & (piece[KING]|piece[QUEEN]) & enemy)           continue;
		if(enemy_bishops && (BISHOP_ATT(to) & enemy_bishops))		continue;
		if(enemy_rooks && (ROOK_ATT(to) & enemy_rooks))				continue;			

		list->AddKingMove(ksq[stm],to,type[to]);		
	}
	
	return;
}

// GenLegalCapturesDebug()

void Board::GenLegalCapturesDebug(MoveList *list) {
	
	// init
	MoveList dml[1]; // debug move list
	uint legal_moves;
	uint i = 0;
	Move *current_move;
	
	GenLegalMoves(dml);
	legal_moves = dml->Size();
	
	while (i < legal_moves) {
		current_move = *dml->move + i++;
		if(current_move->IsCapProm())
			list->Add(*current_move);
	}	
}

// GenQuietChecksDebug()

void Board::GenQuietChecksDebug(MoveList *list) {
	
	// init
	MoveList dml[1], dml_2[1]; // debug move list
	uint legal_moves;
	uint i = 0;
	Move *current_move;
	undo_t u[1];

	GenLegalMoves(dml);
	legal_moves = dml->Size();
	
	while (i < legal_moves) {
		current_move = *dml->move + i++;
		if(current_move->IsQuiet())
			dml_2->Add(*current_move);
	}
	// is it a check?
	legal_moves = dml_2->Size();
	for(i = 0; i < legal_moves; i++) {
		current_move = *dml_2->move + i;
		MakeMove(current_move, u);
		if(InCheck())  
			list->Add(*current_move);
		UnmakeMove(current_move, u);
	}	
}

// GenQuietMovesDebug()

void Board::GenQuietMovesDebug(MoveList *list) {

	uint i = 0;
	MoveList dml[1];
	GenLegalMoves(dml);
	Move *current_move;
	uint legal_moves = dml->Size();
	

	while (i < legal_moves) {
		current_move = *dml->move + i++;
		if(current_move->IsQuiet())
			list->Add(*current_move);
	}	
}

bool Board::MoveIsLegal(Move *m) {
	
	uint i = 0;
	MoveList dml[1];
	GenLegalMoves(dml);
	Move *current_move;
	uint legal_moves = dml->Size();

	if(!m->IsReal())	return false;
	while(i < legal_moves) {
		current_move = *dml->move + i++;
		if(current_move->Equal(m))
			return true;
	}
	return false;
}

void Board::GenEvasions(MoveList *list) {
	
	GenLegalMoves(list);	
}

bool Board::MoveIsLegal(Move *m, BitBoard pinned_rooks, BitBoard pinned_bishops) {	

	// init
	uint from, to, pc, cap, my_king;
	BitBoard me, opp, from_bb, to_bb, occ_tmp, enemy_rooks, enemy_bishops;	
	const BitBoard Rank_2_7[] = {Rank_2, Rank_7};
		
	cap = m->Capture();
	pc = m->Piece();
	from = m->From();
	to = m->To();
	my_king = ksq[stm];
	me = Occupied(stm);
	opp = Occupied(stm^1);
	from_bb = BIT(from);
	
	// 1. is it our piece?
	if(!(piece[pc] & me & from_bb))											return false;
	
	// 2. special cases
	if(m->IsEnPassant()) {

		if(pc != PAWN)														return false;
		if(File(to) + 1 != ep_file)											return false;
		// do not discover FILE
		if(from_bb & pinned_rooks)											return false;
		// ... diagonal
		if((from_bb & pinned_bishops) && !(BIT(to) & pinned_bishops))		return false;
		// two pawns "pinned"			
		occ_tmp = occupied ^ (from_bb|BIT(h4_h3[stm] + ep_file));
		enemy_rooks = (piece[ROOK] | piece[QUEEN]) & opp;
		if(ATT_RANK(my_king, occ_tmp) & enemy_rooks)						return false;	

		return true;
	
	} else if(m->IsCastle()) {	

		if(pc != KING)														return false;
		if(to == g1_g8[stm]) {
			if(CanCastleShort(stm) && !(ShortCastleAttackedSquares[stm] & occupied))
				if(!IsAttacked(stm^1, f1_f8[stm]) && !IsAttacked(stm^1, g1_g8[stm])) 
					return true;
		} else if(to == c1_c8[stm]) {
			if(CanCastleLong(stm)  && !((LongCastleAttackedSquares[stm] & occupied)))
				if(!IsAttacked(stm^1, c1_c8[stm]) && !IsAttacked(stm^1, d1_d8[stm])) 
					return true;
		}

		return false;
	} 

	// 3. Regular moves
	to_bb = BIT(to);
	if(me & to_bb)															return false;
	if(cap != type[to])														return false;

	if(pc == PAWN) {
		// right direction
		if(sign[stm] * (from+1) > sign[stm] * (to+1))						return false;
		if(cap == EMPTY) {
			if(!m->IsPromote()) {
				// one or two forward
				if(occupied & BIT(from + 8*sign[stm]))						return false;	
				if(m->IsTwoForward()) {
					if(occupied & to_bb)									return false;
				}				
			} else {	// promote
				if(occupied & to_bb)										return false;
			}
		} else { // capture
			if(!(opp & to_bb))												return false;				
		}
		// final pawn test
		if(from_bb & pinned_rooks) 
			if(!(to_bb & pinned_rooks))										return false;		
		if(from_bb & pinned_bishops) 
			if(!(to_bb & pinned_bishops))									return false;		
		
	} else if(pc == KNIGHT) {
		if((!cap) && (to_bb & opp))											return false;
		if(cap && (!(to_bb & opp)))											return false;
		if(from_bb & (pinned_bishops|pinned_rooks))							return false;
	
	} else if(pc == BISHOP) {
		if(!(BISHOP_ATT(from) & to_bb))										return false; 
		if((!cap) && (to_bb & opp))											return false;
		if(cap && (!(to_bb & opp)))											return false;
		if(from_bb & pinned_rooks)											return false;
		if((from_bb & pinned_bishops)
		&& !(to_bb & pinned_bishops))										return false;
	
	} else if(pc == ROOK) {
		if(!(ROOK_ATT(from) & to_bb))										return false; 
		if((!cap) && (to_bb & opp))											return false;
		if(cap && (!(to_bb & opp)))											return false;
		if(from_bb & pinned_bishops)										return false;
		if((from_bb & pinned_rooks)
		&& !(to_bb & pinned_rooks))											return false;
	
	} else if(pc == QUEEN) {
		if(!(QUEEN_ATT(from) & to_bb))										return false; 
		if((!cap) && (to_bb & opp))											return false;
		if(cap && (!(to_bb & opp)))											return false;		
		if(from_bb & pinned_rooks) {
			if(!(Line[from][to] & BIT(my_king)))							return false;
		}
		if(from_bb & pinned_bishops) {
			if(!(Line[from][to] & BIT(my_king)))							return false;
		}	
	
	} else { // KING
		if((!cap) && (to_bb & opp))											return false;
		if(cap && (!(to_bb & opp)))											return false;

		BitBoard occ_l90, occ_r45, occ_l45;
		enemy_rooks = (piece[ROOK] | piece[QUEEN]) & opp;
		occ_tmp	= occupied ^ from_bb;
		occ_l90 = occupied_rl90 ^ BIT_L90(from);
		if((ATT_RANK(to,occ_tmp) | ATT_FILE(to,occ_l90)) & enemy_rooks)		return false;

		enemy_bishops = (piece[BISHOP] | piece[QUEEN]) & opp;		
		occ_r45 = occupied_rr45 ^ BIT_R45(from);
		occ_l45 = occupied_rl45 ^ BIT_L45(from);
		if((ATT_R45(to,occ_r45) | ATT_L45(to,occ_l45)) & enemy_bishops)		return false;

		if(Pawn[stm][to] & piece[PAWN] & opp)								return false;
		if(KNIGHT_ATT(to) & piece[KNIGHT] & opp)							return false;
		if(KING_ATT(to) & piece[KING] & opp)								return false;
	}	
	
	return true;
}

bool Board::MoveIsLegalDebug(Move *m, BitBoard pinned_rooks, BitBoard pinned_bishops) {	

	bool test = MoveIsLegal(m, pinned_rooks, pinned_bishops);

	return test;

	bool real = MoveIsLegal(m);	
	MoveList ml[1];
	int i = 0;

	if(real != test) {
		Print();
		m->Print();
		GenLegalMoves(ml);
		printf(" stm %d real %d test %d\n", stm, real, test);

		while(i < ml->Size()) {
			if((*ml->move + i++)->From() == m->From())
				if((*ml->move+i)->To() == m->To()) {
					printf(" real m=%d test m=%d\n", (*ml->move+i)->m, m->m);
					printf(" %d %d %d\n", m->Capture(), m->Promote(), m->Removal());					
				}
		}		
		ml->Print();
		PrintBitBoard(stdout, pinned_rooks);
		PrintBitBoard(stdout, BIT(m->From()));
		ASSERT(false);
		MoveIsLegal(m, pinned_rooks, pinned_bishops);
	}

	return real;
}

// FindDiscovered()
// We are not in check 

void Board::FindDiscovered(BitBoard *discovered_rooks, BitBoard *discovered_bishops) {

	// init
	BitBoard my_bishops, my_rooks, me, enemy, possibly_discovered, checkers;
	uint discovered_square, opp_king = ksq[stm^1], tmp;
	me = Occupied(stm);
	enemy = Occupied(stm^1);
	my_bishops = (piece[BISHOP]|piece[QUEEN]) & me;
	my_rooks = (piece[ROOK]|piece[QUEEN]) & me;
	*discovered_rooks = 0;   
	*discovered_bishops = 0; 

	// 1. bishops or queens	
	if(BISHOP_ATT_PSEUDO(opp_king) & my_bishops) {		
		possibly_discovered = BISHOP_ATT(opp_king) & me & InnerSquares; // heuristic
		while(possibly_discovered) {
			discovered_square = ExtractFirstBit(possibly_discovered);	
			checkers = BISHOP_ATT(discovered_square) & Line[discovered_square][opp_king] & my_bishops;			
			while(checkers) {
				tmp = ExtractFirstBit(checkers);
				*discovered_bishops |= Between[opp_king][tmp];
			}
		}
	}
	// 2. rooks or queens	
	if(ROOK_ATT_PSEUDO(opp_king) & my_rooks) {		
		possibly_discovered = ROOK_ATT(opp_king) & me & NotCornerSquares; // heuristic
		while(possibly_discovered) {
			discovered_square = ExtractFirstBit(possibly_discovered);	
			checkers = ROOK_ATT(discovered_square) & Line[discovered_square][opp_king] & my_rooks;
			while(checkers) {
				tmp = ExtractFirstBit(checkers);
				*discovered_rooks |= Between[opp_king][tmp];
			}
		}
	}	
}


void Board::GenQuietChecks(MoveList *list, BitBoard pinned_rooks, BitBoard pinned_bishops) {

	// init
	BitBoard pawns, pc, me, opp, empty, pinned, discovered_rooks, discovered_bishops, discovered;
	uint opp_king = ksq[stm^1];
	me = Occupied(stm);
	opp = Occupied(stm^1);	
	empty = ~occupied;
	pinned = pinned_bishops | pinned_rooks;
	
	// search for discovered pieces
	FindDiscovered(&discovered_rooks, &discovered_bishops);
	discovered = discovered_rooks | discovered_bishops;

	// king moves
	// discovered checks only
	if(piece[KING] & discovered)	GenKingMoves(list, empty & (~discovered));

	// pawn moves
	// direct checks
	pawns = piece[PAWN] & me & ~pinned;
	GenPawnQuiet(list, empty & Pawn[stm^1][opp_king], pawns);
	// discovered
	if(pawns & discovered) {
		GenPawnQuiet(list, empty & ~discovered_rooks, pawns & discovered_rooks);
		GenPawnQuiet(list, empty & ~discovered_bishops, pawns & discovered_bishops);
	}
	if(pawns = piece[PAWN] & me & pinned_rooks) {// pinned
		GenPawnQuiet(list, empty & pinned_rooks & Pawn[stm^1][opp_king], pawns);
		// discovered by pinned
		if(pawns & discovered)		GenPawnQuiet(list, empty & ~discovered & pinned_rooks, pawns & discovered);
	}

	// regular moves
	GenKnightMoves(list, empty & KNIGHT_ATT(opp_king), me & ~pinned & ~discovered); // discovered will be later
	GenBishopMoves(list, empty & BISHOP_ATT(opp_king), me & ~pinned & ~discovered);
	GenRookMoves(list, empty & ROOK_ATT(opp_king), me & ~pinned & ~discovered);
	// queen`s special
	if(pc = me & ~pinned & piece[QUEEN]) {
		GenBishopMoves(list, empty & ROOK_ATT(opp_king), pc);
		GenRookMoves(list, empty & BISHOP_ATT(opp_king), pc);		
	}
	if(pc = me & pinned & piece[QUEEN]) { // pinned
		GenBishopMoves(list, empty & pinned_bishops & ROOK_ATT(opp_king), pc & pinned_bishops);
		GenRookMoves(list, empty & pinned_rooks & BISHOP_ATT(opp_king), pc & pinned_rooks);
	}

	if(pinned_bishops) {
		GenBishopMoves(list, empty & pinned_bishops & BISHOP_ATT(opp_king), me & pinned_bishops & ~discovered);
		GenBishopMoves(list, empty & pinned_bishops, me & pinned_bishops & discovered_rooks);
	}
	if(pinned_rooks) {
		GenRookMoves(list, empty & pinned_rooks & ROOK_ATT(opp_king), me & pinned_rooks & ~discovered);
		GenRookMoves(list, empty & pinned_rooks, me & pinned_rooks & discovered_bishops);
	}
	// discovered
	GenBishopMoves(list, empty, me & piece[BISHOP] & ~pinned & discovered_rooks);
	GenRookMoves(list, empty, me & piece[ROOK] & ~pinned & discovered_bishops);
	GenKnightMoves(list, empty, me & ~pinned & discovered);

	// castle moves
	if(CanCastle(stm)) {
		// short castle		
		if((ATT_FILE(opp_king, occupied_rl90) & F1_F8[stm])
		|| (ATT_RANK(opp_king, occupied) & E1_E8[stm])) {
			if(CanCastleShort(stm) && !(ShortCastleAttackedSquares[stm] & occupied))
				if( !IsAttacked(stm^1, f1_f8[stm]) && !IsAttacked(stm^1, g1_g8[stm])) 
					list->AddShortCastle(stm);
		} else // hack
		// long castle
		if((ATT_FILE(opp_king, occupied_rl90) & D1_D8[stm])
		|| (ATT_RANK(opp_king, occupied) & E1_E8[stm])) {
			if(CanCastleLong(stm)  && !((LongCastleAttackedSquares[stm] & occupied)))
				if( !IsAttacked(stm^1, c1_c8[stm]) && !IsAttacked(stm^1, d1_d8[stm])) 
					list->AddLongCastle(stm);
		}
	}

	if(DEBUG) {
		MoveList dml[1];
		GenQuietChecksDebug(dml);
		if(list->Size() != dml->Size()) {
			Print();
			printf("stm %d\n", stm);
			printf("new\n");
			list->Print();
			printf("\nreal\n");
			dml->Print();
			PrintBitBoard(stdout, discovered_rooks);
			PrintBitBoard(stdout, discovered_bishops);
			PrintBitBoard(stdout, pinned);
			//ASSERT(false);	
			PrintBitBoard(stdout, pinned_rooks);
		}
	}
}

void Board::GenQuietPseudoChecks(MoveList *list, BitBoard pinned_rooks, BitBoard pinned_bishops, 
								 BitBoard discovered_rooks, BitBoard discovered_bishops) {

	// init
	BitBoard pawns, pc, me, opp, empty, pinned, discovered;
	uint opp_king = ksq[stm^1];
	me = Occupied(stm);
	opp = Occupied(stm^1);	
	empty = ~occupied;
	pinned = pinned_bishops | pinned_rooks;	
	discovered = discovered_rooks | discovered_bishops;

	// king moves
	// discovered checks only
	if(piece[KING] & discovered)	GenKingMoves(list, empty & (~discovered));

	// pawn moves
	// direct checks
	pawns = piece[PAWN] & me;
	GenPawnQuiet(list, empty & Pawn[stm^1][opp_king], pawns);
	// discovered checks
	if(pawns & discovered) {
		GenPawnQuiet(list, empty & ~discovered_rooks, pawns & discovered_rooks);
		GenPawnQuiet(list, empty & ~discovered_bishops, pawns & discovered_bishops);
	}

	// regular moves
	// direct checks
	pc = me & ~discovered;
	GenKnightMoves(list, empty & KNIGHT_ATT(opp_king), pc); // discovered will be later
	GenBishopMoves(list, empty & BISHOP_ATT(opp_king), pc);
	GenRookMoves(list, empty & ROOK_ATT(opp_king), pc);
	// queen`s special
	if(pc = me & piece[QUEEN]) {
		GenBishopMoves(list, empty & ROOK_ATT(opp_king), pc);
		GenRookMoves(list, empty & BISHOP_ATT(opp_king), pc);		
	}
	// discovered
	GenBishopMoves(list, empty, me & piece[BISHOP] & discovered_rooks);
	GenRookMoves(list, empty, me & piece[ROOK] & discovered_bishops);
	GenKnightMoves(list, empty, me & discovered);

	// castle moves
	if(CanCastle(stm)) {			
		if((ATT_FILE(opp_king, occupied_rl90) & F1_F8[stm])	// short castle	
		|| (ATT_RANK(opp_king, occupied) & E1_E8[stm])) {
			if(CanCastleShort(stm) && !(ShortCastleAttackedSquares[stm] & occupied))
				if( !IsAttacked(stm^1, f1_f8[stm]) && !IsAttacked(stm^1, g1_g8[stm])) 
					list->AddShortCastle(stm);
		} else if((ATT_FILE(opp_king, occupied_rl90) & D1_D8[stm])	// long castle
		|| (ATT_RANK(opp_king, occupied) & E1_E8[stm])) {
			if(CanCastleLong(stm)  && !((LongCastleAttackedSquares[stm] & occupied)))
				if( !IsAttacked(stm^1, c1_c8[stm]) && !IsAttacked(stm^1, d1_d8[stm])) 
					list->AddLongCastle(stm);
		}
	}

	if(DEBUG) {
		MoveList dml_n[1], dml_o[1]; // new and old
		GenQuietChecksDebug(dml_o);
		for(int i = 0; i < list->Size(); i++) {
			if(MoveIsLegal(list->move[i]))	dml_n->Add(list->move[i]);
		}
		if(dml_n->Size() != dml_o->Size()) {
			Print();
			printf("stm %d\n", stm);
			printf("new\n");
			dml_n->Print();
			printf("\nreal\n");
			dml_o->Print();
			printf("\nall_new\n");
			list->Print();
			PrintBitBoard(stdout, discovered_rooks);
			PrintBitBoard(stdout, discovered_bishops);
			PrintBitBoard(stdout, pinned);
			ASSERT(false);	
			PrintBitBoard(stdout, pinned_rooks);
		}
	}
}