Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 154 Rev 169
Line 4... Line 4...
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
5
  Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
5
  Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
6
 
6
 
7
  Stockfish is free software: you can redistribute it and/or modify
7
  Stockfish is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
10
  (at your option) any later version.
Line 74... Line 74...
74
 
74
 
75
#if defined(USE_PEXT)
75
#if defined(USE_PEXT)
76
#  include <immintrin.h> // Header for _pext_u64() intrinsic
76
#  include <immintrin.h> // Header for _pext_u64() intrinsic
77
#  define pext(b, m) _pext_u64(b, m)
77
#  define pext(b, m) _pext_u64(b, m)
78
#else
78
#else
79
#  define pext(b, m) (0)
79
#  define pext(b, m) 0
80
#endif
80
#endif
81
 
81
 
82
#ifdef USE_POPCNT
82
#ifdef USE_POPCNT
83
const bool HasPopCnt = true;
83
const bool HasPopCnt = true;
84
#else
84
#else
Line 126... Line 126...
126
  ENPASSANT = 2 << 14,
126
  ENPASSANT = 2 << 14,
127
  CASTLING  = 3 << 14
127
  CASTLING  = 3 << 14
128
};
128
};
129
 
129
 
130
enum Color {
130
enum Color {
131
  WHITE, BLACK, NO_COLOR, COLOR_NB = 2
131
  WHITE, BLACK, COLOR_NB = 2
132
};
132
};
133
 
133
 
134
enum CastlingSide {
134
enum CastlingSide {
135
  KING_SIDE, QUEEN_SIDE, CASTLING_SIDE_NB = 2
135
  KING_SIDE, QUEEN_SIDE, CASTLING_SIDE_NB = 2
136
};
136
};
Line 144... Line 144...
144
  ANY_CASTLING = WHITE_OO | WHITE_OOO | BLACK_OO | BLACK_OOO,
144
  ANY_CASTLING = WHITE_OO | WHITE_OOO | BLACK_OO | BLACK_OOO,
145
  CASTLING_RIGHT_NB = 16
145
  CASTLING_RIGHT_NB = 16
146
};
146
};
147
 
147
 
148
template<Color C, CastlingSide S> struct MakeCastling {
148
template<Color C, CastlingSide S> struct MakeCastling {
149
  static const CastlingRight
149
  static constexpr CastlingRight
150
  right = C == WHITE ? S == QUEEN_SIDE ? WHITE_OOO : WHITE_OO
150
  right = C == WHITE ? S == QUEEN_SIDE ? WHITE_OOO : WHITE_OO
151
                     : S == QUEEN_SIDE ? BLACK_OOO : BLACK_OO;
151
                     : S == QUEEN_SIDE ? BLACK_OOO : BLACK_OO;
152
};
152
};
153
 
153
 
154
enum Phase {
154
enum Phase {
Line 181... Line 181...
181
  VALUE_NONE      = 32002,
181
  VALUE_NONE      = 32002,
182
 
182
 
183
  VALUE_MATE_IN_MAX_PLY  =  VALUE_MATE - 2 * MAX_PLY,
183
  VALUE_MATE_IN_MAX_PLY  =  VALUE_MATE - 2 * MAX_PLY,
184
  VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY,
184
  VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY,
185
 
185
 
186
  PawnValueMg   = 188,   PawnValueEg   = 248,
186
  PawnValueMg   = 171,   PawnValueEg   = 240,
187
  KnightValueMg = 753,   KnightValueEg = 832,
187
  KnightValueMg = 764,   KnightValueEg = 848,
188
  BishopValueMg = 826,   BishopValueEg = 897,
188
  BishopValueMg = 826,   BishopValueEg = 891,
189
  RookValueMg   = 1285,  RookValueEg   = 1371,
189
  RookValueMg   = 1282,  RookValueEg   = 1373,
190
  QueenValueMg  = 2513,  QueenValueEg  = 2650,
190
  QueenValueMg  = 2526,  QueenValueEg  = 2646,
191
 
191
 
192
  MidgameLimit  = 15258, EndgameLimit  = 3915
192
  MidgameLimit  = 15258, EndgameLimit  = 3915
193
};
193
};
194
 
