// Eval()

int Board::Eval(EvalInfo *ev_info, Personality *p, PawnInfo *pi) {
		
	sint16 res, lazy_eval;
	int phase, passer_rank[2];	
	bool mat_draw, shelter_flag[2], bishop_draw, rook_eg, pawn_eg, lazy;
	int wing, curr, poss, shelter, att_weight; // king safety	
	BitBoard king[2], att_target[2], piece_mob[2], mob_tmp, movers,		
		pawn_mob[2], knight_mob[2], bishop_mob[2], rook_mob[2], queen_mob[2],
		mob, rook_support, possible_victims[2], pinned_rooks[2], pinned_bishops[2];
	uint attackers[2], att_weight_gs[2], att_weight_bs[2], colour, sq, mob_count, tmp, qsq[2] = {0, 0};	
			
	// save op & eg
	int saved_op = opening;
	int saved_eg = endgame;

	// retrieve material
	material[mat_key & 0x3FFFF].Retrieve(&res, &phase, &mat_draw, &shelter_flag[WHITE], &shelter_flag[BLACK],
		                                 &bishop_draw, &rook_eg, &pawn_eg, &lazy);			
	opening += mat_diff;
	endgame += mat_diff;
	
	// pawn hash
	ASSERT(pawn_key == InitPawnHashKey());
	PawnEntry *ent = pi->GetInfo(this, p);
	opening += ent->opening;
	endgame += ent->endgame;

	// searching checks and pinned pieces
	ev_info->in_check = InCheck(&ev_info->checkers);
	FindPinned(ev_info->checkers, &ev_info->pinned_rooks, &ev_info->pinned_bishops); // true colour

	// opposite colored bishops
	if(bishop_draw
	&& (piece[BISHOP] & LightSquares) 
	&& (piece[BISHOP] & DarkSquares)) {	
		if(piece[KNIGHT]|piece[ROOK]|piece[QUEEN])	endgame = endgame * (90)/100;
		else										endgame = endgame * (50)/100;
		if(ent->central_file != CENTRAL_FILE_NO)	endgame = endgame * (85)/100;		
	}
	// endgame pawn centralization
	if(ent->central_file != CENTRAL_FILE_NO) {
		endgame += EgKingCentralization[File(ksq[WHITE])][ent->central_file];
		endgame -= EgKingCentralization[File(ksq[BLACK])][ent->central_file];
		if(piece[KNIGHT] & White())			 endgame += KNIGHT_VALUE * 5/100;
		if(piece[KNIGHT] & Black())			 endgame -= KNIGHT_VALUE * 5/100;
	}
			
	// lazy eval	
	ev_info->lazy_used = false;
	if(lazy || rook_eg || pawn_eg || mat_draw) {	
		if(mat_draw)		lazy_eval = 0;
		else if(rook_eg)	lazy_eval = res + RookEndgame(p, ent);
		else if(pawn_eg)	lazy_eval = res + PawnEndgame(p, ent);
		else				lazy_eval = ((phase * endgame + (PHASE_NB - phase) * opening) / PHASE_NB);
		if(lazy_eval >= ev_info->beta 
		|| lazy_eval <= ev_info->alpha
		|| mat_draw == true
		|| rook_eg == true
		|| pawn_eg == true) {
			ev_info->lazy_used = true;
			opening = saved_op;		endgame = saved_eg;
			return ev_info->value = lazy_eval * sign[stm];	
		}	
	}

	// continue searching pinned pieces
	pinned_rooks[stm] = ev_info->pinned_rooks;
	pinned_bishops[stm] = ev_info->pinned_bishops;	
	stm ^= 1;	// we have to evaluate other colour 
	FindPinned(0, &pinned_rooks[stm], &pinned_bishops[stm]);
	stm ^= 1;	// backup 
		
	// main init
	rook_support = ~AllSquares;
	king[WHITE] = piece[KING] & White();
	king[BLACK] = piece[KING] & Black();	
	att_target[WHITE] = King[ksq[BLACK]];
	att_target[BLACK] = King[ksq[WHITE]];
	attackers[WHITE] = attackers[BLACK] = 0;
	att_weight_gs[WHITE] = att_weight_gs[BLACK] = 0;
	att_weight_bs[WHITE] = att_weight_bs[BLACK] = 0;
	// eval info
	ev_info->victims[WHITE] = ev_info->victims[BLACK] = 0;
	possible_victims[WHITE] = possible_victims[BLACK] = 0;
				
	// pawns
	movers = piece[PAWN] & White();
	if((pawn_mob[WHITE] = BIT_UP_LEFT(movers) | BIT_UP_RIGHT(movers)) & att_target[WHITE])		attackers[WHITE]++;	
	if(((movers|pawn_mob[WHITE]) ^ pawn_mob[WHITE]) & KingZone[BLACK][ ksq[BLACK] ])			ESI(WHITE, EG_KING_ZONE_PENALTY);		
	// attacks
	mob = movers & ~(pinned_bishops[WHITE]|pinned_rooks[WHITE]);
	if(mob_tmp = (BIT_UP_LEFT(mob) | BIT_UP_RIGHT(mob)) & Occupied(BLACK)) {
		possible_victims[WHITE] |= mob_tmp & ~(piece[PAWN] & Occupied(stm));  // hack: our pawn attacks pawn only if stm is our
		ev_info->victims[WHITE] |= mob_tmp & ~piece[PAWN];
	} if(mob = movers & pinned_bishops[WHITE]) {
		ev_info->victims[WHITE] |= ((BIT_UP_LEFT(mob) | BIT_UP_RIGHT(mob)) & pinned_bishops[WHITE] & Occupied(BLACK));
	}

	movers = piece[PAWN] & Black();
	if((pawn_mob[BLACK] = BIT_DOWN_LEFT(movers) | BIT_DOWN_RIGHT(movers)) & att_target[BLACK])	attackers[BLACK]++;	
	if(((movers|pawn_mob[BLACK]) ^ pawn_mob[BLACK]) & KingZone[WHITE][ ksq[WHITE] ])			ESI(BLACK, EG_KING_ZONE_PENALTY);
	// attacks
	mob = movers & ~(pinned_bishops[BLACK]|pinned_rooks[BLACK]);
	if(mob_tmp = (BIT_DOWN_LEFT(mob) | BIT_DOWN_RIGHT(mob)) & Occupied(WHITE)) {
		possible_victims[BLACK] |= mob_tmp & ~(piece[PAWN] & Occupied(stm));
		ev_info->victims[BLACK] |= mob_tmp & ~piece[PAWN];
	} if(mob = movers & pinned_bishops[BLACK]) {
		ev_info->victims[BLACK] |= ((BIT_DOWN_LEFT(mob) | BIT_DOWN_RIGHT(mob)) & pinned_bishops[BLACK] & Occupied(WHITE));
	}

	for(colour = WHITE; colour <= BLACK; colour++) {
		// knight
		knight_mob[colour] = 0;
		movers = piece[KNIGHT] & Occupied(colour);
		while(movers) {
			sq = ExtractFirstBit(movers);
			if((mob = KNIGHT_ATT(sq)) & att_target[colour]) {
				attackers[colour]++;
				att_weight_gs[colour] += p->KNIGHT_ATT_WEIGHT_GS;	
				att_weight_bs[colour] += p->KNIGHT_ATT_WEIGHT_BS;
			}
			// attacks
			if(!(BIT(sq) & (pinned_bishops[colour] | pinned_rooks[colour]))) {
				possible_victims[colour] |= (mob & Occupied(colour^1));
				ev_info->victims[colour] |= (mob & Occupied(colour^1) & (piece[ROOK]|piece[QUEEN]));
			}
			// mobility
			knight_mob[colour] |= mob;
			mob_count = CountFirstBits(mob & ~Occupied(colour));
			if(BIT(sq) & FriendlySide[colour]) {
				OTI(colour, OP_KNIGHT_MOB_1, mob_count);
				ETI(colour, EG_KNIGHT_MOB_1, mob_count);
			} else {
				OTIP(colour, OP_KNIGHT_MOB_1, mob_count, p->OP_ENEMY_SIDE_MOB);
				ETIP(colour, EG_KNIGHT_MOB_1, mob_count, p->EG_ENEMY_SIDE_MOB);
			}
			// knight outpost
			if((BIT(sq) & pawn_mob[colour])
			&& !(AntiOutpostPawns[colour][sq] & piece[PAWN] & Occupied(colour^1)))
				OTI(colour, KNIGHT_OUTPOST_OPENING[colour], sq);
		}	 
		// bishop
		bishop_mob[colour] = 0;
		movers = piece[BISHOP] & Occupied(colour);
		while(movers) {
			sq = ExtractFirstBit(movers);
			if((mob = BISHOP_ATT(sq)) & att_target[colour]) {
				attackers[colour]++;
				att_weight_gs[colour] += p->BISHOP_ATT_WEIGHT_GS;
				att_weight_bs[colour] += p->BISHOP_ATT_WEIGHT_BS;

				// there are no pawns in this squares
				if(mob & att_target[colour] & ~piece[PAWN]) {
					// opponent has no bishop with this colour
					if(BIT(sq) & LightSquares) {
						if(!(piece[BISHOP] & Occupied(colour^1) & LightSquares))		OSI(colour, BISHOP_ATT_WEAK_SQUARES);
					} else { // DarkSquares
						if(!(piece[BISHOP] & Occupied(colour^1) & DarkSquares))			OSI(colour, BISHOP_ATT_WEAK_SQUARES);
					}					
				}				
			}
			// attacks
			if(!(BIT(sq) & (pinned_bishops[colour] | pinned_rooks[colour]))) {
				possible_victims[colour] |= (mob & Occupied(colour^1));
				ev_info->victims[colour] |= (mob & Occupied(colour^1) & (piece[ROOK]|piece[QUEEN]));
			} else if(BIT(sq) & pinned_bishops[colour]) {
				possible_victims[colour] |= (mob & Occupied(colour^1) & pinned_bishops[colour]);
				ev_info->victims[colour] |= (mob & Occupied(colour^1) & pinned_bishops[colour] & (piece[ROOK]|piece[QUEEN]));
			}
			// mobility
			bishop_mob[colour] |= mob;
			mob_count = CountFirstBits(mob & ~Occupied(colour));
			if(BIT(sq) & FriendlySide[colour]) {
				OTI(colour, OP_BISHOP_MOB_1, mob_count);
				ETI(colour, EG_BISHOP_MOB_1, mob_count);
			} else {
				OTIP(colour, OP_BISHOP_MOB_1, mob_count, p->OP_ENEMY_SIDE_MOB);
				ETIP(colour, EG_BISHOP_MOB_1, mob_count, p->EG_ENEMY_SIDE_MOB);
			}
		}
		// rook
		rook_mob[colour] = 0;
		movers = piece[ROOK] & Occupied(colour);
		while(movers) {
			sq = ExtractFirstBit(movers);
			mob_tmp = ATT_RANK(sq, occupied);
			mob = ATT_FILE(sq, occupied_rl90) | mob_tmp;
			if(mob & att_target[colour]) {
				attackers[colour]++;
				att_weight_gs[colour] += p->ROOK_ATT_WEIGHT_GS;
				att_weight_bs[colour] += p->ROOK_ATT_WEIGHT_BS;
			}
			// attacks
			if(!(BIT(sq) & (pinned_bishops[colour] | pinned_rooks[colour]))) {
				possible_victims[colour] |= (mob & Occupied(colour^1));
				ev_info->victims[colour] |= (mob & Occupied(colour^1) & piece[QUEEN]);
			} else if(BIT(sq) & pinned_rooks[colour]) {
				possible_victims[colour] |= (mob & Occupied(colour^1) & pinned_rooks[colour]);
				ev_info->victims[colour] |= (mob & Occupied(colour^1) & pinned_rooks[colour] & piece[QUEEN]);
			}
			// mobility
			rook_mob[colour] |= mob;
			mob_count = CountFirstBits(mob & ~Occupied(colour));
			if(BIT(sq) & FriendlySide[colour]) {
				OTI(colour, OP_ROOK_MOB_1, mob_count);
				ETI(colour, EG_ROOK_MOB_1, mob_count);
			} else {
				OTIP(colour, OP_ROOK_MOB_1, mob_count, p->OP_ENEMY_SIDE_MOB);
				ETIP(colour, EG_ROOK_MOB_1, mob_count, p->EG_ENEMY_SIDE_MOB);
			}

			// connected rooks
			if(rook_mob[colour] & BIT(sq)) 		GSI(colour, CONNECTED_ROOKS);			
			// 7th rank
			if((BIT(sq) & SeventhRank[colour])
			&& ((piece[KING] & Occupied(colour^1) & EighthRank[colour]))
				|| (piece[PAWN] & Occupied(colour^1) & SeventhRank[colour])) {
				OSI(colour, OP_ROOK_ON_7TH);
				ESI(colour, EG_ROOK_ON_7TH);
			}								
			// open file
			if(!((mob = HalfOpenFileMask[colour][sq]) & piece[PAWN] & Occupied(colour))) {
				OSI(colour, OP_ROOK_HALF_OPEN_FILE);
				ESI(colour, EG_ROOK_HALF_OPEN_FILE);
				if(!(mob & piece[PAWN] & Occupied(colour^1))) {
					OSI(colour, OP_ROOK_OPEN_FILE);
					ESI(colour, EG_ROOK_OPEN_FILE);
				}				
				if(!(HalfOpenFileMask[colour^1][sq] & piece[PAWN] & Occupied(colour))) { // no our pawns behind rook
					if(shelter_flag[colour^1]) {
						if(mob & att_target[colour]) {
							OSI(colour, OP_ROOK_FILE_ATT_KING_1);
							if(mob & piece[KING] & Occupied(colour^1))
								OSI(colour, OP_ROOK_FILE_ATT_KING_2);
						}
					}
					if(mob & ent->weak_pawns)		OSI(colour, OP_ROOK_ATT_WEAK_PAWN);					
				}
			} else {
				rook_support |= (mob & ent->passed_pawns & Occupied(colour));
			}
			// our pawns behind rook
			if(HalfOpenFileMask[colour^1][sq] & piece[PAWN] & Occupied(colour))		OSI(colour, OP_PAWNS_BEHIND_ROOK_PENALTY);			
		}	
		// queen
		queen_mob[colour] = 0;
		movers = piece[QUEEN] & Occupied(colour);
		while(movers) {
			sq = ExtractFirstBit(movers);
			qsq[colour] = sq;
			if((mob = QUEEN_ATT(sq)) & att_target[colour]) {
				attackers[colour]++;
				att_weight_gs[colour] += p->QUEEN_ATT_WEIGHT_GS;
				att_weight_bs[colour] += p->QUEEN_ATT_WEIGHT_BS;
			}
			// attacks
			if(!(BIT(sq) & (pinned_bishops[colour] | pinned_rooks[colour]))) {
				possible_victims[colour] |= (mob & Occupied(colour^1));
			} else if(BIT(sq) & pinned_rooks[colour]) {
				possible_victims[colour] |= (mob & Occupied(colour^1) & pinned_rooks[colour]);
			} else {
				ASSERT(BIT(sq) & pinned_bishops[colour]);
				possible_victims[colour] |= (mob & Occupied(colour^1) & pinned_bishops[colour]);
			}
			// mobility
			queen_mob[colour] |= mob;
			if(BIT(sq) & EnemySide[colour]) {
				mob_count = CountBits(mob & ~Occupied(colour));
				mob_count = MIN(mob_count, 7);
				OTI(colour, OP_QUEEN_MOB_1, mob_count);
			}
			// tropism
			tmp = ksq[colour^1];
			mob_count = 14 - (FILE_DIST(sq, tmp) + RANK_DIST(sq, tmp));
			OTI(colour, OP_QUEEN_MOB_2, mob_count);
			ETI(colour, EG_QUEEN_MOB_2, mob_count);

			// 7th rank
			if((BIT(sq) & SeventhRank[colour])
			&& ((piece[KING] & Occupied(colour^1) & EighthRank[colour]))
				|| (piece[PAWN] & Occupied(colour^1) & SeventhRank[colour])) {	
				OSI(colour, OP_QUEEN_ON_7TH);
				ESI(colour, EG_QUEEN_ON_7TH);
			}			
		}		
	}

	// mobility
	piece_mob[WHITE] = pawn_mob[WHITE] | knight_mob[WHITE] | bishop_mob[WHITE] | rook_mob[WHITE] | queen_mob[WHITE] | KING_ATT(ksq[WHITE]);
	piece_mob[BLACK] = pawn_mob[BLACK] | knight_mob[BLACK] | bishop_mob[BLACK] | rook_mob[BLACK] | queen_mob[BLACK] | KING_ATT(ksq[BLACK]);

	// king safety & passed pawns
	for(colour = WHITE; colour <= BLACK; colour++) {
		// king attacks		 
		possible_victims[colour] |= (KING_ATT(ksq[colour]) & Occupied(colour^1));	
		// king safety
		if(shelter_flag[colour]) {
			wing = KingWing[ksq[colour]];
			curr = poss = ent->shelter[colour][wing];
			if(CanCastleShort(colour))	poss = MAX(ent->shelter[colour][KINGSIDE], poss);
			if(CanCastleLong(colour))	poss = MAX(ent->shelter[colour][QUEENSIDE], poss);
			shelter = (curr + poss) / 2;
			att_weight = (att_weight_gs[colour^1]*curr + att_weight_bs[colour^1]*(p->MAX_SHELTER_VALUE - curr)) / p->MAX_SHELTER_VALUE;
			shelter -= ((p->PIECE_ATT_WEIGHT[ attackers[colour^1] ]) * att_weight) / MAX(p->SAFETY_RATIO + curr/16, 1);		
			opening += sign[colour]*(ev_info->king_safety[colour] = shelter);			
			endgame += sign[colour]*p->NON_PAWN_DEFENDER_VALUE[CountFirstBits(att_target[colour^1] & Occupied(colour))] / MAX(shelter, p->MIN_SHELTER_VALUE);
		}
		// passed pawns
		passer_rank[colour] = 0;
		movers = ent->passed_pawns & Occupied(colour);
		while(movers) {
			tmp = sq = ExtractFirstBit(movers);
			mob = HalfOpenFileMask[colour][sq];
			// opponent has no pieces (pawns only)
			if(!((piece[KNIGHT] | piece[BISHOP] | piece[ROOK] | piece[QUEEN]) & Occupied(colour^1))) {
				if(mob & piece[KING])				tmp -= 8*sign[colour]; // blocker
				if(colour == stm)					tmp += 8*sign[colour]; // our tempo 
				if(RANK_COL(sq,colour) == RANK_2)	tmp += 8*sign[colour]; // a2-a4 instead of a2-a3
				if((UnstoppablePassed[colour][tmp] & piece[KING] & Occupied(colour^1))
				|| (KingAssist[colour][sq] & piece[KING] & Occupied(colour))) 
					passer_rank[colour] = MAX(passer_rank[colour], RANK_COL(tmp, colour) * 2); // *2 - moves to plies format				
			} 
			// main block
			tmp = sq + 8*sign[colour];
			if(!(mob & Occupied(colour)))								ETI(colour, EG_PASSED_PAWN_WO_OUR_BLOCKER, RANK_COL(sq, colour));
			if(!(mob & Occupied(colour^1)))								ETI(colour, EG_PASSED_PAWN_WO_OPP_BLOCKER, RANK_COL(sq, colour));
			if(!(mob & piece_mob[colour^1] & ~piece_mob[colour]))		ETI(colour, EG_PASSED_PAWN_WO_MOB_BLOCKER, RANK_COL(sq, colour));				
			// pawn is not free to advance penalties
			if(BIT(tmp) & Occupied(colour^1)) {							GTI(colour, PASSED_PAWN_CANT_MOVE_PENALTY, RANK_COL(sq, colour));																																			
			} else if(!(piece_mob[colour] & BIT(tmp)) 
				   && !(rook_support & BIT(sq))) {						ETI(colour, PASSED_PAWN_CANT_MOVE_PENALTY, RANK_COL(sq, colour));
			} else if(!(pawn_mob[colour] & BIT(tmp))
				   && !(rook_support & BIT(sq))
				   && !(knight_mob[colour] & bishop_mob[colour] & BIT(tmp))
				   && !((rook_mob[colour]|queen_mob[colour]|KING_ATT(ksq[colour])) & (knight_mob[colour]|bishop_mob[colour]) & BIT(tmp))) {					   
					   if((knight_mob[colour^1] & bishop_mob[colour^1] & BIT(tmp))
					   ||((rook_mob[colour^1]|queen_mob[colour^1]|KING_ATT(ksq[colour^1])) & (knight_mob[colour^1]|bishop_mob[colour^1]) & BIT(tmp))) 
																		ETI(colour, PASSED_PAWN_CANT_MOVE_PENALTY, RANK_COL(sq, colour));					   
			}
			
			// attacker - opponents king (further king => bigger our bonus) 
			ETIC(colour, EG_PASSED_PAWN_ATTACKER, RANK_COL(sq, colour), SQUARE_DIST(tmp, ksq[colour^1]));
			ETIC(colour, EG_PASSED_PAWN_DEFENDER, RANK_COL(sq, colour), -SQUARE_DIST(tmp, ksq[colour]));

			// passed chain
			if(ChainPawnMask[colour][sq] & ent->passed_pawns & Occupied(colour))	
				MTI(colour, OP_PASSED_CHAIN, EG_PASSED_CHAIN, RANK_COL(sq, colour));
		}		
	}
	if(passer_rank[WHITE] - passer_rank[BLACK] + sign[stm ^ 1] >= 3)		ESI(WHITE, EG_UNSTOPPABLE_PASSED_PAWN);
	else if(passer_rank[BLACK] - passer_rank[WHITE] + sign[stm] >= 3)		ESI(BLACK, EG_UNSTOPPABLE_PASSED_PAWN);

	// compute and store victims info
	ev_info->victims[WHITE] |= (possible_victims[WHITE] & ~piece_mob[BLACK]);
	ev_info->victims[BLACK] |= (possible_victims[BLACK] & ~piece_mob[WHITE]);
	ev_info->pawn_victim_delta = CountFirstBits(ev_info->victims[WHITE]) - CountFirstBits(ev_info->victims[BLACK]);
	ev_info->pure_victim_delta = CountFirstBits(ev_info->victims[WHITE] & ~piece[PAWN]) - CountFirstBits(ev_info->victims[BLACK] & ~piece[PAWN]);
		
	// evaluate attacked pieces
	GSIC(WHITE, ATTACKED_PAWN_BONUS, ev_info->pawn_victim_delta);
	GSIC(WHITE, ATTACKED_PIECE_BONUS, ev_info->pure_victim_delta);	

	// attacked weak pawns
	if(piece_mob[WHITE] & ent->weak_pawns & Occupied(BLACK))	GSI(WHITE, ATTACKED_WEAK_PAWN);
	if(piece_mob[BLACK] & ent->weak_pawns & Occupied(WHITE))	GSI(WHITE, ATTACKED_WEAK_PAWN);

	// evaluate pins and x-ray attacks	
	for(colour = WHITE; (colour <= BLACK) && (phase <= PHASE_NB * 10/24); colour++) {
		// pin::king (pinned pieces already computed)
		mob = piece[KNIGHT]|piece[QUEEN]|(piece[PAWN] & ~(King[ksq[colour]]|pawn_mob[colour]));
		movers = pinned_bishops[colour] & Occupied(colour) & (piece[ROOK]|mob);
		movers |= pinned_rooks[colour] & Occupied(colour) & (piece[BISHOP]|mob); 
		while(movers) {
			sq = ExtractFirstBit(movers);			
			if(pawn_mob[colour] & BIT(sq)) {		GSI(colour, PINNED_KING);
			} else {								GSI(colour, UNDEFENDED_PINNED_KING);}			
		}
		// pin::queen
		sq = a1; // hack
		movers = queen_mob[colour] & (bishop_mob[colour^1]) & Occupied(colour) & (piece[ROOK]|piece[KNIGHT]|ent->weak_pawns);
		while(movers) {				
			sq = ExtractFirstBit(movers);
			if(!(BISHOP_ATT(sq) & Line[ qsq[colour] ][sq] & piece[BISHOP] & Occupied(colour^1) & ~piece_mob[colour]))	sq = a1;
		} 
		movers = queen_mob[colour] & (rook_mob[colour^1]) & Occupied(colour) & (piece[BISHOP]|piece[KNIGHT]);
		while(movers) {			
			sq = ExtractFirstBit(movers);
			if(!(ROOK_ATT(sq) & Line[ qsq[colour] ][sq] & piece[ROOK] & Occupied(colour^1) & ~piece_mob[colour]))		sq = a1;
		} if(sq != a1) {
			if((piece_mob[colour] & ~queen_mob[colour]) & BIT(sq)) {	GSI(colour, PINNED_QUEEN);
			} else {													GSI(colour, UNDEFENDED_PINNED_QUEEN);}
		}	
		// x-ray
		mob = (queen_mob[colour]|QUEEN_ATT(ksq[colour]));
		movers = mob & (bishop_mob[colour^1]|rook_mob[colour^1]) & Occupied(colour^1) & ~(piece[PAWN]|piece[QUEEN]|piece[KING]|pawn_mob[colour]);
		while(movers) {			
			sq = ExtractFirstBit(movers);
			if(QUEEN_ATT(sq) & BIT(ksq[colour])) {
				if(((BISHOP_ATT(sq) & Line[ksq[colour]][sq] & (piece[BISHOP]|piece[QUEEN]) & Occupied(colour^1) & ~piece_mob[colour]) && type[sq] != BISHOP)
				|| ((ROOK_ATT(sq) & Line[ksq[colour]][sq] & (piece[ROOK]|piece[QUEEN]) & Occupied(colour^1) & ~piece_mob[colour]) && type[sq] != ROOK)) {
					GSI(colour, X_RAY_KING);
				}
			} if(QUEEN_ATT(sq) & BIT(qsq[colour])) {
				if(((BISHOP_ATT(sq) & Line[qsq[colour]][sq] & piece[BISHOP] & Occupied(colour^1) & piece_mob[colour^1] & ~piece_mob[colour]) && type[sq] != BISHOP)
				|| ((ROOK_ATT(sq) & Line[qsq[colour]][sq] & (piece[ROOK]) & Occupied(colour^1) & piece_mob[colour^1] & ~piece_mob[colour]) && type[sq] != ROOK)) {
					GSI(colour, X_RAY_QUEEN);
				}
			}
		}
	}	

	// patterns
	BitBoard wn = piece[KNIGHT] & White(),	bn = piece[KNIGHT] & Black(),
		wb = piece[BISHOP] & White(),	bb = piece[BISHOP] & Black(),
		wr = piece[ROOK] & White(),	br = piece[ROOK] & Black(),
		wp = piece[PAWN] & White(),	bp = piece[PAWN] & Black(),
		wk = piece[KING] & White(),	bk = piece[KING] & Black();
	// trapped bishop 7th rank
	if(((wb & A7) && (bp & B6))	|| ((wb & B8) && (bp & C7)))	GSI(WHITE, TRAPPED_PENALTY_1)
	if(((wb & H7) && (bp & G6))	|| ((wb & G8) && (bp & F7)))	GSI(WHITE, TRAPPED_PENALTY_1)
	if(((bb & A2) && (wp & B3))	|| ((bb & B1) && (wp & C2)))	GSI(BLACK, TRAPPED_PENALTY_1)
	if(((bb & H2) && (wp & G3))	|| ((bb & G1) && (wp & F2)))	GSI(BLACK, TRAPPED_PENALTY_1)
	// trapped bishop 6th rank
	if(((wb & A6) && (bp & B5)) || ((wb & H6) && (bp & G5)))	GSI(WHITE, TRAPPED_PENALTY_2)
	if(((bb & A3) && (wp & B4)) || ((bb & H3) && (wp & G4)))	GSI(BLACK, TRAPPED_PENALTY_2)
	// blocked rook
	if(((wk & (C1|B1)) && (wr & (A1|A2|B1))) || ((wk & (F1|G1)) && (wr & (H1|H2|G1))))		OSI(WHITE, BLOCKED_PENALTY);
	if(((bk & (C8|B8)) && (br & (A8|A7|B8))) || ((bk & (F8|G8)) && (br & (H8|H7|G8))))		OSI(BLACK, BLOCKED_PENALTY);

	// pawn storms (opposite side castling)
	if((phase <= PHASE_NB * 10/24)
	&& (KingWing[ksq[WHITE]] != KingWing[ksq[BLACK]])
	&& !castle && shelter_flag[WHITE] && shelter_flag[BLACK]) {
		BitBoard wsh, bsh, wdh, bdh, wss, bss, wds, bds; // [white/black][single/double][hook/storm]
		// white		
		wss = ((BIT_UP(wp) & ~occupied) | wp) & piece_mob[WHITE];		
		wds = ((BIT_UP(wp) & ~occupied) | wp) & pawn_mob[WHITE];		
		movers = wp & BIT_DOWN(occupied);
		wsh = BIT_UP_LEFT(movers) | BIT_UP_RIGHT(movers);
		movers = Occupied(WHITE);
		wdh = BIT_UP_LEFT(movers) & BIT_UP_RIGHT(movers);
		// black						
		bss = ((BIT_DOWN(bp) & ~occupied) | bp) & piece_mob[BLACK];		
		bds = ((BIT_DOWN(bp) & ~occupied) | bp) & pawn_mob[BLACK];		
		movers = bp & BIT_UP(occupied);
		bsh = BIT_DOWN_LEFT(movers) | BIT_DOWN_RIGHT(movers);
		movers = Occupied(BLACK);
		bdh = BIT_DOWN_LEFT(movers) & BIT_DOWN_RIGHT(movers);
		// calculate
		if(wds & bdh & WingBB[KingWing[ksq[BLACK]]] & EnemySide[WHITE]) {					OSI(WHITE, OP_DOUBLE_STORM_BONUS);
		} else if((wds|wss) & bsh & WingBB[KingWing[ksq[BLACK]]] & EnemySide[WHITE]) {		OSI(WHITE, OP_SINGLE_STORM_BONUS);
		} // black
		if(bds & wdh & WingBB[KingWing[ksq[WHITE]]] & EnemySide[BLACK]) {					OSI(BLACK, OP_DOUBLE_STORM_BONUS);
		} else if((bds|bss) & wsh & WingBB[KingWing[ksq[WHITE]]] & EnemySide[BLACK]) {		OSI(BLACK, OP_SINGLE_STORM_BONUS);
		}
		// all storm pawns blocked		
		mob_tmp = (bn|bb) & ((pawn_mob[BLACK] & ~piece_mob[WHITE]) | (BIT_DOWN_LEFT(bp)|BIT_DOWN_RIGHT(bp))); // outpost blockers
		mob = BIT_DOWN(bp|mob_tmp) | BIT_TWO_DOWN(bp);
		movers = wp & WingBB[KingWing[ksq[BLACK]]];
		if(movers && ((mob & movers) == movers)
		&& !(pawn_mob[WHITE] & (bp|mob_tmp) & WingBB[KingWing[ksq[BLACK]]])) 			
			OSIC(WHITE, OP_BLOCKED_STORM_PENALTY, CountFirstBits(movers));
		// black
		mob_tmp = (wn|wb) & ((pawn_mob[WHITE] & ~piece_mob[BLACK]) | (BIT_UP_LEFT(wp)|BIT_UP_RIGHT(wp))); // outpost blockers
		mob = BIT_UP(wp|mob_tmp) | BIT_TWO_UP(wp);
		movers = bp & WingBB[KingWing[ksq[WHITE]]];
		if(movers && ((mob & movers) == movers)
		&& !(pawn_mob[BLACK] & (wp|mob_tmp) & WingBB[KingWing[ksq[WHITE]]])) 			
			OSIC(BLACK, OP_BLOCKED_STORM_PENALTY, CountFirstBits(movers));
	}
				
	// finish
	res += ((phase * endgame + (PHASE_NB - phase) * opening) / PHASE_NB);	
	opening = saved_op;	   endgame = saved_eg;	
	if(mat_draw)	return ev_info->value = 0;
	return ev_info->value = res * sign[stm];	
}