mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-01-31 01:20:46 +01:00
DroidFish: Updated stockfish engine to version 2.2.1.
This commit is contained in:
parent
bd14dedd1d
commit
6c85f9e0c1
|
@ -17,13 +17,13 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
The code in this file is based on the opening book code in PolyGlot
|
||||
by Fabien Letouzey. PolyGlot is available under the GNU General
|
||||
Public License, and can be downloaded from http://wbec-ridderkerk.nl
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -306,225 +306,182 @@ namespace {
|
|||
const Key* ZobEnPassant = PolyGlotRandoms + 772;
|
||||
const Key* ZobTurn = PolyGlotRandoms + 780;
|
||||
|
||||
// Piece offset is calculated as 64 * (PolyPiece ^ 1) where
|
||||
// PolyPiece is: BP = 0, WP = 1, BN = 2, WN = 3 ... BK = 10, WK = 11
|
||||
const int PieceOfs[] = { 0, 64, 192, 320, 448, 576, 704, 0,
|
||||
0, 0, 128, 256, 384, 512, 640 };
|
||||
// PieceOffset is calculated as 64 * (PolyPiece ^ 1) where PolyPiece
|
||||
// is: BP = 0, WP = 1, BN = 2, WN = 3 ... BK = 10, WK = 11
|
||||
const int PieceOffset[] = { 0, 64, 192, 320, 448, 576, 704, 0,
|
||||
0, 0, 128, 256, 384, 512, 640 };
|
||||
|
||||
// book_key() builds up a PolyGlot hash key out of a position
|
||||
// book_key() returns the PolyGlot hash key of the given position
|
||||
uint64_t book_key(const Position& pos) {
|
||||
|
||||
uint64_t result = 0;
|
||||
uint64_t key = 0;
|
||||
Bitboard b = pos.occupied_squares();
|
||||
|
||||
while (b)
|
||||
{
|
||||
Square s = pop_1st_bit(&b);
|
||||
result ^= ZobPiece[PieceOfs[pos.piece_on(s)] + s];
|
||||
key ^= ZobPiece[PieceOffset[pos.piece_on(s)] + s];
|
||||
}
|
||||
|
||||
if (pos.can_castle(WHITE_OO))
|
||||
result ^= ZobCastle[0];
|
||||
b = (pos.can_castle(WHITE_OO) << 0) | (pos.can_castle(WHITE_OOO) << 1)
|
||||
| (pos.can_castle(BLACK_OO) << 2) | (pos.can_castle(BLACK_OOO) << 3);
|
||||
|
||||
if (pos.can_castle(WHITE_OOO))
|
||||
result ^= ZobCastle[1];
|
||||
|
||||
if (pos.can_castle(BLACK_OO))
|
||||
result ^= ZobCastle[2];
|
||||
|
||||
if (pos.can_castle(BLACK_OOO))
|
||||
result ^= ZobCastle[3];
|
||||
while (b)
|
||||
key ^= ZobCastle[pop_1st_bit(&b)];
|
||||
|
||||
if (pos.ep_square() != SQ_NONE)
|
||||
result ^= ZobEnPassant[file_of(pos.ep_square())];
|
||||
key ^= ZobEnPassant[file_of(pos.ep_square())];
|
||||
|
||||
if (pos.side_to_move() == WHITE)
|
||||
result ^= ZobTurn[0];
|
||||
key ^= ZobTurn[0];
|
||||
|
||||
return result;
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Book c'tor. Make random number generation less deterministic, for book moves
|
||||
Book::Book() : bookSize(0) {
|
||||
Book::Book() : size(0) {
|
||||
|
||||
for (int i = abs(system_time() % 10000); i > 0; i--)
|
||||
RKiss.rand<unsigned>();
|
||||
RKiss.rand<unsigned>(); // Make random number generation less deterministic
|
||||
}
|
||||
|
||||
Book::~Book() { if (is_open()) close(); }
|
||||
|
||||
|
||||
/// Book::operator>>() reads sizeof(T) chars from the file's binary byte stream
|
||||
/// and converts them in a number of type T. A Polyglot book stores numbers in
|
||||
/// big-endian format.
|
||||
|
||||
template<typename T> Book& Book::operator>>(T& n) {
|
||||
|
||||
n = 0;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
n = T((n << 8) + ifstream::get());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<> Book& Book::operator>>(BookEntry& e) {
|
||||
return *this >> e.key >> e.move >> e.count >> e.learn;
|
||||
}
|
||||
|
||||
|
||||
/// Book destructor. Be sure file is closed before we leave.
|
||||
/// Book::open() tries to open a book file with the given name after closing
|
||||
/// any exsisting one.
|
||||
|
||||
Book::~Book() {
|
||||
bool Book::open(const char* fName) {
|
||||
|
||||
close();
|
||||
}
|
||||
fileName = "";
|
||||
|
||||
if (is_open()) // Cannot close an already closed file
|
||||
close();
|
||||
|
||||
/// Book::close() closes the file only if it is open, otherwise the call fails
|
||||
/// and the failbit internal state flag is set.
|
||||
ifstream::open(fName, ifstream::in | ifstream::binary | ios::ate);
|
||||
|
||||
void Book::close() {
|
||||
if (!is_open())
|
||||
return false; // Silently fail if the file is not found
|
||||
|
||||
if (bookFile.is_open())
|
||||
bookFile.close();
|
||||
// Get the book size in number of entries, we are already at the end of file
|
||||
size = tellg() / sizeof(BookEntry);
|
||||
|
||||
bookName = "";
|
||||
bookSize = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Book::open() opens a book file with a given name
|
||||
|
||||
void Book::open(const string& fileName) {
|
||||
|
||||
// Close old file before opening the new
|
||||
close();
|
||||
|
||||
bookFile.open(fileName.c_str(), ifstream::in | ifstream::binary |ios::ate);
|
||||
|
||||
// Silently return when asked to open a non-exsistent file
|
||||
if (!bookFile.is_open())
|
||||
return;
|
||||
|
||||
// Get the book size in number of entries, we are already at the file end
|
||||
bookSize = long(bookFile.tellg()) / sizeof(BookEntry);
|
||||
|
||||
if (!bookFile.good())
|
||||
if (!good())
|
||||
{
|
||||
cerr << "Failed to open book file " << fileName << endl;
|
||||
cerr << "Failed to open book file " << fName << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set only if successful
|
||||
bookName = fileName;
|
||||
fileName = fName; // Set only if successful
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Book::probe() gets a book move for a given position. Returns MOVE_NONE
|
||||
/// if no book move is found. If findBest is true then returns always the
|
||||
/// highest rated move otherwise chooses randomly based on the move score.
|
||||
/// Book::probe() tries to find a book move for the given position. If no move
|
||||
/// is found returns MOVE_NONE. If pickBest is true returns always the highest
|
||||
/// rated move, otherwise randomly chooses one, based on the move score.
|
||||
|
||||
Move Book::probe(const Position& pos, bool findBest) {
|
||||
Move Book::probe(const Position& pos, const string& fName, bool pickBest) {
|
||||
|
||||
if (!bookSize || !bookFile.is_open())
|
||||
BookEntry e;
|
||||
uint16_t best = 0;
|
||||
unsigned sum = 0;
|
||||
Move move = MOVE_NONE;
|
||||
uint64_t key = book_key(pos);
|
||||
|
||||
if (fileName != fName && !open(fName.c_str()))
|
||||
return MOVE_NONE;
|
||||
|
||||
BookEntry entry;
|
||||
unsigned scoresSum = 0, bestScore = 0, bookMove = 0;
|
||||
uint64_t key = book_key(pos);
|
||||
int idx = first_entry(key) - 1;
|
||||
binary_search(key);
|
||||
|
||||
// Choose a book move among the possible moves for the given position
|
||||
while (++idx < bookSize && (entry = read_entry(idx), entry.key == key))
|
||||
while (*this >> e, e.key == key && good())
|
||||
{
|
||||
scoresSum += entry.count;
|
||||
best = max(best, e.count);
|
||||
sum += e.count;
|
||||
|
||||
// Choose book move according to its score. If a move has a very
|
||||
// high score it has higher probability to be choosen than a move
|
||||
// with lower score. Note that first entry is always chosen.
|
||||
if ( RKiss.rand<unsigned>() % scoresSum < entry.count
|
||||
|| (findBest && entry.count > bestScore))
|
||||
bookMove = entry.move;
|
||||
|
||||
if (entry.count > bestScore)
|
||||
bestScore = entry.count;
|
||||
if ( (RKiss.rand<unsigned>() % sum < e.count)
|
||||
|| (pickBest && e.count == best))
|
||||
move = Move(e.move);
|
||||
}
|
||||
|
||||
if (!bookMove)
|
||||
if (!move)
|
||||
return MOVE_NONE;
|
||||
|
||||
// A PolyGlot book move is encoded as follows:
|
||||
//
|
||||
// bit 0- 5: destination square (from 0 to 63)
|
||||
// bit 6-11: origin square (from 0 to 63)
|
||||
// bit 12-13-14: promotion piece (from KNIGHT == 1 to QUEEN == 4)
|
||||
// bit 12-14: promotion piece (from KNIGHT == 1 to QUEEN == 4)
|
||||
//
|
||||
// Castling moves follow "king captures rook" representation. So in case
|
||||
// book move is a promotion we have to convert to our representation, in
|
||||
// all other cases we can directly compare with a Move after having
|
||||
// masked out special Move's flags that are not supported by PolyGlot.
|
||||
int promotion = (bookMove >> 12) & 7;
|
||||
// Castling moves follow "king captures rook" representation. So in case book
|
||||
// move is a promotion we have to convert to our representation, in all the
|
||||
// other cases we can directly compare with a Move after having masked out
|
||||
// the special Move's flags (bit 14-15) that are not supported by PolyGlot.
|
||||
int pt = (move >> 12) & 7;
|
||||
if (pt)
|
||||
move = make_promotion(from_sq(move), to_sq(move), PieceType(pt + 1));
|
||||
|
||||
if (promotion)
|
||||
bookMove = make_promotion_move(move_from(Move(bookMove)),
|
||||
move_to(Move(bookMove)),
|
||||
PieceType(promotion + 1));
|
||||
// Verify the book move is legal
|
||||
// Add 'special move' flags and verify it is legal
|
||||
for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
|
||||
if (unsigned(ml.move() & ~(3 << 14)) == bookMove) // Mask out special flags
|
||||
if (move == (ml.move() & 0x3FFF))
|
||||
return ml.move();
|
||||
|
||||
return MOVE_NONE;
|
||||
}
|
||||
|
||||
|
||||
/// Book::first_entry() takes a book key as input, and does a binary search
|
||||
/// through the book file for the given key. The index to the first (leftmost)
|
||||
/// book entry with the same key as the input is returned. When the key is not
|
||||
/// found in the book file, bookSize is returned.
|
||||
/// Book::binary_search() takes a book key as input, and does a binary search
|
||||
/// through the book file for the given key. File stream current position is set
|
||||
/// to the leftmost book entry with the same key as the input.
|
||||
|
||||
int Book::first_entry(uint64_t key) {
|
||||
|
||||
int left, right, mid;
|
||||
|
||||
// Binary search (finds the leftmost entry with given key)
|
||||
left = 0;
|
||||
right = bookSize - 1;
|
||||
|
||||
assert(left <= right);
|
||||
|
||||
while (left < right)
|
||||
{
|
||||
mid = (left + right) / 2;
|
||||
|
||||
assert(mid >= left && mid < right);
|
||||
|
||||
if (key <= read_entry(mid).key)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
|
||||
assert(left == right);
|
||||
|
||||
return read_entry(left).key == key ? left : bookSize;
|
||||
}
|
||||
|
||||
|
||||
/// Book::operator>>() reads sizeof(T) chars from the file's binary byte
|
||||
/// stream and converts them in a number of type T.
|
||||
template<typename T>
|
||||
Book& Book::operator>>(T& n) {
|
||||
|
||||
n = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
n = T((n << 8) + bookFile.get());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// Book::read_entry() takes an integer index, and returns the BookEntry
|
||||
/// at the given index in the book file.
|
||||
|
||||
BookEntry Book::read_entry(int idx) {
|
||||
|
||||
assert(idx >= 0 && idx < bookSize);
|
||||
assert(bookFile.is_open());
|
||||
void Book::binary_search(uint64_t key) {
|
||||
|
||||
size_t low, high, mid;
|
||||
BookEntry e;
|
||||
|
||||
bookFile.seekg(idx * sizeof(BookEntry), ios_base::beg);
|
||||
low = 0;
|
||||
high = size - 1;
|
||||
|
||||
*this >> e.key >> e.move >> e.count >> e.learn;
|
||||
assert(low <= high);
|
||||
|
||||
if (!bookFile.good())
|
||||
while (low < high && good())
|
||||
{
|
||||
cerr << "Failed to read book entry at index " << idx << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
mid = (low + high) / 2;
|
||||
|
||||
assert(mid >= low && mid < high);
|
||||
|
||||
seekg(mid * sizeof(BookEntry), ios_base::beg);
|
||||
*this >> e;
|
||||
|
||||
if (key <= e.key)
|
||||
high = mid;
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
return e;
|
||||
|
||||
assert(low == high);
|
||||
|
||||
seekg(low * sizeof(BookEntry), ios_base::beg);
|
||||
}
|
||||
|
|
|
@ -37,25 +37,22 @@ struct BookEntry {
|
|||
uint32_t learn;
|
||||
};
|
||||
|
||||
class Book {
|
||||
|
||||
class Book : private std::ifstream {
|
||||
public:
|
||||
Book();
|
||||
~Book();
|
||||
void open(const std::string& fileName);
|
||||
void close();
|
||||
Move probe(const Position& pos, bool findBestMove);
|
||||
const std::string name() const { return bookName; }
|
||||
Move probe(const Position& pos, const std::string& fName, bool pickBest);
|
||||
|
||||
private:
|
||||
template<typename T> Book& operator>>(T& n);
|
||||
|
||||
BookEntry read_entry(int idx);
|
||||
int first_entry(uint64_t key);
|
||||
bool open(const char* fName);
|
||||
void binary_search(uint64_t key);
|
||||
|
||||
RKISS RKiss;
|
||||
std::ifstream bookFile;
|
||||
std::string bookName;
|
||||
int bookSize;
|
||||
std::string fileName;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOK_H_INCLUDED)
|
||||
|
|
|
@ -19,12 +19,14 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "bitcount.h"
|
||||
#include "endgame.h"
|
||||
#include "pawns.h"
|
||||
|
||||
using std::string;
|
||||
using std::transform;
|
||||
|
||||
extern uint32_t probe_kpk_bitbase(Square wksq, Square wpsq, Square bksq, Color stm);
|
||||
|
||||
|
@ -72,7 +74,7 @@ namespace {
|
|||
string sides[] = { code.substr(code.find('K', 1)), // Weaker
|
||||
code.substr(0, code.find('K', 1)) }; // Stronger
|
||||
|
||||
std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
|
||||
transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
|
||||
|
||||
string fen = sides[0] + char('0' + int(8 - code.length()))
|
||||
+ sides[1] + "/8/8/8/8/8/8/8 w - - 0 10";
|
||||
|
|
|
@ -75,8 +75,8 @@ typedef HANDLE WaitCondition;
|
|||
# define cond_init(x) { *x = CreateEvent(0, FALSE, FALSE, 0); }
|
||||
# define cond_destroy(x) CloseHandle(*x)
|
||||
# define cond_signal(x) SetEvent(*x)
|
||||
# define cond_wait(x,y) { ResetEvent(*x); lock_release(y); WaitForSingleObject(*x, INFINITE); lock_grab(y); }
|
||||
# define cond_timedwait(x,y,z) { ResetEvent(*x); lock_release(y); WaitForSingleObject(*x,z); lock_grab(y); }
|
||||
# define cond_wait(x,y) { lock_release(y); WaitForSingleObject(*x, INFINITE); lock_grab(y); }
|
||||
# define cond_timedwait(x,y,z) { lock_release(y); WaitForSingleObject(*x,z); lock_grab(y); }
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ using namespace std;
|
|||
/// Version number. If Version is left empty, then Tag plus current
|
||||
/// date (in the format YYMMDD) is used as a version number.
|
||||
|
||||
static const string Version = "2.2";
|
||||
static const string Tag = "";
|
||||
static const string Version = "2.2.1";
|
||||
static const string Tag = "";
|
||||
|
||||
|
||||
/// engine_info() returns the full name of the current Stockfish version.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "movegen.h"
|
||||
#include "position.h"
|
||||
|
@ -33,8 +34,8 @@ using std::string;
|
|||
|
||||
const string move_to_uci(Move m, bool chess960) {
|
||||
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
string promotion;
|
||||
|
||||
if (m == MOVE_NONE)
|
||||
|
@ -83,13 +84,13 @@ const string move_to_san(Position& pos, Move m) {
|
|||
|
||||
Bitboard attackers;
|
||||
bool ambiguousMove, ambiguousFile, ambiguousRank;
|
||||
Square sq, from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square sq, from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
PieceType pt = type_of(pos.piece_on(from));
|
||||
string san;
|
||||
|
||||
if (is_castle(m))
|
||||
san = (move_to(m) < move_from(m) ? "O-O-O" : "O-O");
|
||||
san = (to_sq(m) < from_sq(m) ? "O-O-O" : "O-O");
|
||||
else
|
||||
{
|
||||
if (pt != PAWN)
|
||||
|
|
|
@ -101,8 +101,6 @@ namespace {
|
|||
FORCE_INLINE MoveStack* generate_piece_moves(const Position& p, MoveStack* m, Color us, Bitboard t) {
|
||||
|
||||
assert(Pt == PAWN);
|
||||
assert(Type == MV_CAPTURE || Type == MV_NON_CAPTURE || Type == MV_EVASION);
|
||||
|
||||
return (us == WHITE ? generate_pawn_moves<WHITE, Type>(p, m, t, SQ_NONE)
|
||||
: generate_pawn_moves<BLACK, Type>(p, m, t, SQ_NONE));
|
||||
}
|
||||
|
@ -151,27 +149,22 @@ namespace {
|
|||
template<MoveType Type>
|
||||
MoveStack* generate(const Position& pos, MoveStack* mlist) {
|
||||
|
||||
assert(Type == MV_CAPTURE || Type == MV_NON_CAPTURE || Type == MV_NON_EVASION);
|
||||
assert(!pos.in_check());
|
||||
|
||||
Color us = pos.side_to_move();
|
||||
Bitboard target;
|
||||
|
||||
if (Type == MV_CAPTURE || Type == MV_NON_EVASION)
|
||||
if (Type == MV_CAPTURE)
|
||||
target = pos.pieces(flip(us));
|
||||
|
||||
else if (Type == MV_NON_CAPTURE)
|
||||
target = pos.empty_squares();
|
||||
else
|
||||
assert(false);
|
||||
|
||||
if (Type == MV_NON_EVASION)
|
||||
{
|
||||
mlist = generate_piece_moves<PAWN, MV_CAPTURE>(pos, mlist, us, target);
|
||||
mlist = generate_piece_moves<PAWN, MV_NON_CAPTURE>(pos, mlist, us, pos.empty_squares());
|
||||
target |= pos.empty_squares();
|
||||
}
|
||||
else
|
||||
mlist = generate_piece_moves<PAWN, Type>(pos, mlist, us, target);
|
||||
else if (Type == MV_NON_EVASION)
|
||||
target = pos.pieces(flip(us)) | pos.empty_squares();
|
||||
|
||||
mlist = generate_piece_moves<PAWN, Type>(pos, mlist, us, target);
|
||||
mlist = generate_piece_moves<KNIGHT>(pos, mlist, us, target);
|
||||
mlist = generate_piece_moves<BISHOP>(pos, mlist, us, target);
|
||||
mlist = generate_piece_moves<ROOK>(pos, mlist, us, target);
|
||||
|
@ -339,7 +332,7 @@ namespace {
|
|||
Delta == DELTA_NW ? p << 7 : Delta == DELTA_SW ? p >> 9 : p;
|
||||
}
|
||||
|
||||
template<MoveType Type, Square Delta>
|
||||
template<Square Delta>
|
||||
inline MoveStack* generate_pawn_captures(MoveStack* mlist, Bitboard pawns, Bitboard target) {
|
||||
|
||||
const Bitboard TFileABB = (Delta == DELTA_NE || Delta == DELTA_SE ? FileABB : FileHBB);
|
||||
|
@ -371,21 +364,21 @@ namespace {
|
|||
{
|
||||
to = pop_1st_bit(&b);
|
||||
|
||||
if (Type == MV_CAPTURE || Type == MV_EVASION)
|
||||
(*mlist++).move = make_promotion_move(to - Delta, to, QUEEN);
|
||||
if (Type == MV_CAPTURE || Type == MV_EVASION || Type == MV_NON_EVASION)
|
||||
(*mlist++).move = make_promotion(to - Delta, to, QUEEN);
|
||||
|
||||
if (Type == MV_NON_CAPTURE || Type == MV_EVASION)
|
||||
if (Type == MV_NON_CAPTURE || Type == MV_EVASION || Type == MV_NON_EVASION)
|
||||
{
|
||||
(*mlist++).move = make_promotion_move(to - Delta, to, ROOK);
|
||||
(*mlist++).move = make_promotion_move(to - Delta, to, BISHOP);
|
||||
(*mlist++).move = make_promotion_move(to - Delta, to, KNIGHT);
|
||||
(*mlist++).move = make_promotion(to - Delta, to, ROOK);
|
||||
(*mlist++).move = make_promotion(to - Delta, to, BISHOP);
|
||||
(*mlist++).move = make_promotion(to - Delta, to, KNIGHT);
|
||||
}
|
||||
|
||||
// This is the only possible under promotion that can give a check
|
||||
// not already included in the queen-promotion.
|
||||
if ( Type == MV_CHECK
|
||||
&& bit_is_set(pos.attacks_from<KNIGHT>(to), pos.king_square(Delta > 0 ? BLACK : WHITE)))
|
||||
(*mlist++).move = make_promotion_move(to - Delta, to, KNIGHT);
|
||||
(*mlist++).move = make_promotion(to - Delta, to, KNIGHT);
|
||||
else (void)pos; // Silence a warning under MSVC
|
||||
}
|
||||
return mlist;
|
||||
|
@ -435,10 +428,10 @@ namespace {
|
|||
}
|
||||
|
||||
// Standard captures
|
||||
if (Type == MV_CAPTURE || Type == MV_EVASION)
|
||||
if (Type == MV_CAPTURE || Type == MV_EVASION || Type == MV_NON_EVASION)
|
||||
{
|
||||
mlist = generate_pawn_captures<Type, RIGHT_UP>(mlist, pawns, enemyPieces);
|
||||
mlist = generate_pawn_captures<Type, LEFT_UP>(mlist, pawns, enemyPieces);
|
||||
mlist = generate_pawn_captures<RIGHT_UP>(mlist, pawns, enemyPieces);
|
||||
mlist = generate_pawn_captures<LEFT_UP>(mlist, pawns, enemyPieces);
|
||||
}
|
||||
|
||||
// Single and double pawn pushes
|
||||
|
@ -470,7 +463,8 @@ namespace {
|
|||
}
|
||||
|
||||
// En passant captures
|
||||
if ((Type == MV_CAPTURE || Type == MV_EVASION) && pos.ep_square() != SQ_NONE)
|
||||
if ( (Type == MV_CAPTURE || Type == MV_EVASION || Type == MV_NON_EVASION)
|
||||
&& pos.ep_square() != SQ_NONE)
|
||||
{
|
||||
assert(Us != WHITE || rank_of(pos.ep_square()) == RANK_6);
|
||||
assert(Us != BLACK || rank_of(pos.ep_square()) == RANK_3);
|
||||
|
@ -488,7 +482,7 @@ namespace {
|
|||
while (b1)
|
||||
{
|
||||
to = pop_1st_bit(&b1);
|
||||
(*mlist++).move = make_enpassant_move(to, pos.ep_square());
|
||||
(*mlist++).move = make_enpassant(to, pos.ep_square());
|
||||
}
|
||||
}
|
||||
return mlist;
|
||||
|
@ -535,7 +529,7 @@ namespace {
|
|||
return mlist;
|
||||
}
|
||||
|
||||
(*mlist++).move = make_castle_move(kfrom, rfrom);
|
||||
(*mlist++).move = make_castle(kfrom, rfrom);
|
||||
|
||||
return mlist;
|
||||
}
|
||||
|
|
|
@ -254,8 +254,8 @@ void MovePicker::score_captures() {
|
|||
for (MoveStack* cur = moves; cur != lastMove; cur++)
|
||||
{
|
||||
m = cur->move;
|
||||
cur->score = PieceValueMidgame[pos.piece_on(move_to(m))]
|
||||
- type_of(pos.piece_on(move_from(m)));
|
||||
cur->score = PieceValueMidgame[pos.piece_on(to_sq(m))]
|
||||
- type_of(pos.piece_on(from_sq(m)));
|
||||
|
||||
if (is_promotion(m))
|
||||
cur->score += PieceValueMidgame[Piece(promotion_piece_type(m))];
|
||||
|
@ -270,8 +270,8 @@ void MovePicker::score_noncaptures() {
|
|||
for (MoveStack* cur = moves; cur != lastMove; cur++)
|
||||
{
|
||||
m = cur->move;
|
||||
from = move_from(m);
|
||||
cur->score = H.value(pos.piece_on(from), move_to(m));
|
||||
from = from_sq(m);
|
||||
cur->score = H.value(pos.piece_on(from), to_sq(m));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,10 +293,10 @@ void MovePicker::score_evasions() {
|
|||
if ((seeScore = pos.see_sign(m)) < 0)
|
||||
cur->score = seeScore - History::MaxValue; // Be sure we are at the bottom
|
||||
else if (pos.is_capture(m))
|
||||
cur->score = PieceValueMidgame[pos.piece_on(move_to(m))]
|
||||
- type_of(pos.piece_on(move_from(m))) + History::MaxValue;
|
||||
cur->score = PieceValueMidgame[pos.piece_on(to_sq(m))]
|
||||
- type_of(pos.piece_on(from_sq(m))) + History::MaxValue;
|
||||
else
|
||||
cur->score = H.value(pos.piece_on(move_from(m)), move_to(m));
|
||||
cur->score = H.value(pos.piece_on(from_sq(m)), to_sq(m));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,7 @@ Move MovePicker::next_move() {
|
|||
|
||||
case PH_QRECAPTURES:
|
||||
move = (curMove++)->move;
|
||||
if (move_to(move) == recaptureSquare)
|
||||
if (to_sq(move) == recaptureSquare)
|
||||
return move;
|
||||
break;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "bitcount.h"
|
||||
#include "movegen.h"
|
||||
|
@ -420,8 +421,8 @@ bool Position::move_attacks_square(Move m, Square s) const {
|
|||
assert(square_is_ok(s));
|
||||
|
||||
Bitboard occ, xray;
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
Piece piece = piece_on(from);
|
||||
|
||||
assert(!square_is_empty(from));
|
||||
|
@ -451,7 +452,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
|
|||
assert(pinned == pinned_pieces());
|
||||
|
||||
Color us = side_to_move();
|
||||
Square from = move_from(m);
|
||||
Square from = from_sq(m);
|
||||
|
||||
assert(color_of(piece_on(from)) == us);
|
||||
assert(piece_on(king_square(us)) == make_piece(us, KING));
|
||||
|
@ -462,7 +463,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
|
|||
if (is_enpassant(m))
|
||||
{
|
||||
Color them = flip(us);
|
||||
Square to = move_to(m);
|
||||
Square to = to_sq(m);
|
||||
Square capsq = to + pawn_push(them);
|
||||
Square ksq = king_square(us);
|
||||
Bitboard b = occupied_squares();
|
||||
|
@ -484,13 +485,13 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
|
|||
// square is attacked by the opponent. Castling moves are checked
|
||||
// for legality during move generation.
|
||||
if (type_of(piece_on(from)) == KING)
|
||||
return is_castle(m) || !(attackers_to(move_to(m)) & pieces(flip(us)));
|
||||
return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(flip(us)));
|
||||
|
||||
// A non-king move is legal if and only if it is not pinned or it
|
||||
// is moving along the ray towards or away from the king.
|
||||
return !pinned
|
||||
|| !bit_is_set(pinned, from)
|
||||
|| squares_aligned(from, move_to(m), king_square(us));
|
||||
|| squares_aligned(from, to_sq(m), king_square(us));
|
||||
}
|
||||
|
||||
|
||||
|
@ -516,8 +517,8 @@ bool Position::is_pseudo_legal(const Move m) const {
|
|||
|
||||
Color us = sideToMove;
|
||||
Color them = flip(sideToMove);
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
Piece pc = piece_on(from);
|
||||
|
||||
// Use a slower but simpler function for uncommon cases
|
||||
|
@ -613,7 +614,7 @@ bool Position::is_pseudo_legal(const Move m) const {
|
|||
{
|
||||
Bitboard b = occupied_squares();
|
||||
clear_bit(&b, from);
|
||||
if (attackers_to(move_to(m), b) & pieces(flip(us)))
|
||||
if (attackers_to(to_sq(m), b) & pieces(flip(us)))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -626,7 +627,7 @@ bool Position::is_pseudo_legal(const Move m) const {
|
|||
|
||||
// Our move must be a blocking evasion or a capture of the checking piece
|
||||
target = squares_between(checksq, king_square(us)) | checkers();
|
||||
if (!bit_is_set(target, move_to(m)))
|
||||
if (!bit_is_set(target, to_sq(m)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -641,10 +642,10 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
|
|||
|
||||
assert(is_ok(m));
|
||||
assert(ci.dcCandidates == discovered_check_candidates());
|
||||
assert(color_of(piece_on(move_from(m))) == side_to_move());
|
||||
assert(color_of(piece_on(from_sq(m))) == side_to_move());
|
||||
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
PieceType pt = type_of(piece_on(from));
|
||||
|
||||
// Direct check ?
|
||||
|
@ -766,8 +767,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
|||
|
||||
Color us = side_to_move();
|
||||
Color them = flip(us);
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
Piece piece = piece_on(from);
|
||||
PieceType pt = type_of(piece);
|
||||
PieceType capture = is_enpassant(m) ? PAWN : type_of(piece_on(to));
|
||||
|
@ -982,8 +983,8 @@ void Position::undo_move(Move m) {
|
|||
|
||||
Color us = side_to_move();
|
||||
Color them = flip(us);
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
Piece piece = piece_on(to);
|
||||
PieceType pt = type_of(piece);
|
||||
PieceType capture = st->capturedType;
|
||||
|
@ -1077,8 +1078,8 @@ void Position::do_castle_move(Move m) {
|
|||
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
|
||||
|
||||
Color us = side_to_move();
|
||||
Square kBefore = move_from(m);
|
||||
Square rBefore = move_to(m);
|
||||
Square kBefore = from_sq(m);
|
||||
Square rBefore = to_sq(m);
|
||||
|
||||
// Find after-castle squares for king and rook
|
||||
if (rBefore > kBefore) // O-O
|
||||
|
@ -1228,8 +1229,8 @@ int Position::see_sign(Move m) const {
|
|||
|
||||
assert(is_ok(m));
|
||||
|
||||
Square from = move_from(m);
|
||||
Square to = move_to(m);
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
|
||||
// Early return if SEE cannot be negative because captured piece value
|
||||
// is not less then capturing one. Note that king moves always return
|
||||
|
@ -1256,8 +1257,8 @@ int Position::see(Move m) const {
|
|||
if (is_castle(m))
|
||||
return 0;
|
||||
|
||||
from = move_from(m);
|
||||
to = move_to(m);
|
||||
from = from_sq(m);
|
||||
to = to_sq(m);
|
||||
capturedType = type_of(piece_on(to));
|
||||
occ = occupied_squares();
|
||||
|
||||
|
|
|
@ -428,8 +428,8 @@ inline Value Position::non_pawn_material(Color c) const {
|
|||
|
||||
inline bool Position::is_passed_pawn_push(Move m) const {
|
||||
|
||||
return board[move_from(m)] == make_piece(sideToMove, PAWN)
|
||||
&& pawn_is_passed(sideToMove, move_to(m));
|
||||
return board[from_sq(m)] == make_piece(sideToMove, PAWN)
|
||||
&& pawn_is_passed(sideToMove, to_sq(m));
|
||||
}
|
||||
|
||||
inline int Position::startpos_ply_counter() const {
|
||||
|
@ -454,14 +454,14 @@ inline bool Position::is_chess960() const {
|
|||
inline bool Position::is_capture_or_promotion(Move m) const {
|
||||
|
||||
assert(is_ok(m));
|
||||
return is_special(m) ? !is_castle(m) : !square_is_empty(move_to(m));
|
||||
return is_special(m) ? !is_castle(m) : !square_is_empty(to_sq(m));
|
||||
}
|
||||
|
||||
inline bool Position::is_capture(Move m) const {
|
||||
|
||||
// Note that castle is coded as "king captures the rook"
|
||||
assert(is_ok(m));
|
||||
return (!square_is_empty(move_to(m)) && !is_castle(m)) || is_enpassant(m);
|
||||
return (!square_is_empty(to_sq(m)) && !is_castle(m)) || is_enpassant(m);
|
||||
}
|
||||
|
||||
inline PieceType Position::captured_piece_type() const {
|
||||
|
|
|
@ -49,8 +49,9 @@ namespace Search {
|
|||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::count;
|
||||
using std::find;
|
||||
using namespace Search;
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -140,6 +141,9 @@ namespace {
|
|||
// better than the second best move.
|
||||
const Value EasyMoveMargin = Value(0x150);
|
||||
|
||||
// This is the minimum interval in msec between two check_time() calls
|
||||
const int TimerResolution = 5;
|
||||
|
||||
|
||||
/// Namespace variables
|
||||
|
||||
|
@ -198,19 +202,19 @@ namespace {
|
|||
FORCE_INLINE bool is_dangerous(const Position& pos, Move m, bool captureOrPromotion) {
|
||||
|
||||
// Test for a pawn pushed to 7th or a passed pawn move
|
||||
if (type_of(pos.piece_on(move_from(m))) == PAWN)
|
||||
if (type_of(pos.piece_on(from_sq(m))) == PAWN)
|
||||
{
|
||||
Color c = pos.side_to_move();
|
||||
if ( relative_rank(c, move_to(m)) == RANK_7
|
||||
|| pos.pawn_is_passed(c, move_to(m)))
|
||||
if ( relative_rank(c, to_sq(m)) == RANK_7
|
||||
|| pos.pawn_is_passed(c, to_sq(m)))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test for a capture that triggers a pawn endgame
|
||||
if ( captureOrPromotion
|
||||
&& type_of(pos.piece_on(move_to(m))) != PAWN
|
||||
&& type_of(pos.piece_on(to_sq(m))) != PAWN
|
||||
&& ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
|
||||
- PieceValueMidgame[pos.piece_on(move_to(m))] == VALUE_ZERO)
|
||||
- PieceValueMidgame[pos.piece_on(to_sq(m))] == VALUE_ZERO)
|
||||
&& !is_special(m))
|
||||
return true;
|
||||
|
||||
|
@ -291,22 +295,17 @@ void Search::think() {
|
|||
// Populate RootMoves with all the legal moves (default) or, if a SearchMoves
|
||||
// is given, with the subset of legal moves to search.
|
||||
for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
|
||||
if ( SearchMoves.empty()
|
||||
|| count(SearchMoves.begin(), SearchMoves.end(), ml.move()))
|
||||
if (SearchMoves.empty() || count(SearchMoves.begin(), SearchMoves.end(), ml.move()))
|
||||
RootMoves.push_back(RootMove(ml.move()));
|
||||
|
||||
if (Options["OwnBook"])
|
||||
{
|
||||
if (book.name() != (string)Options["Book File"])
|
||||
book.open(Options["Book File"]);
|
||||
Move bookMove = book.probe(pos, Options["Book File"], Options["Best Book Move"]);
|
||||
|
||||
Move bookMove = book.probe(pos, Options["Best Book Move"]);
|
||||
|
||||
if ( bookMove != MOVE_NONE
|
||||
&& count(RootMoves.begin(), RootMoves.end(), bookMove))
|
||||
if (bookMove && count(RootMoves.begin(), RootMoves.end(), bookMove))
|
||||
{
|
||||
std::swap(RootMoves[0], *find(RootMoves.begin(), RootMoves.end(), bookMove));
|
||||
goto finish;
|
||||
goto finalize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,8 +348,8 @@ void Search::think() {
|
|||
|
||||
// Set best timer interval to avoid lagging under time pressure. Timer is
|
||||
// used to check for remaining available thinking time.
|
||||
if (TimeMgr.available_time())
|
||||
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 8, 20)));
|
||||
if (Limits.use_time_management())
|
||||
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)));
|
||||
else
|
||||
Threads.set_timer(100);
|
||||
|
||||
|
@ -376,7 +375,7 @@ void Search::think() {
|
|||
pos.undo_move(RootMoves[0].pv[0]);
|
||||
}
|
||||
|
||||
finish:
|
||||
finalize:
|
||||
|
||||
// When we reach max depth we arrive here even without a StopRequest, but if
|
||||
// we are pondering or in infinite search, we shouldn't print the best move
|
||||
|
@ -519,7 +518,7 @@ namespace {
|
|||
bestMoveNeverChanged = false;
|
||||
|
||||
// Do we have time for the next iteration? Can we stop searching now?
|
||||
if (!Signals.stop && !Signals.stopOnPonderhit && Limits.useTimeManagement())
|
||||
if (!Signals.stop && !Signals.stopOnPonderhit && Limits.use_time_management())
|
||||
{
|
||||
bool stop = false; // Local variable, not the volatile Signals.stop
|
||||
|
||||
|
@ -707,7 +706,7 @@ namespace {
|
|||
&& pos.captured_piece_type() == NO_PIECE_TYPE
|
||||
&& !is_special(move))
|
||||
{
|
||||
Square to = move_to(move);
|
||||
Square to = to_sq(move);
|
||||
H.update_gain(pos.piece_on(to), to, -(ss-1)->eval - ss->eval);
|
||||
}
|
||||
|
||||
|
@ -871,7 +870,8 @@ split_point_start: // At split points actual search starts from here
|
|||
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
|
||||
while ( bestValue < beta
|
||||
&& (move = mp.next_move()) != MOVE_NONE
|
||||
&& !thread.cutoff_occurred())
|
||||
&& !thread.cutoff_occurred()
|
||||
&& !Signals.stop)
|
||||
{
|
||||
assert(is_ok(move));
|
||||
|
||||
|
@ -972,7 +972,7 @@ split_point_start: // At split points actual search starts from here
|
|||
// but fixing this made program slightly weaker.
|
||||
Depth predictedDepth = newDepth - reduction<PvNode>(depth, moveCount);
|
||||
futilityValue = futilityBase + futility_margin(predictedDepth, moveCount)
|
||||
+ H.gain(pos.piece_on(move_from(move)), move_to(move));
|
||||
+ H.gain(pos.piece_on(from_sq(move)), to_sq(move));
|
||||
|
||||
if (futilityValue < beta)
|
||||
{
|
||||
|
@ -1156,13 +1156,13 @@ split_point_start: // At split points actual search starts from here
|
|||
|
||||
// Increase history value of the cut-off move
|
||||
Value bonus = Value(int(depth) * int(depth));
|
||||
H.add(pos.piece_on(move_from(move)), move_to(move), bonus);
|
||||
H.add(pos.piece_on(from_sq(move)), to_sq(move), bonus);
|
||||
|
||||
// Decrease history of all the other played non-capture moves
|
||||
for (int i = 0; i < playedMoveCount - 1; i++)
|
||||
{
|
||||
Move m = movesSearched[i];
|
||||
H.add(pos.piece_on(move_from(m)), move_to(m), -bonus);
|
||||
H.add(pos.piece_on(from_sq(m)), to_sq(m), -bonus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1268,7 +1268,7 @@ split_point_start: // At split points actual search starts from here
|
|||
// to search the moves. Because the depth is <= 0 here, only captures,
|
||||
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
|
||||
// be generated.
|
||||
MovePicker mp(pos, ttMove, depth, H, move_to((ss-1)->currentMove));
|
||||
MovePicker mp(pos, ttMove, depth, H, to_sq((ss-1)->currentMove));
|
||||
CheckInfo ci(pos);
|
||||
|
||||
// Loop through the moves until no moves remain or a beta cutoff occurs
|
||||
|
@ -1289,7 +1289,7 @@ split_point_start: // At split points actual search starts from here
|
|||
&& !pos.is_passed_pawn_push(move))
|
||||
{
|
||||
futilityValue = futilityBase
|
||||
+ PieceValueEndgame[pos.piece_on(move_to(move))]
|
||||
+ PieceValueEndgame[pos.piece_on(to_sq(move))]
|
||||
+ (is_enpassant(move) ? PawnValueEndgame : VALUE_ZERO);
|
||||
|
||||
if (futilityValue < beta)
|
||||
|
@ -1393,8 +1393,8 @@ split_point_start: // At split points actual search starts from here
|
|||
Color them;
|
||||
Value futilityValue, bv = *bestValue;
|
||||
|
||||
from = move_from(move);
|
||||
to = move_to(move);
|
||||
from = from_sq(move);
|
||||
to = to_sq(move);
|
||||
them = flip(pos.side_to_move());
|
||||
ksq = pos.king_square(them);
|
||||
kingAtt = pos.attacks_from<KING>(ksq);
|
||||
|
@ -1454,14 +1454,14 @@ split_point_start: // At split points actual search starts from here
|
|||
assert(is_ok(m2));
|
||||
|
||||
// Case 1: The moving piece is the same in both moves
|
||||
f2 = move_from(m2);
|
||||
t1 = move_to(m1);
|
||||
f2 = from_sq(m2);
|
||||
t1 = to_sq(m1);
|
||||
if (f2 == t1)
|
||||
return true;
|
||||
|
||||
// Case 2: The destination square for m2 was vacated by m1
|
||||
t2 = move_to(m2);
|
||||
f1 = move_from(m1);
|
||||
t2 = to_sq(m2);
|
||||
f1 = from_sq(m1);
|
||||
if (t2 == f1)
|
||||
return true;
|
||||
|
||||
|
@ -1534,10 +1534,10 @@ split_point_start: // At split points actual search starts from here
|
|||
|
||||
Square mfrom, mto, tfrom, tto;
|
||||
|
||||
mfrom = move_from(m);
|
||||
mto = move_to(m);
|
||||
tfrom = move_from(threat);
|
||||
tto = move_to(threat);
|
||||
mfrom = from_sq(m);
|
||||
mto = to_sq(m);
|
||||
tfrom = from_sq(threat);
|
||||
tto = to_sq(threat);
|
||||
|
||||
// Case 1: Don't prune moves which move the threatened piece
|
||||
if (mfrom == tto)
|
||||
|
@ -1963,11 +1963,11 @@ void Thread::idle_loop(SplitPoint* sp) {
|
|||
}
|
||||
|
||||
|
||||
/// do_timer_event() is called by the timer thread when the timer triggers. It
|
||||
/// is used to print debug info and, more important, to detect when we are out of
|
||||
/// check_time() is called by the timer thread when the timer triggers. It is
|
||||
/// used to print debug info and, more important, to detect when we are out of
|
||||
/// available time and so stop the search.
|
||||
|
||||
void do_timer_event() {
|
||||
void check_time() {
|
||||
|
||||
static int lastInfoTime;
|
||||
int e = elapsed_time();
|
||||
|
@ -1985,10 +1985,10 @@ void do_timer_event() {
|
|||
&& !Signals.failedLowAtRoot
|
||||
&& e > TimeMgr.available_time();
|
||||
|
||||
bool noMoreTime = e > TimeMgr.maximum_time()
|
||||
bool noMoreTime = e > TimeMgr.maximum_time() - 2 * TimerResolution
|
||||
|| stillAtFirstMove;
|
||||
|
||||
if ( (Limits.useTimeManagement() && noMoreTime)
|
||||
if ( (Limits.use_time_management() && noMoreTime)
|
||||
|| (Limits.maxTime && e >= Limits.maxTime)
|
||||
/* missing nodes limit */ ) // FIXME
|
||||
Signals.stop = true;
|
||||
|
|
|
@ -55,7 +55,7 @@ struct Stack {
|
|||
struct LimitsType {
|
||||
|
||||
LimitsType() { memset(this, 0, sizeof(LimitsType)); }
|
||||
bool useTimeManagement() const { return !(maxTime | maxDepth | maxNodes | infinite); }
|
||||
bool use_time_management() const { return !(maxTime | maxDepth | maxNodes | infinite); }
|
||||
|
||||
int time, increment, movesToGo, maxTime, maxDepth, maxNodes, infinite, ponder;
|
||||
};
|
||||
|
|
|
@ -172,7 +172,7 @@ void ThreadsManager::init() {
|
|||
for (int i = 0; i <= MAX_THREADS; i++)
|
||||
{
|
||||
threads[i].is_searching = false;
|
||||
threads[i].do_sleep = true;
|
||||
threads[i].do_sleep = (i != 0); // Avoid a race with start_thinking()
|
||||
threads[i].threadID = i;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -202,7 +202,7 @@ void ThreadsManager::exit() {
|
|||
|
||||
// Wait for thread termination
|
||||
#if defined(_MSC_VER)
|
||||
WaitForSingleObject(threads[i].handle, 0);
|
||||
WaitForSingleObject(threads[i].handle, INFINITE);
|
||||
CloseHandle(threads[i].handle);
|
||||
#else
|
||||
pthread_join(threads[i].handle, NULL);
|
||||
|
@ -367,7 +367,7 @@ template Value ThreadsManager::split<true>(Position&, Stack*, Value, Value, Valu
|
|||
|
||||
// Thread::timer_loop() is where the timer thread waits maxPly milliseconds and
|
||||
// then calls do_timer_event(). If maxPly is 0 thread sleeps until is woken up.
|
||||
extern void do_timer_event();
|
||||
extern void check_time();
|
||||
|
||||
void Thread::timer_loop() {
|
||||
|
||||
|
@ -376,7 +376,7 @@ void Thread::timer_loop() {
|
|||
lock_grab(&sleepLock);
|
||||
timed_wait(&sleepCond, &sleepLock, maxPly ? maxPly : INT_MAX);
|
||||
lock_release(&sleepLock);
|
||||
do_timer_event();
|
||||
check_time();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +452,8 @@ void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limit
|
|||
cond_signal(&main.sleepCond); // Wake up main thread and start searching
|
||||
|
||||
if (!asyncMode)
|
||||
cond_wait(&sleepCond, &main.sleepLock);
|
||||
while (!main.do_sleep)
|
||||
cond_wait(&sleepCond, &main.sleepLock);
|
||||
|
||||
lock_release(&main.sleepLock);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
|
@ -433,11 +432,11 @@ inline Square pawn_push(Color c) {
|
|||
return c == WHITE ? DELTA_N : DELTA_S;
|
||||
}
|
||||
|
||||
inline Square move_from(Move m) {
|
||||
inline Square from_sq(Move m) {
|
||||
return Square((m >> 6) & 0x3F);
|
||||
}
|
||||
|
||||
inline Square move_to(Move m) {
|
||||
inline Square to_sq(Move m) {
|
||||
return Square(m & 0x3F);
|
||||
}
|
||||
|
||||
|
@ -465,20 +464,20 @@ inline Move make_move(Square from, Square to) {
|
|||
return Move(to | (from << 6));
|
||||
}
|
||||
|
||||
inline Move make_promotion_move(Square from, Square to, PieceType promotion) {
|
||||
return Move(to | (from << 6) | (1 << 14) | ((promotion - 2) << 12)) ;
|
||||
inline Move make_promotion(Square from, Square to, PieceType pt) {
|
||||
return Move(to | (from << 6) | (1 << 14) | ((pt - 2) << 12)) ;
|
||||
}
|
||||
|
||||
inline Move make_enpassant_move(Square from, Square to) {
|
||||
inline Move make_enpassant(Square from, Square to) {
|
||||
return Move(to | (from << 6) | (2 << 14));
|
||||
}
|
||||
|
||||
inline Move make_castle_move(Square from, Square to) {
|
||||
inline Move make_castle(Square from, Square to) {
|
||||
return Move(to | (from << 6) | (3 << 14));
|
||||
}
|
||||
|
||||
inline bool is_ok(Move m) {
|
||||
return move_from(m) != move_to(m); // Catches also MOVE_NULL and MOVE_NONE
|
||||
return from_sq(m) != to_sq(m); // Catches also MOVE_NULL and MOVE_NONE
|
||||
}
|
||||
|
||||
#include <string>
|
||||
|
|
|
@ -19,12 +19,14 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "thread.h"
|
||||
#include "ucioption.h"
|
||||
|
||||
using std::string;
|
||||
using std::lexicographical_compare;
|
||||
|
||||
OptionsMap Options; // Global object
|
||||
|
||||
|
@ -33,7 +35,7 @@ OptionsMap Options; // Global object
|
|||
static bool ci_less(char c1, char c2) { return tolower(c1) < tolower(c2); }
|
||||
|
||||
bool CaseInsensitiveLess::operator() (const string& s1, const string& s2) const {
|
||||
return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), ci_less);
|
||||
return lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), ci_less);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
|
||||
<string name="about_info">\
|
||||
<b>Information</b>\n\
|
||||
<i>DroidFish</i> ist eine Android-Version von <i>Stockfish 2.2</i>, \
|
||||
<i>DroidFish</i> ist eine Android-Version von <i>Stockfish 2.2.1</i>, \
|
||||
das zu den spielstärksten Schachprogrammen der Welt zählt. \
|
||||
Die Android-Version erreicht auf einem 1GHz-Snapdragon-Prozessor oft eine Rechentiefe von 15 oder mehr Halbzügen.\n\
|
||||
\n\
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
|
||||
<string name="about_info">\
|
||||
<b>About</b>\n\
|
||||
<i>DroidFish</i> es un derivado Android del famoso motor de ajedrez <i>stockfish 2.2</i> . \
|
||||
<i>DroidFish</i> es un derivado Android del famoso motor de ajedrez <i>stockfish 2.2.1</i> . \
|
||||
<i>Stockfish</i> es uno de los motores de ajedrez más fuertes del mundo. \
|
||||
En su versión Android, a menudo profundiza 15 ply e incluso más, con un procesador Snapdragon a 1GHz.\n\
|
||||
\n\
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
|
||||
<string name="about_info">\
|
||||
<b>About</b>\n\
|
||||
<i>DroidFish</i> is an Android port of the famous <i>stockfish 2.2</i> chess engine. \
|
||||
<i>DroidFish</i> is an Android port of the famous <i>stockfish 2.2.1</i> chess engine. \
|
||||
<i>Stockfish</i> is one of the strongest chess engines in the world. \
|
||||
The Android version can often search 15 ply or deeper on a 1GHz Snapdragon CPU.\n\
|
||||
\n\
|
||||
|
|
Loading…
Reference in New Issue
Block a user