194
 
195
enum PieceType {
195
enum PieceType {
196
  NO_PIECE_TYPE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING,
196
  NO_PIECE_TYPE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING,
197
  ALL_PIECES = 0,
197
  ALL_PIECES = 0,
-
 
198
  QUEEN_DIAGONAL = 7,
198
  PIECE_TYPE_NB = 8
199
  PIECE_TYPE_NB = 8
199
};
200
};
200
 
201
 
201
enum Piece {
202
enum Piece {
202
  NO_PIECE,
203
  NO_PIECE,
203
  W_PAWN = 1, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
204
  W_PAWN = 1, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
204
  B_PAWN = 9, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
205
  B_PAWN = 9, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
205
  PIECE_NB = 16
206
  PIECE_NB = 16
206
};
207
};
207
 
208
 
208
const Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
-
 
209
                         B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
-
 
210
extern Value PieceValue[PHASE_NB][PIECE_NB];
209
extern Value PieceValue[PHASE_NB][PIECE_NB];
211
 
210
 
212
enum Depth {
211
enum Depth : int {
213
 
212
 
214
  ONE_PLY = 1,
213
  ONE_PLY = 1,
215
 
214
 
216
  DEPTH_ZERO          =  0 * ONE_PLY,
215
  DEPTH_ZERO          =  0 * ONE_PLY,
217
  DEPTH_QS_CHECKS     =  0 * ONE_PLY,
216
  DEPTH_QS_CHECKS     =  0 * ONE_PLY,
Line 222... Line 221...
222
  DEPTH_MAX  = MAX_PLY * ONE_PLY
221
  DEPTH_MAX  = MAX_PLY * ONE_PLY
223
};
222
};
224
 
223
 
225
static_assert(!(ONE_PLY & (ONE_PLY - 1)), "ONE_PLY is not a power of 2");
224
static_assert(!(ONE_PLY & (ONE_PLY - 1)), "ONE_PLY is not a power of 2");
226
 
225
 
