void Init() {
	
	int i, f, r, k, s, colour;
	BitBoard bit;
		
	memset(Line, 0, sizeof(Line));	
	memset(RookR0, 0, sizeof(RookR0));
	memset(WingBB, 0, sizeof(WingBB));
	memset(Between, 0, sizeof(Between));
	memset(RookRL90, 0, sizeof(RookRL90));	
	memset(KingWing, 0, sizeof(KingWing));
	memset(BehindKing, 0, sizeof(BehindKing));
	memset(BishopRL45, 0, sizeof(BishopRL45));
	memset(BishopRR45, 0, sizeof(BishopRR45));
				
	for (i = 0, bit = 1; i < 64; i++) 		BitMask[i] = bit << i;	
	for (i = 0; i < 64; i++) {
		BitMaskL90[i] = BIT(ROTATE_LEFT_90(i));
		BitMaskL45[i] = BIT(ROTATE_LEFT_45(i));
		BitMaskR45[i] = BIT(ROTATE_RIGHT_45(i));

		ShiftRL45[i] = SHIFT_LEFT_45(i);
		RotateL45[i] = ROTATE_LEFT_45(i);
		RotateR45[i] = ROTATE_RIGHT_45(i);		
		ShiftRR45[i] = SHIFT_RIGHT_45(i);

		RankMirror[i] = RANK_MIRROR_INIT(i);
		CastleMask[i] = 255;
				
	} for(i = 0; i < 64; i++) {		
		bit = BIT(i);
		// Pieces:
		// kings		
		King[i]  = BIT_UP(bit);
		King[i] |= BIT_LEFT(bit);
		King[i] |= BIT_DOWN(bit);
		King[i] |= BIT_RIGHT(bit);
		King[i] |= BIT_UP_LEFT(bit);
		King[i] |= BIT_UP_RIGHT(bit);
		King[i] |= BIT_DOWN_LEFT(bit);
		King[i] |= BIT_DOWN_RIGHT(bit);

		// pawns
		Pawn[WHITE][i] = BIT_UP_LEFT(bit);
		Pawn[WHITE][i]|= BIT_UP_RIGHT(bit);		
		Pawn[BLACK][i] = BIT_DOWN_LEFT(bit);
		Pawn[BLACK][i]|= BIT_DOWN_RIGHT(bit);

		// knights
		Knight[i]  = BIT_LEFT(BIT_TWO_UP(bit));
		Knight[i] |= BIT_RIGHT(BIT_TWO_UP(bit));
		Knight[i] |= BIT_LEFT(BIT_TWO_DOWN(bit));
		Knight[i] |= BIT_RIGHT(BIT_TWO_DOWN(bit));
		Knight[i] |= BIT_TWO_RIGHT(BIT_DOWN(bit));
		Knight[i] |= BIT_TWO_LEFT(BIT_DOWN(bit));
		Knight[i] |= BIT_TWO_RIGHT(BIT_UP(bit));
		Knight[i] |= BIT_TWO_LEFT(BIT_UP(bit));

		// bishops
		for(k = 0; k < 64; k++) {
			for(s = i-7; File(s+7) < 7 && Rank(s+7) > 0; s -= 7) {				
				BishopRL45[i][k] |= BIT(s);
				if(k & (BIT(RotateL45[s])>>ShiftRL45[i]))break;
			} for(s = i+7; File(s-7)>0 && Rank(s-7)<7; s += 7) {				
				BishopRL45[i][k] |= BIT(s);
				if(k & (BIT(RotateL45[s])>>ShiftRL45[i]))break;
			} for(s = i-9; File(s+9) > 0 && Rank(s+9) > 0; s -= 9) {				
				BishopRR45[i][k] |= BIT(s);
				if(k & (BIT(RotateR45[s])>>ShiftRR45[i]))break;
			} for(s = i+9; File(s-9) < 7 && Rank(s-9) < 7; s += 9) {				
				BishopRR45[i][k] |= BIT(s);
				if(k & (BIT(RotateR45[s])>>ShiftRR45[i]))break;
			}			
		}
		// rooks
		for(k = 0; k < 64; k++) {
			for(f = File(i) - 1, s = i - 1; f >= 0; s--, f--) {
				RookR0[i][k] |= BIT(s);
				if((k<<1)&(1<<f))	 break;
			} for(f = File(i) + 1, s = i + 1; f < 8; s++, f++) {
				RookR0[i][k] |= BIT(s);
				if((k<<1)&(1<<f))	 break;
			} for(r = Rank(i) - 1, s = i - 8; r >= 0; s -= 8, r--) {
				RookRL90[i][k] |= BIT(s);
				if((k<<1)&(1<<(7-r)))break;
			} for(r = Rank(i) + 1, s = i + 8; r < 8; s += 8, r++) {
				RookRL90[i][k] |= BIT(s);
				if((k<<1)&(1<<(7-r)))break;
			} 			
		}

		// Pseudo
		BishopPseudo[i] = ATT_R45(i, 0) | ATT_L45(i, 0);
		RookPseudo[i]   = ATT_RANK(i, 0)| ATT_FILE(i, 0);
		QueenPseudo[i]  = BishopPseudo[i] | RookPseudo[i];

		// Anti...Pawns
		for(colour = WHITE; colour <= BLACK; colour++) {
			AntiOutpostPawns[colour][i] = FRONT_RANKS(colour, i) & CONTACT_FILES_BB(i);	
			AntiPassedPawns[colour][i]  = FRONT_RANKS(colour, i) & (CONTACT_FILES_BB(i) | FILE_BB(i));
		}	
		
		// pawn mask
		IsolatedPawnMask[i] = CONTACT_FILES_BB(i);
		DoubledPawnMask[WHITE][i] = FILE_BB(i) & FRONT_RANKS(BLACK, i);
		DoubledPawnMask[BLACK][i] = FILE_BB(i) & FRONT_RANKS(WHITE, i);
		HalfOpenFileMask[WHITE][i] = FILE_BB(i) & FRONT_RANKS(WHITE, i);
		HalfOpenFileMask[BLACK][i] = FILE_BB(i) & FRONT_RANKS(BLACK, i);
		ChainPawnMask[WHITE][i] = (CONTACT_FILES_BB(i) & (RANK_BB(i))) | Pawn[BLACK][i];
		ChainPawnMask[BLACK][i] = (CONTACT_FILES_BB(i) & (RANK_BB(i))) | Pawn[WHITE][i];
		ProtectedPawnMask[WHITE][i] = CONTACT_FILES_BB(i) & ~(FRONT_RANKS(WHITE, i) | RANK_BB(i));
		ProtectedPawnMask[BLACK][i] = CONTACT_FILES_BB(i) & ~(FRONT_RANKS(BLACK, i) | RANK_BB(i));
		CandidatePawnMask[WHITE][i] = CONTACT_FILES_BB(i) & ~FRONT_RANKS(WHITE, i);
		CandidatePawnMask[BLACK][i] = CONTACT_FILES_BB(i) & ~FRONT_RANKS(BLACK, i);
		CandidateOppPawnMask[WHITE][i] = CONTACT_FILES_BB(i) & FRONT_RANKS(WHITE, i);
		CandidateOppPawnMask[BLACK][i] = CONTACT_FILES_BB(i) & FRONT_RANKS(BLACK, i);
		LCandidatePawnMask[WHITE][i] = L_CONTACT_FILES_BB(i) & ~FRONT_RANKS(WHITE, i);
		LCandidatePawnMask[BLACK][i] = L_CONTACT_FILES_BB(i) & ~FRONT_RANKS(BLACK, i);
		RCandidatePawnMask[WHITE][i] = R_CONTACT_FILES_BB(i) & ~FRONT_RANKS(WHITE, i);
		RCandidatePawnMask[BLACK][i] = R_CONTACT_FILES_BB(i) & ~FRONT_RANKS(BLACK, i);
		LCandidateOppPawnMask[WHITE][i] = L_CONTACT_FILES_BB(i) & FRONT_RANKS(WHITE, i);
		LCandidateOppPawnMask[BLACK][i] = L_CONTACT_FILES_BB(i) & FRONT_RANKS(BLACK, i);
		RCandidateOppPawnMask[WHITE][i] = R_CONTACT_FILES_BB(i) & FRONT_RANKS(WHITE, i);
		RCandidateOppPawnMask[BLACK][i] = R_CONTACT_FILES_BB(i) & FRONT_RANKS(BLACK, i);
		BackwardPawnMask1[WHITE][i] = BIT_TWO_UP(BIT_LEFT(bit)) | BIT_TWO_UP(BIT_RIGHT(bit));
		BackwardPawnMask1[BLACK][i] = BIT_TWO_DOWN(BIT_LEFT(bit)) | BIT_TWO_DOWN(BIT_RIGHT(bit));
		BackwardPawnMask2[WHITE][i] = BIT_TWO_UP(BIT_UP_LEFT(bit)) | BIT_TWO_UP(BIT_UP_RIGHT(bit));
		BackwardPawnMask2[BLACK][i] = BIT_TWO_DOWN(BIT_DOWN_LEFT(bit)) | BIT_TWO_DOWN(BIT_DOWN_RIGHT(bit));
		UnstoppablePassed[WHITE][i] = UnstoppablePassed[BLACK][i] = KingAssist[WHITE][i] = KingAssist[BLACK][i] = 0;
		PassedPair[WHITE][i] = PassedPair[BLACK][i] = 0;
	
		// wing
		if(File(i) <= FILE_C)	KingWing[i] = QUEENSIDE;
		else if(File(i) <= FILE_E)	KingWing[i] = CENTER;
		else if(File(i) <= FILE_H)	KingWing[i] = KINGSIDE;		
		WingBB[	KingWing[i] ] |= bit;
	}
	// CharBitsCount & CharFirstBit
	for(i = 0; i < 256; i++) {
		CharBitsCount[i] = CountBits((BitBoard)i);
		CharFirstBit[i] = FindFirstBit((BitBoard)i);
	}
	// Between , Line and BehindKing
	for(i = 0; i < 64; i++) {
		for(k = 0; k < 64; k++) {
			if(ROOK_ATT_PSEUDO(i) & BIT(k)) {	
				Line[i][k] = (ROOK_ATT_PSEUDO(i) & ROOK_ATT_PSEUDO(k)) | BIT(i) | BIT(k);
				Between[i][k] = ROOK_ATT_MODEL(i,BitMask[k],BitMaskL90[k]) & ROOK_ATT_MODEL(k,BitMask[i],BitMaskL90[i]);				
				BehindKing[i][k] = King[i] & ROOK_ATT_PSEUDO(i) & ROOK_ATT_PSEUDO(k) & (~Between[i][k]);				
			} else if(BISHOP_ATT_PSEUDO(i) & BIT(k)) {
				Line[i][k] = (BISHOP_ATT_PSEUDO(i) & BISHOP_ATT_PSEUDO(k)) | BIT(i) | BIT(k);
				Between[i][k] = BISHOP_ATT_MODEL(i,BitMaskR45[k],BitMaskL45[k]) & BISHOP_ATT_MODEL(k,BitMaskR45[i],BitMaskL45[i]);				
				BehindKing[i][k] = King[i] & BISHOP_ATT_PSEUDO(i) & BISHOP_ATT_PSEUDO(k) & (~Between[i][k]);				
			}	
			if(false && QUEEN_ATT_PSEUDO(i) & BIT(k)) {
				PrintBitBoard(stdout, BIT(i));
				PrintBitBoard(stdout, BIT(k));
				PrintBitBoard(stdout, Between[i][k]);
				printf("\n\n");
			}

			// Unstoppable passed pawns
			// +1 for tempo	, remember about moves like a2-a4			
			if(SQUARE_DIST(k, SQUARE_MAKE(File(i), RANK_8)) > MIN( RANK_COL(i, BLACK),RANK_6 )+1)	UnstoppablePassed[WHITE][i] |= BIT(k); 
			if(SQUARE_DIST(k, SQUARE_MAKE(File(i), RANK_1)) > MIN( RANK_COL(i, WHITE),RANK_6 )+1)	UnstoppablePassed[BLACK][i] |= BIT(k);

			if(CountBits(KING_ATT(k) & FILE_BB(i) & FRONT_RANKS(WHITE, i)) == RANK_COL(i, BLACK))	KingAssist[WHITE][i] |= BIT(k);
			if(CountBits(KING_ATT(k) & FILE_BB(i) & FRONT_RANKS(BLACK, i)) == RANK_COL(i, WHITE))	KingAssist[BLACK][i] |= BIT(k);

			// Passed pair
			if(RANK_COL(i, WHITE) <= RANK_COL(k, WHITE)
			&& File(k) - File(i) >= 7 - RANK_COL(i, WHITE))			PassedPair[WHITE][i] |= BIT(k);
			if(RANK_COL(i, BLACK) <= RANK_COL(k, BLACK)
			&& File(k) - File(i) >= 7 - RANK_COL(i, BLACK))			PassedPair[BLACK][i] |= BIT(k);
		}

		// KingZone		
		// White
		bit = King[i] ^ Pawn[WHITE][i];
		while(bit) {
			s = ExtractFirstBit(bit);
			KingZone[WHITE][i] |= King[s];
		}
		// Black
		bit = King[i] ^ Pawn[BLACK][i];
		while(bit) {
			s = ExtractFirstBit(bit);
			KingZone[BLACK][i] |= King[s];
		}
	}

	CastleMask[a1] = 251; //~4;
	CastleMask[h1] = 254; //~1;
	CastleMask[a8] = 247; //~8;
	CastleMask[h8] = 253; //~2;
	CastleMask[e1] = 250; //~(4+1);
	CastleMask[e8] = 245; //~(8+2);	

	for(i = 0; i < 16; i++) {
		CastleHashKey[i] = 0;
		 for(k = 0; k < 4; k++) {
			if((k & (1<<k)) != 0) 
				CastleHashKey[i] ^= CASTLE_HASH_KEY(k);
		 }
	}
}