Now that we have just two mutually exclusive thread's states
we can repleace them by a simple boolean.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that Rml ordering is based on normal MovePicker logic,
apart for the ttMove that is given, we can avoid to score
all the root moves at depth 1. We only need it for easy move
detection logic, but in this case we just need to score the
first two best moves and not all the Rml set.
No regression after 6400 games
Mod vs Orig 1052 1012 4336 ELO +2 (+- 4.9)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Allocation of pawn and material hash tables should
be strictly bounded to the change of the number of
activeThreads, so move the code inside set_size().
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Use proper way to detect for thread terimnation instead of
our homegrown flag.
It adds more code than it removes and adds also platform specific
code, neverthless I think is the way to go becuase Thread::TERMINATED
flag is intrinsecly racy given that when we raise it thread is still
_not_ terminated nor it can be, and also we don't want to reinvent
the (broken) wheel of thread termination detection when there is
already available the proper one.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Was used to prevent issues when creating multiple threads
on Windows, but now it seems we can remove it safely.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we can split at root it happens that SendSearchedNodes
works only once at the end of the iteration, but this is useless
becuase speed info is sent anyhow toghter with the pv line.
So retire for now, waiting to find something SMP compatible.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Change qsearch() to reflect alpha update logic
of search().
To be consistent changed also moves loop condition and
futility pruning condition.
No regression after 5072 games at TC 10"+0.1
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Start a slave as soon as is allocated.
No functional change with faked split.
Regression tested the full split() series and after
2000 games no regression and no crash.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When calling split or we immediately return because unable to
find available slaves, or we start searching on _all_ the moves
of the node or until a cut-off occurs, so that when returning
from split we immediately leave the moves loop.
Because of this we don't need to change alpha inside split() and
we can use a signature similar to search() so to better clarify
that split() is actually a search on the remaining node's moves.
No functional change with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Allocate and initialize a new split point
out of lock becuase modified data is local to
master thread only.
Also better document why we need a lock at
the end of split().
No functional change with faked split.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
When StopRequest is raised we cannot immediately exit the
move loop but first we need to update bestValue so to avoid
assert:
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that we don't special case the root moves anymore
we don't need to pass NodeType anymore as template parameter,
a simple bool to detect a SpNode will be enough.
Spotted by Joona.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After issuing "go"-command, at the end of the search
SF shows: "Unknown command: ...".
Spotted by Joona.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Instead of our home grown function to perform a case
insensitive compare on option names as required by UCI
protocol.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems FritzGUI already remembers the old lines, so
we just need to update PV info only for the new lines.
Also introduced prevScore field in RootMove to avoid
a bulk copy of Rml.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This should fix following issue:
Suppose the search with MultiPVIteration == 0 returns an exact score
move = Nxf4, score = 100
Now search with MultiPVIteration == 1 and get two scores
move = Qg8, score = 150
move = Ra1, score = 180
If we now reorder all the moves in one step we end up with
pv[0] = Ra1, pv[1] = Qg8
Instead reordering as the current patch we end up in:
pv[0] = Ra1, pv[1] = Nxf4
preserving the first searched move.
No functional change in single PV.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
As a side effect now root position can be directly
allocated on the stack and doesn't need to be defined
static anymore.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is misnamed because it is not a parser, perhaps a
tokenizer, anyhow better call it for what it is, an
input string stream.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Return the correct number of played plies at the end
of the setup moves. Currently it always returns 0 when
starting from start position, like in real games.
We fix this adding st->pliesFromNull that starts from 0
and is incremented after each setup move and is never
reset in the setup phase but only once search is started.
It is an hack because startpos_ply_counter() will return
different values during the search and is correct only
at the beginning of the search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This fixes a regression on real games due to the fact that
we have some mismatches:
history[st->gamePly - i] != stp->key
when st->gamePly - i == 0,this is due to a nasty bug I have
introduced when using std::vector<> as StateInfo backup. The
point is that StateInfo keeps inside a pointer to the previous
StateInfo in a kind of linked list. But when std::vector<> is
resized reallocates a larger chunk of memory and moves the
data there so these pointers became stale.
This patch fixes the issue.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We just need startup value to calculate available
thinking time. So remove from state.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Avoid the ugly and anyhow incorrect hard limit on the
maximum number of moves and allow to handle an arbitrary
number of moves to search.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This allow to retire do_setup_move() and also to simplify
draw detection logic becuase now we always have:
Min(st->rule50, st->gamePly) = st->rule50
This was already true when starting from starting position,
but now is true even when starting from a FEN string because
now we take in account fullmove number in counting gamePly so
that it is always.
st->rule50 <= st->gamePly
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We have a bug (possibly because of returning draw from
root move list), it is possible to see when looking at
games with a GUI, we can see rarely but consistently the
score return as #0 for many depths until it comes back to
normal values.
Revert patches until it is not fixed.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Running following command:
position startpos moves e1e8
Makes SF to assert in debug mode in do_move() but to accept
bad input and continue in release mode where probably it is
going to crash little later.
So validate input before to feed do_move().
Suggestion by Yakovlev Vadim.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It's only necessary to do the checking at the end of every non-const
member (including the constructors and from_fen()) of class Position.
Once the post-condition of every modifier guarantees the class invariant,
we don't need to verify sanity of the position as preconditions for outside
callers such as movegen, search etc. For non-class types such as Move and
Square we still need to assert of course.
Suggested by Rein Halbersma.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
After previous patch is no more needed to pass
the color, becuase it is always the side to move.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It worked by accident because we always called both directions,
but definition was wrong.
Functional change due to different generation order, but
perft numbers are the correct ones.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Functional change due to the fact that now pick_best() is
stable, but should be no change in strenght.
Example code and ideas by Rein Halbersma.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And pass correct currentPly to TimeManager::init().
This restores old behaviour, in particular now black has
a different timing than white becuase is no more:
currentPly = 2 * fullMoveNumber;
but becomes
2 * (fullMoves - 1) + int(sideToMove == BLACK)
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
No functional change also in faked split mode
To be sure verified in real games with 4 threads TC 2"+0.1
After 11125 games 2497 - 2469 - 6159 ELO +0 (+- 4.4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Fix also an incredible 3% speed regression by an almost
never called function. I guess this is due to mingw very low
quality standard libraries implementation.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And also tolerate a 0 value for full move number.
Revert BUG_41 patch, now we set initial King file only
if a castling is possible, so we don't need the fix
anymore in case of correct FEN.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
If we cannot castle castleRightsMask[] could be not valid,
for instance when king initial file is FILE_A as queen rook.
In this case castleRightsMask[] at initialQRFile is different
from the expected (ALL_CASTLES ^ WHITE_OOO).
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
See:
http://talkchess.com/forum/viewtopic.php?t=39327
After 8130 games on QUAD at 20"+0.1
1342 - 1359 - 5429 ELO +0 (+- 4.4)
Tried also version with just king settings changed:
After 5932 games 962 - 1052 - 3918 ELO -5 (+- 5.2)
And with just mobility settings changed:
After 4114 games 618 - 619 - 2877 ELO +0 (+- 5.9)
Frank has tested only 1200 games, but at longer TC and
against many engines, so because PHQ results are not worst
than other combination and not worst than original let's
commit his version.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We miss to account as a capture a promotion capture !
Incredible bug in this critical function that is here
since a long time (b50921fd5c of 21/10/2009 !!)
This patch fixes the bug and readds the faster
move_is_capture_or_promotion() that slightly increases
overall speed.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is now much more modular than before and also we
always send the seldepth when we send the depth, this
avoids to make seldepth disappearing from GUI at the
start of a new iteration.
Print also fails high/low pv lines at high enough
search depths.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Easy, almost trivial simplification, I don't understand
how I missed this before !!
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This trivial change gives an impressive 2,5% speedup !!!!
Also retire one unused move_gives_check() overload.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Restore original behaviour, before root unification and
remove a now useless ugly hack for alpha in multi-pv case.
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is not correct to use an iterator stick on a vector that
is sorted becuase iterator is invalidated in general case.
It happens to work by accident because iterators are implemented
as pointers and so they behave in the same (correct) way then
using array indices, but the latters are the correct thing to use.
Also better document the code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It is a fossil from the root_search() era, no more
needed today.
Spotted by Onno
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This avoids search explosion in qsearch for some
patological cases like:
r1n1n1b1/1P1P1P1P/1N1N1N2/2RnQrRq/2pKp3/3BNQbQ/k7/4Bq2 w - - 0 1
After 9078 games 20"+0.1 QUAD:
Mod vs Orig 1413 - 1319 - 6346 ELO +3 (+- 4)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The trick is to classify more position at first cycle,
so to reduce following work. Speed up is of about 50% !
Also some cleanup while there.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Seems there is no regression so prefer to prune less.
After 8278 games
Mod vs Orig 1246 - 1265 - 5767 +0 ELO (+- 4.2)
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We should start from i = 0, it works by accident because
static storage BSFTable[] is init to zero by default.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In case we have more than one promotion move, prefer
the one that captures the biggest piece.
Almost no functional change, anyhow I don't expect any
ELO change, it is just the correct thing to do.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>