/// unsuccessful during the current search, and is used for reduction and move
/// ordering decisions. It uses 2 tables (one for each color) indexed by
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
-typedef Stats<int16_t, 10692, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)> ButterflyHistory;
+typedef Stats<int16_t, 10692, COLOR_NB, int(SQUARE_NB + 1) * int(1 << SQUARE_BITS)> ButterflyHistory;
- /// LowPlyHistory at higher depths records successful quiet moves on plies 0 to 3
- /// and quiet moves which are/were in the PV (ttPv)
- /// It get cleared with each new search and get filled during iterative deepening
+ /// At higher depths LowPlyHistory records successful quiet moves near the root and quiet
+ /// moves which are/were in the PV (ttPv)
+ /// It is cleared with each new search and filled during iterative deepening
constexpr int MAX_LPH = 4;
-typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB) * int(SQUARE_NB)> LowPlyHistory;
+typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB + 1) * int(1 << SQUARE_BITS)> LowPlyHistory;
/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
/// move, see www.chessprogramming.org/Countermove_Heuristic
if ( opposed
&& (ourPawns & forward_file_bb(Them, s))
&& !(theirPawns & adjacent_files_bb(s)))
- score -= Doubled;
+ score -= Doubled * (1 + 2 * pos.must_capture());
else
- score -= Isolated * (1 + 2 * pos.must_capture())
- + WeakUnopposed * !opposed;
- score -= Isolated
++ score -= Isolated * (1 + 2 * pos.must_capture())
+ + WeakUnopposed * !opposed;
}
else if (backward)
- score -= Backward
- + WeakUnopposed * !opposed;
+ score -= Backward
+ + WeakUnopposed * !opposed;
if (!support)
- score -= Doubled * doubled
- + WeakLever * more_than_one(lever);
+ score -= Doubled * doubled
+ + WeakLever * more_than_one(lever);
}
+ // Double pawn evaluation if there are no non-pawn pieces
+ if (pos.count<ALL_PIECES>(Us) == pos.count<PAWN>(Us))
+ score = score * 2;
+
+ const Square* pl_shogi = pos.squares<SHOGI_PAWN>(Us);
+
+ ourPawns = pos.pieces(Us, SHOGI_PAWN);
+ theirPawns = pos.pieces(Them, SHOGI_PAWN);
+
+ // Loop through all shogi pawns of the current color and score each one
+ while ((s = *pl_shogi++) != SQ_NONE)
+ {
+ assert(pos.piece_on(s) == make_piece(Us, SHOGI_PAWN));
+
+ neighbours = ourPawns & adjacent_files_bb(s);
+
+ if (!neighbours)
+ score -= Isolated / 2;
+ }
+
return score;
}
return Value(mg.s);
}
+#define ENABLE_BIT_OPERATORS_ON(T) \
+inline T operator~ (T d) { return (T)~(int)d; } \
+inline T operator| (T d1, T d2) { return (T)((int)d1 | (int)d2); } \
+inline T operator& (T d1, T d2) { return (T)((int)d1 & (int)d2); } \
+inline T operator^ (T d1, T d2) { return (T)((int)d1 ^ (int)d2); } \
+inline T& operator|= (T& d1, T d2) { return (T&)((int&)d1 |= (int)d2); } \
+inline T& operator&= (T& d1, T d2) { return (T&)((int&)d1 &= (int)d2); } \
+inline T& operator^= (T& d1, T d2) { return (T&)((int&)d1 ^= (int)d2); }
+
#define ENABLE_BASE_OPERATORS_ON(T) \
- constexpr T operator+(T d1, T d2) { return T(int(d1) + int(d2)); } \
- constexpr T operator-(T d1, T d2) { return T(int(d1) - int(d2)); } \
+ constexpr T operator+(T d1, int d2) { return T(int(d1) + d2); } \
+ constexpr T operator-(T d1, int d2) { return T(int(d1) - d2); } \
constexpr T operator-(T d) { return T(-int(d)); } \
- inline T& operator+=(T& d1, T d2) { return d1 = d1 + d2; } \
- inline T& operator-=(T& d1, T d2) { return d1 = d1 - d2; }
+ inline T& operator+=(T& d1, int d2) { return d1 = d1 + d2; } \
+ inline T& operator-=(T& d1, int d2) { return d1 = d1 - d2; }
#define ENABLE_INCR_OPERATORS_ON(T) \
inline T& operator++(T& d) { return d = T(int(d) + 1); } \
#undef ENABLE_FULL_OPERATORS_ON
#undef ENABLE_INCR_OPERATORS_ON
#undef ENABLE_BASE_OPERATORS_ON
+#undef ENABLE_BIT_OPERATORS_ON
- /// Additional operators to add integers to a Value
- constexpr Value operator+(Value v, int i) { return Value(int(v) + i); }
- constexpr Value operator-(Value v, int i) { return Value(int(v) - i); }
- inline Value& operator+=(Value& v, int i) { return v = v + i; }
- inline Value& operator-=(Value& v, int i) { return v = v - i; }
-
/// Additional operators to add a Direction to a Square
constexpr Square operator+(Square s, Direction d) { return Square(int(s) + int(d)); }
constexpr Square operator-(Square s, Direction d) { return Square(int(s) - int(d)); }
}
template<MoveType T>
-constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
- return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
+constexpr Move make_gating(Square from, Square to, PieceType pt, Square gate) {
+ return Move((gate << (2 * SQUARE_BITS + MOVE_TYPE_BITS + PIECE_TYPE_BITS)) + (pt << (2 * SQUARE_BITS + MOVE_TYPE_BITS)) + T + (from << SQUARE_BITS) + to);
+}
+
+constexpr PieceType dropped_piece_type(Move m) {
+ return PieceType((m >> (2 * SQUARE_BITS + MOVE_TYPE_BITS)) & (PIECE_TYPE_NB - 1));
+}
+
+constexpr PieceType in_hand_piece_type(Move m) {
+ return PieceType((m >> (2 * SQUARE_BITS + MOVE_TYPE_BITS + PIECE_TYPE_BITS)) & (PIECE_TYPE_NB - 1));
+}
+
+inline bool is_ok(Move m) {
+ return from_sq(m) != to_sq(m) || type_of(m) == PROMOTION || type_of(m) == SPECIAL; // Catch MOVE_NULL and MOVE_NONE
}
-constexpr bool is_ok(Move m) {
- return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
+inline int dist(Direction d) {
- return std::abs(d % NORTH) < NORTH / 2 ? std::max(std::abs(d / NORTH), std::abs(d % NORTH))
- : std::max(std::abs(d / NORTH) + 1, NORTH - std::abs(d % NORTH));
++ return std::abs(d % NORTH) < NORTH / 2 ? std::max(std::abs(d / NORTH), int(std::abs(d % NORTH)))
++ : std::max(std::abs(d / NORTH) + 1, int(NORTH - std::abs(d % NORTH)));
}
#endif // #ifndef TYPES_H_INCLUDED