Page 1 of 2

Arasan 20.1

Posted: Fri Apr 28, 2017 10:41 pm
by jdart
Arasan 20.1 is available from https://www.arasanchess.org.

Changes in Arasan 20.1:

1) Fixes to UCI multipv handling.
2) Fix logic for terminating search on tablebase hit.
3) Bug fixes in parameter tuning code. Use actual sigmoid function when
tuning king safety, not an approximated lookup table.
4) Add file-dependent scoring for passed pawns.
5) Fix bug in scoring for rooks behind passed pawns.
6) Allow setting Arasan version string on make command line. Builds done
between release tags now have versions generated from git commit # (if
done from a git repository).
7) In UCI mode, return a move even in cases where a legal draw position
(according to 3-move rule) exists before search is started. Fixes problems
with some UCI UIs.
8) Allow LMR of some evasion moves.
9) Remove "forced move" extension (1 single reply to check).
10) More code cleanup and conversion to C++ 11.
11) Some Android portability fixes. Note: Android build still not fully
supported.

This release uses a modified version of the Fathom library (with portability and code fixes) for access to Syzygy tablebases. If you are interested in that code as a separate package, it is available from https://github.com/jdart1/Fathom.

This version is significantly stronger than 20.0 in my testing.

Blitz results against some comparable engines:

Code: Select all

Rank Name                         Elo    +    - games score oppo. draws 
   1 Stockfish-2.2               2479   19   19   600   63%  2400   44% 
   2 Texel-1.06                  2460   20   19   600   59%  2400   36% 
   3 Arasan 20.1                 2400    9    9  3000   50%  2400   40% 
   4 Senpai-1.0                  2394   19   19   600   49%  2400   38% 
   5 Arasan-19.2                 2362   18   19   600   44%  2400   50% 
   6 Crafty-25.2                 2305   20   20   600   36%  2400   34% 
--Jon

Re: Arasan 20.1

Posted: Fri Apr 28, 2017 11:31 pm
by Dann Corbit
Thanks for the new version.

Re: Arasan 20.1

Posted: Sat Apr 29, 2017 1:06 am
by MikeB
Thanks - very nice progress. Long time fan of Arasan, a very long time. I can still recall playing it on a PC around 1994 back in the day when it had its own interface. Could actually beat it now and then, impossible now of course.

Re: Arasan 20.1

Posted: Sat Apr 29, 2017 4:05 am
by Dann Corbit
I notice that your null reductions are purely depth based.

A smooth scaling alternative similar to the Stockfish formula, bt a bit more aggressive to more closely mirror the Arasan reductions:

Code: Select all

#ifdef SS
        int R = ((1024 + 64 * depth / DEPTH_INCREMENT) / 256 + std::min((node->eval - node->beta) / PAWN_VALUE, 3)) * DEPTH_INCREMENT;
		nu_depth = depth - R;
#else
		nu_depth = depth - 4*DEPTH_INCREMENT - depth/6;
#endif
seems to be doing well in my tests.

Have you tried this sort of reduction that also takes into account the distance to beta before?

Re: Arasan 20.1

Posted: Sat Apr 29, 2017 4:30 am
by jdart
Yes, I have tried it. It was taken out in version 18.0.

May possibly be worth re-visiting but if I remember right it had no or minimal gain.

--Jon

Re: Arasan 20.1

Posted: Sat Apr 29, 2017 4:47 am
by Dann Corbit
jdart wrote:Yes, I have tried it. It was taken out in version 18.0.

May possibly be worth re-visiting but if I remember right it had no or minimal gain.

--Jon
I don't have a lot of games. I also think that using the Arasan book may have tossed in a wrench, because I noticed that sometimes Arasan fell out of book a little lopsided, so that may possibly have lead to the advantage.
I am repeating the experiment now with no book. Real early, but SS has a small lead.

It's probably a fiddly thing to tune for each engine. It also depends on having a decent estimate of the score, so IID helps if I recall correctly. And if IID is not called for due to node type or whatever, an eval call is better than nothing.

I noticed that your null move margin was pretty large compared to other engines, at least at shallow depths. I did not examine to see what happens when the depths are larger.

Re: Arasan 20.1

Posted: Sat Apr 29, 2017 8:53 am
by Damir
Thanks for the new version Jon. :)

Re: Arasan 20.1

Posted: Mon May 01, 2017 9:12 pm
by Dann Corbit
After 914 games, run over the weekend at time control 60 + 1:

Code: Select all

  Program           Elo    +   -   Games   Score   Av.Op.  Draws
1 Arasanx-64-ss   : 2923   17  17   914    56.5 %   2877   44.9 %
2 Arasanx-64-std  : 2877   17  17   914    43.5 %   2923   44.9 %
The ss version has the smooth scaling adaptation.

Note that I did not tune the constants at all, so I guess it can be made a lot better.

I simply did a crude attempt to approximate the normal Arasan aggressive pruning.

+46 Elo is well beyond the two standard deviation error bars, but I admit that 914 games is a pretty small dose.

The code patch:

Code: Select all

#ifdef SS
        int R = ((1024 + 64 * depth / DEPTH_INCREMENT) / 256 + std::min((node->eval - node->beta) / PAWN_VALUE, 3)) * DEPTH_INCREMENT;
		nu_depth = depth - R;
#else
		nu_depth = depth - 4*DEPTH_INCREMENT - depth/6;
#endif
I also fudged a little bit to chose constants that were powers of 2, because the compiler can probably do some math shortcuts with them, though I did not look at the assembly to see if the calculation was actually more efficient.

Re: Arasan 20.1

Posted: Tue May 02, 2017 4:04 am
by jdart
I will give it a try. I am being very picky lately and wanting only to accept changes that pass both self-play and also improve in a gauntlet match.

--Jon

Re: Arasan 20.1

Posted: Tue May 02, 2017 4:43 am
by Dann Corbit
jdart wrote:I will give it a try. I am being very picky lately and wanting only to accept changes that pass both self-play and also improve in a gauntlet match.

--Jon
Due to the nature of the formula, I think it may be difficult to test effectively at ultra high speed.

It appears to me that there are three numbers of interest:

Code: Select all

   int depth_constant = 1024; // depth constant factor
   int depth_multiplier = 64; // depth slope factor
   float ceiling = 3.0; // 3 pawns difference lid

/*  Loop that alters the constants goes here... */  

...
   int R = ((depth_constant + depth_multiplier * depth / DEPTH_INCREMENT) / 256 + std::min(float(node->eval - node->beta) / PAWN_VALUE, ceiling)) * DEPTH_INCREMENT; 
The float bit is temporary, just to see if fractional parts {in pawns} are highly important for the score difference. Once you find an optimal value, just use an integral equivalent