+#define ENABLE_SAFE_OPERATORS_ON(T) \
+inline T operator+(const T d1, const T d2) { return T(int(d1) + int(d2)); } \
+inline T operator-(const T d1, const T d2) { return T(int(d1) - int(d2)); } \
+inline T operator*(int i, const T d) { return T(i * int(d)); } \
+inline T operator*(const T d, int i) { return T(int(d) * i); } \
+inline T operator-(const T d) { return T(-int(d)); } \
+inline T& operator+=(T& d1, const T d2) { d1 = d1 + d2; return d1; } \
+inline T& operator-=(T& d1, const T d2) { d1 = d1 - d2; return d1; } \
+inline T& operator*=(T& d, int i) { d = T(int(d) * i); return d; }
+
+#define ENABLE_OPERATORS_ON(T) ENABLE_SAFE_OPERATORS_ON(T) \
+inline T operator++(T& d, int) { d = T(int(d) + 1); return d; } \
+inline T operator--(T& d, int) { d = T(int(d) - 1); return d; } \
+inline T operator/(const T d, int i) { return T(int(d) / i); } \
+inline T& operator/=(T& d, int i) { d = T(int(d) / i); return d; }
+
+ENABLE_OPERATORS_ON(Value)
+ENABLE_OPERATORS_ON(PieceType)
+ENABLE_OPERATORS_ON(Piece)
+ENABLE_OPERATORS_ON(Color)
+ENABLE_OPERATORS_ON(Depth)
+ENABLE_OPERATORS_ON(Square)
+ENABLE_OPERATORS_ON(File)
+ENABLE_OPERATORS_ON(Rank)
+
+/// Added operators for adding integers to a Value
+inline Value operator+(Value v, int i) { return Value(int(v) + i); }
+inline Value operator-(Value v, int i) { return Value(int(v) - i); }
+
+ENABLE_SAFE_OPERATORS_ON(Score)
+
+/// Only declared but not defined. We don't want to multiply two scores due to
+/// a very high risk of overflow. So user should explicitly convert to integer.
+inline Score operator*(Score s1, Score s2);
+
+/// Division of a Score must be handled separately for each term
+inline Score operator/(Score s, int i) {
+ return make_score(mg_value(s) / i, eg_value(s) / i);
+}
+
+/// Weight score v by score w trying to prevent overflow
+inline Score apply_weight(Score v, Score w) {
+ return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
+ (int(eg_value(v)) * eg_value(w)) / 0x100);
+}
+
+#undef ENABLE_OPERATORS_ON
+#undef ENABLE_SAFE_OPERATORS_ON
+
+namespace Zobrist {
+
+ extern Key psq[2][8][64]; // [color][pieceType][square / piece count]
+ extern Key enpassant[8]; // [file]
+ extern Key castle[16]; // [castleRight]
+ extern Key side;
+ extern Key exclusion;
+
+ void init();
+}
+
+CACHE_LINE_ALIGNMENT
+
+extern Score pieceSquareTable[16][64]; // [piece][square]
+extern Value PieceValue[2][18]; // [Mg / Eg][piece / pieceType]
+extern int SquareDistance[64][64]; // [square][square]
+
+struct MoveStack {
+ Move move;
+ int score;
+};
+
+inline bool operator<(const MoveStack& f, const MoveStack& s) {
+ return f.score < s.score;
+}
+
+inline Color operator~(Color c) {
+ return Color(c ^ 1);
+}
+
+inline Square operator~(Square s) {
+ return Square(s ^ 56); // Vertical flip SQ_A1 -> SQ_A8
+}
+
+inline Square operator|(File f, Rank r) {
+ return Square((r << 3) | f);
+}
+
+inline Value mate_in(int ply) {
+ return VALUE_MATE - ply;
+}
+
+inline Value mated_in(int ply) {
+ return -VALUE_MATE + ply;
+}
+
+inline Piece make_piece(Color c, PieceType pt) {
+ return Piece((c << 3) | pt);
+}
+
+inline CastleRight make_castle_right(Color c, CastlingSide s) {
+ return CastleRight(WHITE_OO << ((s == QUEEN_SIDE) + 2 * c));
+}
+
+inline PieceType type_of(Piece p) {
+ return PieceType(p & 7);
+}
+
+inline Color color_of(Piece p) {
+ return Color(p >> 3);
+}
+
+inline bool is_ok(Square s) {
+ return s >= SQ_A1 && s <= SQ_H8;
+}
+
+inline File file_of(Square s) {
+ return File(s & 7);
+}
+
+inline Rank rank_of(Square s) {
+ return Rank(s >> 3);
+}
+
+inline Square mirror(Square s) {
+ return Square(s ^ 7); // Horizontal flip SQ_A1 -> SQ_H1
+}
+
+inline Square relative_square(Color c, Square s) {
+ return Square(s ^ (c * 56));
+}
+
+inline Rank relative_rank(Color c, Rank r) {
+ return Rank(r ^ (c * 7));
+}
+
+inline Rank relative_rank(Color c, Square s) {
+ return relative_rank(c, rank_of(s));
+}
+
+inline bool opposite_colors(Square s1, Square s2) {
+ int s = int(s1) ^ int(s2);
+ return ((s >> 3) ^ s) & 1;
+}
+
+inline int file_distance(Square s1, Square s2) {
+ return abs(file_of(s1) - file_of(s2));
+}
+
+inline int rank_distance(Square s1, Square s2) {
+ return abs(rank_of(s1) - rank_of(s2));
+}
+
+inline int square_distance(Square s1, Square s2) {
+ return SquareDistance[s1][s2];
+}
+
+inline char file_to_char(File f) {
+ return char(f - FILE_A + int('a'));
+}
+
+inline char rank_to_char(Rank r) {
+ return char(r - RANK_1 + int('1'));
+}
+
+inline Square pawn_push(Color c) {
+ return c == WHITE ? DELTA_N : DELTA_S;
+}
+
+inline Square from_sq(Move m) {
+ return Square((m >> 6) & 0x3F);
+}
+
+inline Square to_sq(Move m) {
+ return Square(m & 0x3F);
+}
+
+inline MoveType type_of(Move m) {
+ return MoveType(m & (3 << 14));
+}
+
+inline PieceType promotion_type(Move m) {
+ return PieceType(((m >> 12) & 3) + 2);
+}
+
+inline Move make_move(Square from, Square to) {
+ return Move(to | (from << 6));
+}
+
+template<MoveType T>
+inline Move make(Square from, Square to, PieceType pt = KNIGHT) {
+ return Move(to | (from << 6) | T | ((pt - KNIGHT) << 12)) ;
+}
+
+inline bool is_ok(Move m) {
+ return from_sq(m) != to_sq(m); // Catches also MOVE_NULL and MOVE_NONE
+}
+
+#include <string>
+
+inline const std::string square_to_string(Square s) {
+ char ch[] = { file_to_char(file_of(s)), rank_to_char(rank_of(s)), 0 };
+ return ch;
+}
+
+/// Our insertion sort implementation, works with pointers and iterators and is
+/// guaranteed to be stable, as is needed.
+template<typename T, typename K>
+void sort(K first, K last)
+{
+ T tmp;
+ K p, q;
+
+ for (p = first + 1; p < last; p++)
+ {
+ tmp = *p;
+ for (q = p; q != first && *(q-1) < tmp; --q)
+ *q = *(q-1);
+ *q = tmp;
+ }
+}
+