227
enum Square {
226
enum Square : int {
228
  SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1,
227
  SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1,
229
  SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2,
228
  SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2,
230
  SQ_A3, SQ_B3, SQ_C3, SQ_D3, SQ_E3, SQ_F3, SQ_G3, SQ_H3,
229
  SQ_A3, SQ_B3, SQ_C3, SQ_D3, SQ_E3, SQ_F3, SQ_G3, SQ_H3,
231
  SQ_A4, SQ_B4, SQ_C4, SQ_D4, SQ_E4, SQ_F4, SQ_G4, SQ_H4,
230
  SQ_A4, SQ_B4, SQ_C4, SQ_D4, SQ_E4, SQ_F4, SQ_G4, SQ_H4,
232
  SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_F5, SQ_G5, SQ_H5,
231
  SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_F5, SQ_G5, SQ_H5,
233
  SQ_A6, SQ_B6, SQ_C6, SQ_D6, SQ_E6, SQ_F6, SQ_G6, SQ_H6,
232
  SQ_A6, SQ_B6, SQ_C6, SQ_D6, SQ_E6, SQ_F6, SQ_G6, SQ_H6,
234
  SQ_A7, SQ_B7, SQ_C7, SQ_D7, SQ_E7, SQ_F7, SQ_G7, SQ_H7,
233
  SQ_A7, SQ_B7, SQ_C7, SQ_D7, SQ_E7, SQ_F7, SQ_G7, SQ_H7,
235
  SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8,
234
  SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8,
236
  SQ_NONE,
235
  SQ_NONE,
237
 
236
 
238
  SQUARE_NB = 64,
237
  SQUARE_NB = 64
-
 
238
};
239
 
239
 
-
 
240
enum Direction : int {
240
  NORTH =  8,
241
  NORTH =  8,
241
  EAST  =  1,
242
  EAST  =  1,
242
  SOUTH = -8,
243
  SOUTH = -NORTH,
243
  WEST  = -1,
244
  WEST  = -EAST,
244
 
245
 
245
  NORTH_EAST = NORTH + EAST,
246
  NORTH_EAST = NORTH + EAST,
246
  SOUTH_EAST = SOUTH + EAST,
247
  SOUTH_EAST = SOUTH + EAST,
247
  SOUTH_WEST = SOUTH + WEST,
248
  SOUTH_WEST = SOUTH + WEST,
248
  NORTH_WEST = NORTH + WEST
249
  NORTH_WEST = NORTH + WEST
Line 261... Line 262...
261
/// (enum). The least significant 16 bits are used to store the endgame value
262
/// (enum). The least significant 16 bits are used to store the endgame value
262
/// and the upper 16 bits are used to store the middlegame value. Take some
263
/// and the upper 16 bits are used to store the middlegame value. Take some
263
/// care to avoid left-shifting a signed int to avoid undefined behavior.
264
/// care to avoid left-shifting a signed int to avoid undefined behavior.
264
enum Score : int { SCORE_ZERO };
265
enum Score : int { SCORE_ZERO };
265
 
266
 
266
inline Score make_score(int mg, int eg) {
267
constexpr Score make_score(int mg, int eg) {
267
  return Score((int)((unsigned int)eg << 16) + mg);
268
  return Score((int)((unsigned int)eg << 16) + mg);
268
}
269
}
269
 
270
 
270
/// Extracting the signed lower and upper 16 bits is not so trivial because
271
/// Extracting the signed lower and upper 16 bits is not so trivial because
271
/// according to the standard a simple cast to short is implementation defined
272
/// according to the standard a simple cast to short is implementation defined
272
/// and so is a right shift of a signed integer.
273
/// and so is a right shift of a signed integer.
273
inline Value eg_value(Score s) {
274
inline Value eg_value(Score s) {
274
 
-
 
275
  union { uint16_t u; int16_t s; } eg = { uint16_t(unsigned(s + 0x8000) >> 16) };
275
  union { uint16_t u; int16_t s; } eg = { uint16_t(unsigned(s + 0x8000) >> 16) };
276
  return Value(eg.s);
276
  return Value(eg.s);
277
}
277
}
278
 
278
 
279
inline Value mg_value(Score s) {
279
inline Value mg_value(Score s) {
280
 
-
 
281
  union { uint16_t u; int16_t s; } mg = { uint16_t(unsigned(s)) };
280
  union { uint16_t u; int16_t s; } mg = { uint16_t(unsigned(s)) };
282
  return Value(mg.s);
281
  return Value(mg.s);
283
}
282
}
284
 
283
 
285
#define ENABLE_BASE_OPERATORS_ON(T)                             \
284
#define ENABLE_BASE_OPERATORS_ON(T)                                \
286
inline T operator+(T d1, T d2) { return T(int(d1) + int(d2)); } \
285
constexpr T operator+(T d1, T d2) { return T(int(d1) + int(d2)); } \
287
inline T operator-(T d1, T d2) { return T(int(d1) - int(d2)); } \
286
constexpr T operator-(T d1, T d2) { return T(int(d1) - int(d2)); } \
288
inline T operator*(int i, T d) { return T(i * int(d)); }        \
287
constexpr T operator-(T d) { return T(-int(d)); }                  \
289
inline T operator*(T d, int i) { return T(int(d) * i); }        \
288
inline T& operator+=(T& d1, T d2) { return d1 = d1 + d2; }         \
290
inline T operator-(T d) { return T(-int(d)); }                  \
289
inline T& operator-=(T& d1, T d2) { return d1 = d1 - d2; }
-
 
290
 
291
inline T& operator+=(T& d1, T d2) { return d1 = d1 + d2; }      \
291
#define ENABLE_INCR_OPERATORS_ON(T)                                \
292
inline T& operator-=(T& d1, T d2) { return d1 = d1 - d2; }      \
292
inline T& operator++(T& d) { return d = T(int(d) + 1); }           \
293
inline T& operator*=(T& d, int i) { return d = T(int(d) * i); }
293
inline T& operator--(T& d) { return d = T(int(d) - 1); }
294
 
294
 
295
#define ENABLE_FULL_OPERATORS_ON(T)                             \
295
#define ENABLE_FULL_OPERATORS_ON(T)                                \
296
ENABLE_BASE_OPERATORS_ON(T)                                     \
296
ENABLE_BASE_OPERATORS_ON(T)                                        \
-
 
297
ENABLE_INCR_OPERATORS_ON(T)                                        \
297
inline T& operator++(T& d) { return d = T(int(d) + 1); }        \
298
constexpr T operator*(int i, T d) { return T(i * int(d)); }        \
298
inline T& operator--(T& d) { return d = T(int(d) - 1); }        \
299
constexpr T operator*(T d, int i) { return T(int(d) * i); }        \
299
inline T operator/(T d, int i) { return T(int(d) / i); }        \
300
constexpr T operator/(T d, int i) { return T(int(d) / i); }        \
300
inline int operator/(T d1, T d2) { return int(d1) / int(d2); }  \
301
constexpr int operator/(T d1, T d2) { return int(d1) / int(d2); }  \
-
 
302
inline T& operator*=(T& d, int i) { return d = T(int(d) * i); }    \
301
inline T& operator/=(T& d, int i) { return d = T(int(d) / i); }
303
inline T& operator/=(T& d, int i) { return d = T(int(d) / i); }
302
 
304
 
303
ENABLE_FULL_OPERATORS_ON(Value)
305
ENABLE_FULL_OPERATORS_ON(Value)
304
ENABLE_FULL_OPERATORS_ON(PieceType)
-
 
305
ENABLE_FULL_OPERATORS_ON(Piece)
-
 
306
ENABLE_FULL_OPERATORS_ON(Color)
-
 
307
ENABLE_FULL_OPERATORS_ON(Depth)
306
ENABLE_FULL_OPERATORS_ON(Depth)
-
 
307
ENABLE_FULL_OPERATORS_ON(Direction)
-
 
308
 
-
 
309
ENABLE_INCR_OPERATORS_ON(PieceType)
-
 
310
ENABLE_INCR_OPERATORS_ON(Piece)
-
 
311
ENABLE_INCR_OPERATORS_ON(Color)
308
ENABLE_FULL_OPERATORS_ON(Square)
312
ENABLE_INCR_OPERATORS_ON(Square)
309
ENABLE_FULL_OPERATORS_ON(File)
313
ENABLE_INCR_OPERATORS_ON(File)
310
ENABLE_FULL_OPERATORS_ON(Rank)
314
ENABLE_INCR_OPERATORS_ON(Rank)
311
 
315
 
312
ENABLE_BASE_OPERATORS_ON(Score)
316
ENABLE_BASE_OPERATORS_ON(Score)
313
 
317
 
314
#undef ENABLE_FULL_OPERATORS_ON
318
#undef ENABLE_FULL_OPERATORS_ON
-
 
319
#undef ENABLE_INCR_OPERATORS_ON
315
#undef ENABLE_BASE_OPERATORS_ON
320
#undef ENABLE_BASE_OPERATORS_ON
316
 
321
 
317
/// Additional operators to add integers to a Value
322
/// Additional operators to add integers to a Value
318
inline Value operator+(Value v, int i) { return Value(int(v) + i); }
323
constexpr Value operator+(Value v, int i) { return Value(int(v) + i); }
319
inline Value operator-(Value v, int i) { return Value(int(v) - i); }
324
constexpr Value operator-(Value v, int i) { return Value(int(v) - i); }
320
inline Value& operator+=(Value& v, int i) { return v = v + i; }
325
inline Value& operator+=(Value& v, int i) { return v = v + i; }
321
inline Value& operator-=(Value& v, int i) { return v = v - i; }
326
inline Value& operator-=(Value& v, int i) { return v = v - i; }
-
 
327
 
-
 
328
/// Additional operators to add a Direction to a Square
-
 
329
inline Square operator+(Square s, Direction d) { return Square(int(s) + int(d)); }
-
 
330
inline Square operator-(Square s, Direction d) { return Square(int(s) - int(d)); }
-
 
331
inline Square& operator+=(Square &s, Direction d) { return s = s + d; }
-
 
332
inline Square& operator-=(Square &s, Direction d) { return s = s - d; }
322
 
333
 
323
/// Only declared but not defined. We don't want to multiply two scores due to
334
/// Only declared but not defined. We don't want to multiply two scores due to
324
/// a very high risk of overflow. So user should explicitly convert to integer.
335
/// a very high risk of overflow. So user should explicitly convert to integer.
325
inline Score operator*(Score s1, Score s2);
336
Score operator*(Score, Score) = delete;
326
 
337
 
327
/// Division of a Score must be handled separately for each term
338
/// Division of a Score must be handled separately for each term
328
inline Score operator/(Score s, int i) {
339
inline Score operator/(Score s, int i) {
329
  return make_score(mg_value(s) / i, eg_value(s) / i);
340
  return make_score(mg_value(s) / i, eg_value(s) / i);
330
}
341
}
331
 
342
 
-
 
343
/// Multiplication of a Score by an integer. We check for overflow in debug mode.
-
 
344
inline Score operator*(Score s, int i) {
-
 
345
 
-
 
346
  Score result = Score(int(s) * i);
-
 
347
 
-
 
348
  assert(eg_value(result) == (i * eg_value(s)));
-
 
349
  assert(mg_value(result) == (i * mg_value(s)));
-
 
350
  assert((i == 0) || (result / i) == s );
-
 
351
 
-
 
352
  return result;
-
 
353
}
-
 
354
 
332
inline Color operator~(Color c) {
355
constexpr Color operator~(Color c) {
333
  return Color(c ^ BLACK); // Toggle color
356
  return Color(c ^ BLACK); // Toggle color
334
}
357
}
335
 
358
 
336
inline Square operator~(Square s) {
359
constexpr Square operator~(Square s) {
337
  return Square(s ^ SQ_A8); // Vertical flip SQ_A1 -> SQ_A8
360
  return Square(s ^ SQ_A8); // Vertical flip SQ_A1 -> SQ_A8
338
}
361
}
339
 
362
 
-
 
363
constexpr File operator~(File f) {
-
 
364
  return File(f ^ FILE_H); // Horizontal flip FILE_A -> FILE_H
-
 
365
}
-
 
366
 
340
inline Piece operator~(Piece pc) {
367
constexpr Piece operator~(Piece pc) {
341
  return Piece(pc ^ 8); // Swap color of piece B_KNIGHT -> W_KNIGHT
368
  return Piece(pc ^ 8); // Swap color of piece B_KNIGHT -> W_KNIGHT
342
}
369
}
343
 
370
 
344
inline CastlingRight operator|(Color c, CastlingSide s) {
371
constexpr CastlingRight operator|(Color c, CastlingSide s) {
345
  return CastlingRight(WHITE_OO << ((s == QUEEN_SIDE) + 2 * c));
372
  return CastlingRight(WHITE_OO << ((s == QUEEN_SIDE) + 2 * c));
346
}
373
}
347
 
374
 
348
inline Value mate_in(int ply) {
375
constexpr Value mate_in(int ply) {
349
  return VALUE_MATE - ply;
376
  return VALUE_MATE - ply;
350
}
377
}
351
 
378
 
352
inline Value mated_in(int ply) {
379
constexpr Value mated_in(int ply) {
353
  return -VALUE_MATE + ply;
380
  return -VALUE_MATE + ply;
354
}
381
}
355
 
382
 
356
inline Square make_square(File f, Rank r) {
383
constexpr Square make_square(File f, Rank r) {
357
  return Square((r << 3) + f);
384
  return Square((r << 3) + f);
358
}
385
}
359
 
386
 
360
inline Piece make_piece(Color c, PieceType pt) {
387
constexpr Piece make_piece(Color c, PieceType pt) {
361
  return Piece((c << 3) + pt);
388
  return Piece((c << 3) + pt);
362
}
389
}
363
 
390
 
364
inline PieceType type_of(Piece pc) {
391
constexpr PieceType type_of(Piece pc) {
365
  return PieceType(pc & 7);
392
  return PieceType(pc & 7);
366
}
393
}
367
 
394
 
368
inline Color color_of(Piece pc) {
395
inline Color color_of(Piece pc) {
369
  assert(pc != NO_PIECE);
396
  assert(pc != NO_PIECE);
370
  return Color(pc >> 3);
397
  return Color(pc >> 3);
371
}
398
}
372
 
399
 
373
inline bool is_ok(Square s) {
400
constexpr bool is_ok(Square s) {
374
  return s >= SQ_A1 && s <= SQ_H8;
401
  return s >= SQ_A1 && s <= SQ_H8;
375
}
402
}
376
 
403
 
377
inline File file_of(Square s) {
404
constexpr File file_of(Square s) {
378
  return File(s & 7);
405
  return File(s & 7);
379
}
406
}
380
 
407
 
381
inline Rank rank_of(Square s) {
408
constexpr Rank rank_of(Square s) {
382
  return Rank(s >> 3);
409
  return Rank(s >> 3);
383
}
410
}
384
 
411
 
385
inline Square relative_square(Color c, Square s) {
412
constexpr Square relative_square(Color c, Square s) {
386
  return Square(s ^ (c * 56));
413
  return Square(s ^ (c * 56));
387
}
414
}
388
 
415
 
389
inline Rank relative_rank(Color c, Rank r) {
416
constexpr Rank relative_rank(Color c, Rank r) {
390
  return Rank(r ^ (c * 7));
417
  return Rank(r ^ (c * 7));
391
}
418
}
392
 
419
 
393
inline Rank relative_rank(Color c, Square s) {
420
constexpr Rank relative_rank(Color c, Square s) {
394
  return relative_rank(c, rank_of(s));
421
  return relative_rank(c, rank_of(s));
395
}
422
}
396
 
423
 
397
inline bool opposite_colors(Square s1, Square s2) {
424
inline bool opposite_colors(Square s1, Square s2) {
398
  int s = int(s1) ^ int(s2);
425
  int s = int(s1) ^ int(s2);
399
  return ((s >> 3) ^ s) & 1;
426
  return ((s >> 3) ^ s) & 1;
400
}
427
}
401
 
428
 
402
inline Square pawn_push(Color c) {
429
constexpr Direction pawn_push(Color c) {
403
  return c == WHITE ? NORTH : SOUTH;
430
  return c == WHITE ? NORTH : SOUTH;
404
}
431
}
405
 
432
 
406
inline Square from_sq(Move m) {
433
constexpr Square from_sq(Move m) {
407
  return Square((m >> 6) & 0x3F);
434
  return Square((m >> 6) & 0x3F);
408
}
435
}
409
 
436
 
410
inline Square to_sq(Move m) {
437
constexpr Square to_sq(Move m) {
411
  return Square(m & 0x3F);
438
  return Square(m & 0x3F);
412
}
439
}
413
 
440
 
-
 
441
constexpr int from_to(Move m) {
-
 
442
 return m & 0xFFF;
-
 
443
}
-
 
444
 
414
inline MoveType type_of(Move m) {
445
constexpr MoveType type_of(Move m) {
415
  return MoveType(m & (3 << 14));
446
  return MoveType(m & (3 << 14));
416
}
447
}
417
 
448
 
418
inline PieceType promotion_type(Move m) {
449
constexpr PieceType promotion_type(Move m) {
419
  return PieceType(((m >> 12) & 3) + KNIGHT);
450
  return PieceType(((m >> 12) & 3) + KNIGHT);
420
}
451
}
421
 
452
 
422
inline Move make_move(Square from, Square to) {
453
inline Move make_move(Square from, Square to) {
423
  return Move((from << 6) + to);
454
  return Move((from << 6) + to);
424
}
455
}
425
 
456
 
426
template<MoveType T>
457
template<MoveType T>
427
inline Move make(Square from, Square to, PieceType pt = KNIGHT) {
458
constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
428
  return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
459
  return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
429
}
460
}
430
 
461
 
431
inline bool is_ok(Move m) {
462
constexpr bool is_ok(Move m) {
432
  return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
463
  return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
433
}
464
}
434
 
465
 
435
#endif // #ifndef TYPES_H_INCLUDED
466
#endif // #ifndef TYPES_H_INCLUDED