mirror of
https://github.com/sockspls/badfish
synced 2025-07-12 12:09:14 +00:00
Merge branch 'master' into clusterMergeMaster8
This commit is contained in:
commit
8ec5faa46e
42 changed files with 771 additions and 604 deletions
|
@ -1,5 +1,4 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
sudo: required
|
|
||||||
dist: xenial
|
dist: xenial
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
|
63
AUTHORS
63
AUTHORS
|
@ -1,4 +1,4 @@
|
||||||
# List of authors for Stockfish, updated for version 10
|
# List of authors for Stockfish, as of January 7, 2020
|
||||||
|
|
||||||
Tord Romstad (romstad)
|
Tord Romstad (romstad)
|
||||||
Marco Costalba (mcostalba)
|
Marco Costalba (mcostalba)
|
||||||
|
@ -22,18 +22,23 @@ Auguste Pop
|
||||||
Balint Pfliegel
|
Balint Pfliegel
|
||||||
Ben Koshy (BKSpurgeon)
|
Ben Koshy (BKSpurgeon)
|
||||||
Bill Henry (VoyagerOne)
|
Bill Henry (VoyagerOne)
|
||||||
|
Bojun Guo (noobpwnftw, Nooby)
|
||||||
braich
|
braich
|
||||||
Bojun Guo (noobpwnftw)
|
Brian Sheppard (SapphireBrand, briansheppard-toast)
|
||||||
Brian Sheppard (SapphireBrand)
|
|
||||||
Bryan Cross (crossbr)
|
Bryan Cross (crossbr)
|
||||||
|
candirufish
|
||||||
|
Chess13234
|
||||||
Chris Cain (ceebo)
|
Chris Cain (ceebo)
|
||||||
Dan Schmidt
|
Dan Schmidt (dfannius)
|
||||||
|
Daniel Axtens (daxtens)
|
||||||
Daniel Dugovic (ddugovic)
|
Daniel Dugovic (ddugovic)
|
||||||
Dariusz Orzechowski
|
Dariusz Orzechowski
|
||||||
David Zar
|
David Zar
|
||||||
Daylen Yang (daylen)
|
Daylen Yang (daylen)
|
||||||
DiscanX
|
DiscanX
|
||||||
Eelco de Groot
|
double-beep
|
||||||
|
Eduardo Cáceres (eduherminio)
|
||||||
|
Eelco de Groot (KingDefender)
|
||||||
Elvin Liu (solarlight2)
|
Elvin Liu (solarlight2)
|
||||||
erbsenzaehler
|
erbsenzaehler
|
||||||
Ernesto Gatti
|
Ernesto Gatti
|
||||||
|
@ -60,17 +65,18 @@ Jacques B. (Timshel)
|
||||||
Jan Ondruš (hxim)
|
Jan Ondruš (hxim)
|
||||||
Jared Kish (Kurtbusch)
|
Jared Kish (Kurtbusch)
|
||||||
Jarrod Torriero (DU-jdto)
|
Jarrod Torriero (DU-jdto)
|
||||||
Jean Gauthier (QuaisBla)
|
Jean Gauthier (OuaisBla)
|
||||||
Jean-Francois Romang (jromang)
|
Jean-Francois Romang (jromang)
|
||||||
|
Jekaa
|
||||||
Jerry Donald Watson (jerrydonaldwatson)
|
Jerry Donald Watson (jerrydonaldwatson)
|
||||||
Jonathan Calovski (Mysseno)
|
Jonathan Calovski (Mysseno)
|
||||||
Jonathan D. (SFisGOD)
|
Jonathan Dumale (SFisGOD)
|
||||||
Joost VandeVondele (vondele)
|
Joost VandeVondele (vondele)
|
||||||
Jörg Oster (joergoster)
|
Jörg Oster (joergoster)
|
||||||
Joseph Ellis (jhellis3)
|
Joseph Ellis (jhellis3)
|
||||||
Joseph R. Prostko
|
Joseph R. Prostko
|
||||||
jundery
|
jundery
|
||||||
Justin Blanchard
|
Justin Blanchard (UncombedCoconut)
|
||||||
Kelly Wilson
|
Kelly Wilson
|
||||||
Ken Takusagawa
|
Ken Takusagawa
|
||||||
kinderchocolate
|
kinderchocolate
|
||||||
|
@ -78,23 +84,27 @@ Kiran Panditrao (Krgp)
|
||||||
Kojirion
|
Kojirion
|
||||||
Leonardo Ljubičić (ICCF World Champion)
|
Leonardo Ljubičić (ICCF World Champion)
|
||||||
Leonid Pechenik (lp--)
|
Leonid Pechenik (lp--)
|
||||||
Linus Arver
|
Linus Arver (listx)
|
||||||
loco-loco
|
loco-loco
|
||||||
Lub van den Berg (ElbertoOne)
|
Lub van den Berg (ElbertoOne)
|
||||||
Luca Brivio (lucabrivio)
|
Luca Brivio (lucabrivio)
|
||||||
Lucas Braesch (lucasart)
|
Lucas Braesch (lucasart)
|
||||||
Lyudmil Antonov (lantonov)
|
Lyudmil Antonov (lantonov)
|
||||||
Maciej Żenczykowski (zenczykowski)
|
Maciej Żenczykowski (zenczykowski)
|
||||||
Matthew Lai (matthewlai)
|
Malcolm Campbell (xoto10)
|
||||||
Matthew Sullivan
|
|
||||||
Mark Tenzer (31m059)
|
Mark Tenzer (31m059)
|
||||||
|
marotear
|
||||||
|
Matthew Lai (matthewlai)
|
||||||
|
Matthew Sullivan (Matt14916)
|
||||||
|
Michael An (man)
|
||||||
Michael Byrne (MichaelB7)
|
Michael Byrne (MichaelB7)
|
||||||
Michael Stembera (mstembera)
|
|
||||||
Michael Chaly (Vizvezdenec)
|
Michael Chaly (Vizvezdenec)
|
||||||
|
Michael Stembera (mstembera)
|
||||||
|
Michael Whiteley (protonspring)
|
||||||
Michel Van den Bergh (vdbergh)
|
Michel Van den Bergh (vdbergh)
|
||||||
Miguel Lahoz (miguel-l)
|
Miguel Lahoz (miguel-l)
|
||||||
Mikael Bäckman (mbootsector)
|
Mikael Bäckman (mbootsector)
|
||||||
Michael Whiteley (protonspring)
|
Mira
|
||||||
Miroslav Fontán (Hexik)
|
Miroslav Fontán (Hexik)
|
||||||
Moez Jellouli (MJZ1977)
|
Moez Jellouli (MJZ1977)
|
||||||
Mohammed Li (tthsqe12)
|
Mohammed Li (tthsqe12)
|
||||||
|
@ -102,9 +112,11 @@ Nathan Rugg (nmrugg)
|
||||||
Nick Pelling (nickpelling)
|
Nick Pelling (nickpelling)
|
||||||
Nicklas Persson (NicklasPersson)
|
Nicklas Persson (NicklasPersson)
|
||||||
Niklas Fiekas (niklasf)
|
Niklas Fiekas (niklasf)
|
||||||
|
Nikolay Kostov (NikolayIT)
|
||||||
Ondrej Mosnáček (WOnder93)
|
Ondrej Mosnáček (WOnder93)
|
||||||
Oskar Werkelin Ahlin
|
Oskar Werkelin Ahlin
|
||||||
Pablo Vazquez
|
Pablo Vazquez
|
||||||
|
Panthee
|
||||||
Pascal Romaret
|
Pascal Romaret
|
||||||
Pasquale Pigazzini (ppigazzini)
|
Pasquale Pigazzini (ppigazzini)
|
||||||
Patrick Jansen (mibere)
|
Patrick Jansen (mibere)
|
||||||
|
@ -117,24 +129,35 @@ Reuven Peleg
|
||||||
Richard Lloyd
|
Richard Lloyd
|
||||||
Rodrigo Exterckötter Tjäder
|
Rodrigo Exterckötter Tjäder
|
||||||
Ron Britvich (Britvich)
|
Ron Britvich (Britvich)
|
||||||
Ronald de Man (syzygy1)
|
Ronald de Man (syzygy1, syzygy)
|
||||||
Ryan Schmitt
|
Ryan Schmitt
|
||||||
Ryan Takker
|
Ryan Takker
|
||||||
|
Sami Kiminki (skiminki)
|
||||||
Sebastian Buchwald (UniQP)
|
Sebastian Buchwald (UniQP)
|
||||||
Sergei Antonov (saproj)
|
Sergei Antonov (saproj)
|
||||||
|
Sergei Ivanov (svivanov72)
|
||||||
sf-x
|
sf-x
|
||||||
shane31
|
Shane Booth (shane31)
|
||||||
Steinar Gunderson (sesse)
|
|
||||||
Stefan Geschwentner (locutus2)
|
Stefan Geschwentner (locutus2)
|
||||||
Stefano Cardanobile (Stefano80)
|
Stefano Cardanobile (Stefano80)
|
||||||
|
Steinar Gunderson (sesse)
|
||||||
Stéphane Nicolet (snicolet)
|
Stéphane Nicolet (snicolet)
|
||||||
Thanar2
|
Thanar2
|
||||||
thaspel
|
thaspel
|
||||||
|
theo77186
|
||||||
|
Tom Truscott
|
||||||
Tom Vijlbrief (tomtor)
|
Tom Vijlbrief (tomtor)
|
||||||
Torsten Franz (torfranz)
|
Torsten Franz (torfranz, tfranzer)
|
||||||
|
Tracey Emery (basepr1me)
|
||||||
Uri Blass (uriblass)
|
Uri Blass (uriblass)
|
||||||
Vince Negri
|
Vince Negri (cuddlestmonkey)
|
||||||
|
|
||||||
# Additionally, we acknowledge the authors of fishtest,
|
|
||||||
# an essential framework for the development of Stockfish:
|
# Additionally, we acknowledge the authors and maintainers of fishtest,
|
||||||
|
# an amazing and essential framework for the development of Stockfish!
|
||||||
|
#
|
||||||
# https://github.com/glinscott/fishtest/blob/master/AUTHORS
|
# https://github.com/glinscott/fishtest/blob/master/AUTHORS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
Readme.md
16
Readme.md
|
@ -181,6 +181,14 @@ compile (for instance with Microsoft MSVC) you need to manually
|
||||||
set/unset some switches in the compiler command line; see file *types.h*
|
set/unset some switches in the compiler command line; see file *types.h*
|
||||||
for a quick reference.
|
for a quick reference.
|
||||||
|
|
||||||
|
When reporting an issue or a bug, please tell us which version and
|
||||||
|
compiler you used to create your executable. These informations can
|
||||||
|
be found by typing the following commands in a console:
|
||||||
|
|
||||||
|
```
|
||||||
|
./stockfish
|
||||||
|
compiler
|
||||||
|
```
|
||||||
|
|
||||||
## Understanding the code base and participating in the project
|
## Understanding the code base and participating in the project
|
||||||
|
|
||||||
|
@ -190,12 +198,12 @@ community effort. There are a few ways to help contribute to its growth.
|
||||||
### Donating hardware
|
### Donating hardware
|
||||||
|
|
||||||
Improving Stockfish requires a massive amount of testing. You can donate
|
Improving Stockfish requires a massive amount of testing. You can donate
|
||||||
your hardware resources by installing the [Fishtest Worker](https://github.com/glinscott/fishtest/wiki/Running-the-worker)
|
your hardware resources by installing the [Fishtest Worker](https://github.com/glinscott/fishtest/wiki/Running-the-worker:-overview)
|
||||||
and view the current tests on [Fishtest](http://tests.stockfishchess.org/tests).
|
and view the current tests on [Fishtest](https://tests.stockfishchess.org/tests).
|
||||||
|
|
||||||
### Improving the code
|
### Improving the code
|
||||||
|
|
||||||
If you want to help improve the code, there are several valuable ressources:
|
If you want to help improve the code, there are several valuable resources:
|
||||||
|
|
||||||
* [In this wiki,](https://www.chessprogramming.org) many techniques used in
|
* [In this wiki,](https://www.chessprogramming.org) many techniques used in
|
||||||
Stockfish are explained with a lot of background information.
|
Stockfish are explained with a lot of background information.
|
||||||
|
@ -207,7 +215,7 @@ Nevertheless, a helpful resource.
|
||||||
|
|
||||||
* The latest source can always be found on [GitHub](https://github.com/official-stockfish/Stockfish).
|
* The latest source can always be found on [GitHub](https://github.com/official-stockfish/Stockfish).
|
||||||
Discussions about Stockfish take place in the [FishCooking](https://groups.google.com/forum/#!forum/fishcooking)
|
Discussions about Stockfish take place in the [FishCooking](https://groups.google.com/forum/#!forum/fishcooking)
|
||||||
group and engine testing is done on [Fishtest](http://tests.stockfishchess.org/tests).
|
group and engine testing is done on [Fishtest](https://tests.stockfishchess.org/tests).
|
||||||
If you want to help improve Stockfish, please read this [guideline](https://github.com/glinscott/fishtest/wiki/Creating-my-first-test)
|
If you want to help improve Stockfish, please read this [guideline](https://github.com/glinscott/fishtest/wiki/Creating-my-first-test)
|
||||||
first, where the basics of Stockfish development are explained.
|
first, where the basics of Stockfish development are explained.
|
||||||
|
|
||||||
|
|
|
@ -1,146 +1,154 @@
|
||||||
Contributors with >10,000 CPU hours as of November 4, 2018
|
Contributors with >10,000 CPU hours as of January 7, 2020
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
Username CPU Hours Games played
|
Username CPU Hours Games played
|
||||||
noobpwnftw 3730975 292309380
|
--------------------------------------------------
|
||||||
mibere 535242 43333774
|
noobpwnftw 9305707 695548021
|
||||||
crunchy 375564 29121434
|
mlang 780050 61648867
|
||||||
cw 371664 28748719
|
dew 621626 43921547
|
||||||
fastgm 318178 22283584
|
mibere 524702 42238645
|
||||||
JojoM 295354 20958931
|
crunchy 354587 27344275
|
||||||
dew 215476 17079219
|
cw 354495 27274181
|
||||||
ctoks 214031 17312035
|
fastgm 332801 22804359
|
||||||
glinscott 204517 13932027
|
JojoM 295750 20437451
|
||||||
bking_US 187568 12233168
|
CSU_Dynasty 262015 21828122
|
||||||
velislav 168404 13336219
|
Fisherman 232181 18939229
|
||||||
CSU_Dynasty 168069 14417712
|
ctoks 218866 17622052
|
||||||
Thanar 162373 13842179
|
glinscott 201989 13780820
|
||||||
spams 149531 10940322
|
tvijlbrief 201204 15337115
|
||||||
Fisherman 141137 12099359
|
velislav 188630 14348485
|
||||||
drabel 134441 11180178
|
gvreuls 187164 15149976
|
||||||
leszek 133658 9812120
|
bking_US 180289 11876016
|
||||||
marrco 133566 10115202
|
nordlandia 172076 13467830
|
||||||
sqrt2 128420 10022279
|
leszek 157152 11443978
|
||||||
vdbergh 123230 9200516
|
Thanar 148021 12365359
|
||||||
tvijlbrief 123007 9498831
|
spams 141975 10319326
|
||||||
vdv 120381 8555423
|
drabel 138073 11121749
|
||||||
malala 117291 8126488
|
vdv 137850 9394330
|
||||||
dsmith 114010 7622414
|
mgrabiak 133578 10454324
|
||||||
BrunoBanani 104938 7448565
|
TueRens 132485 10878471
|
||||||
CoffeeOne 100042 4593596
|
bcross 129683 11557084
|
||||||
Data 94621 8433010
|
marrco 126078 9356740
|
||||||
mgrabiak 92248 7787406
|
sqrt2 125830 9724586
|
||||||
bcross 89440 8506568
|
robal 122873 9593418
|
||||||
brabos 81868 6647613
|
vdbergh 120766 8926915
|
||||||
BRAVONE 80811 5341681
|
malala 115926 8002293
|
||||||
psk 77195 6156031
|
CoffeeOne 114241 5004100
|
||||||
nordlandia 74833 6231930
|
dsmith 113189 7570238
|
||||||
robal 72818 5969856
|
BrunoBanani 104644 7436849
|
||||||
TueRens 72523 6383294
|
Data 92328 8220352
|
||||||
sterni1971 71049 5647590
|
mhoram 89333 6695109
|
||||||
sunu 65855 5360884
|
davar 87924 7009424
|
||||||
mhoram 65034 5192880
|
xoto 81094 6869316
|
||||||
davar 64794 5457564
|
ElbertoOne 80899 7023771
|
||||||
nssy 64607 5371952
|
grandphish2 78067 6160199
|
||||||
Pking_cda 64499 5704075
|
brabos 77212 6186135
|
||||||
biffhero 63557 5480444
|
psk 75733 5984901
|
||||||
teddybaer 62147 5585620
|
BRAVONE 73875 5054681
|
||||||
solarlight 61278 5402642
|
sunu 70771 5597972
|
||||||
ElbertoOne 60156 5504304
|
sterni1971 70605 5590573
|
||||||
jromang 58854 4704502
|
MaZePallas 66886 5188978
|
||||||
dv8silencer 57421 3961325
|
Vizvezdenec 63708 4967313
|
||||||
tinker 56039 4204914
|
nssy 63462 5259388
|
||||||
Freja 50331 3808121
|
jromang 61634 4940891
|
||||||
renouve 50318 3544864
|
teddybaer 61231 5407666
|
||||||
robnjr 47504 4131742
|
Pking_cda 60099 5293873
|
||||||
grandphish2 47377 4110003
|
solarlight 57469 5028306
|
||||||
eva42 46857 4075716
|
dv8silencer 56913 3883992
|
||||||
ttruscott 46802 3811534
|
tinker 54936 4086118
|
||||||
finfish 46244 3481661
|
renouve 49732 3501516
|
||||||
rap 46201 3219490
|
Freja 49543 3733019
|
||||||
ronaldjerum 45641 3964331
|
robnjr 46972 4053117
|
||||||
xoto 44998 4170431
|
rap 46563 3219146
|
||||||
gvreuls 44359 3902234
|
Bobo1239 46036 3817196
|
||||||
bigpen0r 41780 3448224
|
ttruscott 45304 3649765
|
||||||
Bobo1239 40767 3657490
|
racerschmacer 44881 3975413
|
||||||
Antihistamine 39218 2792761
|
finfish 44764 3370515
|
||||||
mhunt 38991 2697512
|
eva42 41783 3599691
|
||||||
racerschmacer 38929 3756111
|
biffhero 40263 3111352
|
||||||
VoyagerOne 35896 3378887
|
bigpen0r 39817 3291647
|
||||||
homyur 35561 3012398
|
mhunt 38871 2691355
|
||||||
rkl 33217 2978536
|
ronaldjerum 38820 3240695
|
||||||
pb00067 33034 2803485
|
Antihistamine 38785 2761312
|
||||||
speedycpu 32043 2531964
|
pb00067 38038 3086320
|
||||||
SC 31954 2848432
|
speedycpu 37591 3003273
|
||||||
EthanOConnor 31638 2143255
|
rkl 37207 3289580
|
||||||
oryx 30962 2899534
|
VoyagerOne 37050 3441673
|
||||||
gri 30108 2429137
|
jbwiebe 35320 2805433
|
||||||
csnodgrass 29396 2808611
|
cuistot 34191 2146279
|
||||||
Garf 28887 2873564
|
homyur 33927 2850481
|
||||||
Pyafue 28885 1986098
|
manap 32873 2327384
|
||||||
jkiiski 28014 1923255
|
gri 32538 2515779
|
||||||
slakovv 27017 2031279
|
oryx 31267 2899051
|
||||||
Prcuvu 26300 2307154
|
EthanOConnor 30959 2090311
|
||||||
hyperbolic.tom 26248 2200777
|
SC 30832 2730764
|
||||||
jbwiebe 25663 2129063
|
csnodgrass 29505 2688994
|
||||||
anst 25525 2279159
|
jmdana 29458 2205261
|
||||||
Patrick_G 24222 1835674
|
strelock 28219 2067805
|
||||||
nabildanial 23524 1586321
|
jkiiski 27832 1904470
|
||||||
achambord 23495 1942546
|
Pyafue 27533 1902349
|
||||||
Sharaf_DG 22975 1790697
|
Garf 27515 2747562
|
||||||
chriswk 22876 1947731
|
eastorwest 27421 2317535
|
||||||
ncfish1 22689 1830009
|
slakovv 26903 2021889
|
||||||
cuistot 22201 1383031
|
Prcuvu 24835 2170122
|
||||||
Zirie 21171 1493227
|
anst 24714 2190091
|
||||||
Isidor 20634 1736219
|
hyperbolic.tom 24319 2017394
|
||||||
JanErik 20596 1791991
|
Patrick_G 23687 1801617
|
||||||
xor12 20535 1819280
|
Sharaf_DG 22896 1786697
|
||||||
team-oh 20364 1653708
|
nabildanial 22195 1519409
|
||||||
nesoneg 20264 1493435
|
chriswk 21931 1868317
|
||||||
dex 20110 1682756
|
achambord 21665 1767323
|
||||||
rstoesser 19802 1335177
|
Zirie 20887 1472937
|
||||||
Vizvezdenec 19750 1695579
|
team-oh 20217 1636708
|
||||||
eastorwest 19531 1841839
|
Isidor 20096 1680691
|
||||||
sg4032 18913 1720157
|
ncfish1 19931 1520927
|
||||||
horst.prack 18425 1708197
|
nesoneg 19875 1463031
|
||||||
cisco2015 18408 1793774
|
Spprtr 19853 1548165
|
||||||
ianh2105 18133 1668562
|
JanErik 19849 1703875
|
||||||
MazeOfGalious 18022 1644593
|
agg177 19478 1395014
|
||||||
ville 17900 1539130
|
SFTUser 19231 1567999
|
||||||
j3corre 17607 975954
|
xor12 19017 1680165
|
||||||
eudhan 17502 1424648
|
sg4032 18431 1641865
|
||||||
jmdana 17351 1287546
|
rstoesser 18118 1293588
|
||||||
iisiraider 17175 1118788
|
MazeOfGalious 17917 1629593
|
||||||
jundery 17172 1115855
|
j3corre 17743 941444
|
||||||
wei 16852 1822582
|
cisco2015 17725 1690126
|
||||||
SFTUser 16635 1363975
|
ianh2105 17706 1632562
|
||||||
purplefishies 16621 1106850
|
dex 17678 1467203
|
||||||
DragonLord 16599 1252348
|
jundery 17194 1115855
|
||||||
chris 15274 1575333
|
iisiraider 17019 1101015
|
||||||
IgorLeMasson 15201 1364148
|
horst.prack 17012 1465656
|
||||||
dju 15074 914278
|
Adrian.Schmidt123 16563 1281436
|
||||||
Flopzee 14700 1331632
|
purplefishies 16342 1092533
|
||||||
OssumOpossum 14149 1029265
|
wei 16274 1745989
|
||||||
enedene 13762 935618
|
ville 16144 1384026
|
||||||
ako027ako 13442 1250249
|
eudhan 15712 1283717
|
||||||
AdrianSA 13324 924980
|
OuaisBla 15581 972000
|
||||||
bpfliegel 13318 886523
|
DragonLord 15559 1162790
|
||||||
Nikolay.IT 13260 1155612
|
dju 14716 875569
|
||||||
jpulman 12776 854815
|
chris 14479 1487385
|
||||||
joster 12438 988413
|
0xB00B1ES 14079 1001120
|
||||||
fatmurphy 12015 901134
|
OssumOpossum 13776 1007129
|
||||||
Nesa92 11711 1132245
|
enedene 13460 905279
|
||||||
Adrian.Schmidt123 11542 898699
|
bpfliegel 13346 884523
|
||||||
modolief 11228 926456
|
Ente 13198 1156722
|
||||||
Dark_wizzie 11214 1017910
|
IgorLeMasson 13087 1147232
|
||||||
mschmidt 10973 818594
|
jpulman 13000 870599
|
||||||
Andrew Grant 10780 947859
|
ako027ako 12775 1173203
|
||||||
infinity 10762 746397
|
Nikolay.IT 12352 1068349
|
||||||
SapphireBrand 10692 1024604
|
Andrew Grant 12327 895539
|
||||||
Thomas A. Anderson 10553 736094
|
joster 12008 950160
|
||||||
basepi 10434 935168
|
AdrianSA 11996 804972
|
||||||
lantonov 10325 972610
|
Nesa92 11455 1111993
|
||||||
pgontarz 10294 878746
|
fatmurphy 11345 853210
|
||||||
Spprtr 10189 823246
|
Dark_wizzie 11108 1007152
|
||||||
crocogoat 10115 1017325
|
modolief 10869 896470
|
||||||
stocky 10083 718114
|
mschmidt 10757 803401
|
||||||
|
infinity 10594 727027
|
||||||
|
mabichito 10524 749391
|
||||||
|
Thomas A. Anderson 10474 732094
|
||||||
|
thijsk 10431 719357
|
||||||
|
Flopzee 10339 894821
|
||||||
|
crocogoat 10104 1013854
|
||||||
|
SapphireBrand 10104 969604
|
||||||
|
stocky 10017 699440
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -117,7 +117,7 @@ vector<string> setup_bench(const Position& current, istream& is) {
|
||||||
string fenFile = (is >> token) ? token : "default";
|
string fenFile = (is >> token) ? token : "default";
|
||||||
string limitType = (is >> token) ? token : "depth";
|
string limitType = (is >> token) ? token : "depth";
|
||||||
|
|
||||||
go = "go " + limitType + " " + limit;
|
go = limitType == "eval" ? "eval" : "go " + limitType + " " + limit;
|
||||||
|
|
||||||
if (fenFile == "default")
|
if (fenFile == "default")
|
||||||
fens = Defaults;
|
fens = Defaults;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -44,7 +44,7 @@ namespace {
|
||||||
// bit 13-14: white pawn file (from FILE_A to FILE_D)
|
// bit 13-14: white pawn file (from FILE_A to FILE_D)
|
||||||
// bit 15-17: white pawn RANK_7 - rank (from RANK_7 - RANK_7 to RANK_7 - RANK_2)
|
// bit 15-17: white pawn RANK_7 - rank (from RANK_7 - RANK_7 to RANK_7 - RANK_2)
|
||||||
unsigned index(Color us, Square bksq, Square wksq, Square psq) {
|
unsigned index(Color us, Square bksq, Square wksq, Square psq) {
|
||||||
return wksq | (bksq << 6) | (us << 12) | (file_of(psq) << 13) | ((RANK_7 - rank_of(psq)) << 15);
|
return int(wksq) | (bksq << 6) | (us << 12) | (file_of(psq) << 13) | ((RANK_7 - rank_of(psq)) << 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Result {
|
enum Result {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -76,25 +76,29 @@ void Bitboards::init() {
|
||||||
|
|
||||||
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
|
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
|
||||||
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
|
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
|
||||||
SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
|
SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
|
||||||
|
|
||||||
int steps[][5] = { {}, { 7, 9 }, { 6, 10, 15, 17 }, {}, {}, {}, { 1, 7, 8, 9 } };
|
for (Square s = SQ_A1; s <= SQ_H8; ++s)
|
||||||
|
{
|
||||||
|
PawnAttacks[WHITE][s] = pawn_attacks_bb<WHITE>(square_bb(s));
|
||||||
|
PawnAttacks[BLACK][s] = pawn_attacks_bb<BLACK>(square_bb(s));
|
||||||
|
}
|
||||||
|
|
||||||
for (Color c : { WHITE, BLACK })
|
// Helper returning the target bitboard of a step from a square
|
||||||
for (PieceType pt : { PAWN, KNIGHT, KING })
|
auto landing_square_bb = [&](Square s, int step)
|
||||||
for (Square s = SQ_A1; s <= SQ_H8; ++s)
|
{
|
||||||
for (int i = 0; steps[pt][i]; ++i)
|
Square to = Square(s + step);
|
||||||
{
|
return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0);
|
||||||
Square to = s + Direction(c == WHITE ? steps[pt][i] : -steps[pt][i]);
|
};
|
||||||
|
|
||||||
if (is_ok(to) && distance(s, to) < 3)
|
for (Square s = SQ_A1; s <= SQ_H8; ++s)
|
||||||
{
|
{
|
||||||
if (pt == PAWN)
|
for (int step : {-9, -8, -7, -1, 1, 7, 8, 9} )
|
||||||
PawnAttacks[c][s] |= to;
|
PseudoAttacks[KING][s] |= landing_square_bb(s, step);
|
||||||
else
|
|
||||||
PseudoAttacks[pt][s] |= to;
|
for (int step : {-17, -15, -10, -6, 6, 10, 15, 17} )
|
||||||
}
|
PseudoAttacks[KNIGHT][s] |= landing_square_bb(s, step);
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST };
|
Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST };
|
||||||
Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
|
Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -119,6 +119,12 @@ inline Bitboard operator^( Bitboard b, Square s) { return b ^ square_bb(s); }
|
||||||
inline Bitboard& operator|=(Bitboard& b, Square s) { return b |= square_bb(s); }
|
inline Bitboard& operator|=(Bitboard& b, Square s) { return b |= square_bb(s); }
|
||||||
inline Bitboard& operator^=(Bitboard& b, Square s) { return b ^= square_bb(s); }
|
inline Bitboard& operator^=(Bitboard& b, Square s) { return b ^= square_bb(s); }
|
||||||
|
|
||||||
|
inline Bitboard operator&(Square s, Bitboard b) { return b & s; }
|
||||||
|
inline Bitboard operator|(Square s, Bitboard b) { return b | s; }
|
||||||
|
inline Bitboard operator^(Square s, Bitboard b) { return b ^ s; }
|
||||||
|
|
||||||
|
inline Bitboard operator|(Square s, Square s2) { return square_bb(s) | square_bb(s2); }
|
||||||
|
|
||||||
constexpr bool more_than_one(Bitboard b) {
|
constexpr bool more_than_one(Bitboard b) {
|
||||||
return b & (b - 1);
|
return b & (b - 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -74,7 +74,7 @@ namespace {
|
||||||
assert(pos.count<PAWN>(strongSide) == 1);
|
assert(pos.count<PAWN>(strongSide) == 1);
|
||||||
|
|
||||||
if (file_of(pos.square<PAWN>(strongSide)) >= FILE_E)
|
if (file_of(pos.square<PAWN>(strongSide)) >= FILE_E)
|
||||||
sq = Square(sq ^ 7); // Mirror SQ_H1 -> SQ_A1
|
sq = Square(int(sq) ^ 7); // Mirror SQ_H1 -> SQ_A1
|
||||||
|
|
||||||
return strongSide == WHITE ? sq : ~sq;
|
return strongSide == WHITE ? sq : ~sq;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
|
||||||
Square loserKSq = pos.square<KING>(weakSide);
|
Square loserKSq = pos.square<KING>(weakSide);
|
||||||
Square bishopSq = pos.square<BISHOP>(strongSide);
|
Square bishopSq = pos.square<BISHOP>(strongSide);
|
||||||
|
|
||||||
// If our Bishop does not attack A1/H8, we flip the enemy king square
|
// If our bishop does not attack A1/H8, we flip the enemy king square
|
||||||
// to drive to opposite corners (A8/H1).
|
// to drive to opposite corners (A8/H1).
|
||||||
|
|
||||||
Value result = VALUE_KNOWN_WIN
|
Value result = VALUE_KNOWN_WIN
|
||||||
|
@ -167,7 +167,7 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// KP vs K. This endgame is evaluated with the help of a bitbase.
|
/// KP vs K. This endgame is evaluated with the help of a bitbase
|
||||||
template<>
|
template<>
|
||||||
Value Endgame<KPK>::operator()(const Position& pos) const {
|
Value Endgame<KPK>::operator()(const Position& pos) const {
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
116
src/evaluate.cpp
116
src/evaluate.cpp
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -135,16 +135,17 @@ namespace {
|
||||||
constexpr Score KnightOnQueen = S( 16, 12);
|
constexpr Score KnightOnQueen = S( 16, 12);
|
||||||
constexpr Score LongDiagonalBishop = S( 45, 0);
|
constexpr Score LongDiagonalBishop = S( 45, 0);
|
||||||
constexpr Score MinorBehindPawn = S( 18, 3);
|
constexpr Score MinorBehindPawn = S( 18, 3);
|
||||||
constexpr Score Outpost = S( 32, 10);
|
constexpr Score Outpost = S( 30, 21);
|
||||||
constexpr Score PassedFile = S( 11, 8);
|
constexpr Score PassedFile = S( 11, 8);
|
||||||
constexpr Score PawnlessFlank = S( 17, 95);
|
constexpr Score PawnlessFlank = S( 17, 95);
|
||||||
constexpr Score RestrictedPiece = S( 7, 7);
|
constexpr Score RestrictedPiece = S( 7, 7);
|
||||||
|
constexpr Score ReachableOutpost = S( 32, 10);
|
||||||
constexpr Score RookOnQueenFile = S( 7, 6);
|
constexpr Score RookOnQueenFile = S( 7, 6);
|
||||||
constexpr Score SliderOnQueen = S( 59, 18);
|
constexpr Score SliderOnQueen = S( 59, 18);
|
||||||
constexpr Score ThreatByKing = S( 24, 89);
|
constexpr Score ThreatByKing = S( 24, 89);
|
||||||
constexpr Score ThreatByPawnPush = S( 48, 39);
|
constexpr Score ThreatByPawnPush = S( 48, 39);
|
||||||
constexpr Score ThreatBySafePawn = S(173, 94);
|
constexpr Score ThreatBySafePawn = S(173, 94);
|
||||||
constexpr Score TrappedRook = S( 47, 4);
|
constexpr Score TrappedRook = S( 52, 10);
|
||||||
constexpr Score WeakQueen = S( 49, 15);
|
constexpr Score WeakQueen = S( 49, 15);
|
||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
|
@ -213,8 +214,8 @@ namespace {
|
||||||
void Evaluation<T>::initialize() {
|
void Evaluation<T>::initialize() {
|
||||||
|
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
|
constexpr Direction Up = pawn_push(Us);
|
||||||
constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
|
constexpr Direction Down = -Up;
|
||||||
constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
|
constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
|
||||||
|
|
||||||
const Square ksq = pos.square<KING>(Us);
|
const Square ksq = pos.square<KING>(Us);
|
||||||
|
@ -224,9 +225,9 @@ namespace {
|
||||||
// Find our pawns that are blocked or on the first two ranks
|
// Find our pawns that are blocked or on the first two ranks
|
||||||
Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
|
Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
|
||||||
|
|
||||||
// Squares occupied by those pawns, by our king or queen or controlled by
|
// Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
|
||||||
// enemy pawns are excluded from the mobility area.
|
// or controlled by enemy pawns are excluded from the mobility area.
|
||||||
mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them));
|
mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
|
||||||
|
|
||||||
// Initialize attackedBy[] for king and pawns
|
// Initialize attackedBy[] for king and pawns
|
||||||
attackedBy[Us][KING] = pos.attacks_from<KING>(ksq);
|
attackedBy[Us][KING] = pos.attacks_from<KING>(ksq);
|
||||||
|
@ -235,15 +236,9 @@ namespace {
|
||||||
attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
|
attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
|
||||||
|
|
||||||
// Init our king safety tables
|
// Init our king safety tables
|
||||||
kingRing[Us] = attackedBy[Us][KING];
|
Square s = make_square(clamp(file_of(ksq), FILE_B, FILE_G),
|
||||||
if (relative_rank(Us, ksq) == RANK_1)
|
clamp(rank_of(ksq), RANK_2, RANK_7));
|
||||||
kingRing[Us] |= shift<Up>(kingRing[Us]);
|
kingRing[Us] = PseudoAttacks[KING][s] | s;
|
||||||
|
|
||||||
if (file_of(ksq) == FILE_H)
|
|
||||||
kingRing[Us] |= shift<WEST>(kingRing[Us]);
|
|
||||||
|
|
||||||
else if (file_of(ksq) == FILE_A)
|
|
||||||
kingRing[Us] |= shift<EAST>(kingRing[Us]);
|
|
||||||
|
|
||||||
kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
|
kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
|
||||||
kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
|
kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
|
||||||
|
@ -258,7 +253,7 @@ namespace {
|
||||||
Score Evaluation<T>::pieces() {
|
Score Evaluation<T>::pieces() {
|
||||||
|
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
|
constexpr Direction Down = -pawn_push(Us);
|
||||||
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
||||||
: Rank5BB | Rank4BB | Rank3BB);
|
: Rank5BB | Rank4BB | Rank3BB);
|
||||||
const Square* pl = pos.squares<Pt>(Us);
|
const Square* pl = pos.squares<Pt>(Us);
|
||||||
|
@ -301,7 +296,7 @@ namespace {
|
||||||
score += Outpost * (Pt == KNIGHT ? 2 : 1);
|
score += Outpost * (Pt == KNIGHT ? 2 : 1);
|
||||||
|
|
||||||
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
|
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
|
||||||
score += Outpost;
|
score += ReachableOutpost;
|
||||||
|
|
||||||
// Knight and Bishop bonus for being right behind a pawn
|
// Knight and Bishop bonus for being right behind a pawn
|
||||||
if (shift<Down>(pos.pieces(PAWN)) & s)
|
if (shift<Down>(pos.pieces(PAWN)) & s)
|
||||||
|
@ -322,20 +317,19 @@ namespace {
|
||||||
// Bonus for bishop on a long diagonal which can "see" both center squares
|
// Bonus for bishop on a long diagonal which can "see" both center squares
|
||||||
if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
|
if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
|
||||||
score += LongDiagonalBishop;
|
score += LongDiagonalBishop;
|
||||||
}
|
|
||||||
|
|
||||||
// An important Chess960 pattern: A cornered bishop blocked by a friendly
|
// An important Chess960 pattern: a cornered bishop blocked by a friendly
|
||||||
// pawn diagonally in front of it is a very serious problem, especially
|
// pawn diagonally in front of it is a very serious problem, especially
|
||||||
// when that pawn is also blocked.
|
// when that pawn is also blocked.
|
||||||
if ( Pt == BISHOP
|
if ( pos.is_chess960()
|
||||||
&& pos.is_chess960()
|
&& (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
|
||||||
&& (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
|
{
|
||||||
{
|
Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
|
||||||
Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
|
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
|
||||||
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
|
score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
|
||||||
score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
|
: pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
|
||||||
: pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
|
: CorneredBishop;
|
||||||
: CorneredBishop;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +375,7 @@ namespace {
|
||||||
constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
|
constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
|
||||||
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
|
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
|
||||||
|
|
||||||
Bitboard weak, b1, b2, safe, unsafeChecks = 0;
|
Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
|
||||||
Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
|
Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
|
||||||
int kingDanger = 0;
|
int kingDanger = 0;
|
||||||
const Square ksq = pos.square<KING>(Us);
|
const Square ksq = pos.square<KING>(Us);
|
||||||
|
@ -440,25 +434,27 @@ namespace {
|
||||||
else
|
else
|
||||||
unsafeChecks |= knightChecks;
|
unsafeChecks |= knightChecks;
|
||||||
|
|
||||||
// Find the squares that opponent attacks in our king flank, and the squares
|
// Find the squares that opponent attacks in our king flank, the squares
|
||||||
// which are attacked twice in that flank.
|
// which they attack twice in that flank, and the squares that we defend.
|
||||||
b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
|
b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
|
||||||
b2 = b1 & attackedBy2[Them];
|
b2 = b1 & attackedBy2[Them];
|
||||||
|
b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
|
||||||
|
|
||||||
int kingFlankAttacks = popcount(b1) + popcount(b2);
|
int kingFlankAttack = popcount(b1) + popcount(b2);
|
||||||
|
int kingFlankDefense = popcount(b3);
|
||||||
|
|
||||||
kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
|
kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
|
||||||
+ 69 * kingAttacksCount[Them]
|
|
||||||
+ 185 * popcount(kingRing[Us] & weak)
|
+ 185 * popcount(kingRing[Us] & weak)
|
||||||
- 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
|
|
||||||
- 35 * bool(attackedBy[Us][BISHOP] & attackedBy[Us][KING])
|
|
||||||
+ 148 * popcount(unsafeChecks)
|
+ 148 * popcount(unsafeChecks)
|
||||||
+ 98 * popcount(pos.blockers_for_king(Us))
|
+ 98 * popcount(pos.blockers_for_king(Us))
|
||||||
- 873 * !pos.count<QUEEN>(Them)
|
+ 69 * kingAttacksCount[Them]
|
||||||
- 6 * mg_value(score) / 8
|
+ 3 * kingFlankAttack * kingFlankAttack / 8
|
||||||
+ mg_value(mobility[Them] - mobility[Us])
|
+ mg_value(mobility[Them] - mobility[Us])
|
||||||
+ 3 * kingFlankAttacks * kingFlankAttacks / 8
|
- 873 * !pos.count<QUEEN>(Them)
|
||||||
- 7;
|
- 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
|
||||||
|
- 6 * mg_value(score) / 8
|
||||||
|
- 4 * kingFlankDefense
|
||||||
|
+ 37;
|
||||||
|
|
||||||
// Transform the kingDanger units into a Score, and subtract it from the evaluation
|
// Transform the kingDanger units into a Score, and subtract it from the evaluation
|
||||||
if (kingDanger > 100)
|
if (kingDanger > 100)
|
||||||
|
@ -469,7 +465,7 @@ namespace {
|
||||||
score -= PawnlessFlank;
|
score -= PawnlessFlank;
|
||||||
|
|
||||||
// Penalty if king flank is under attack, potentially moving toward the king
|
// Penalty if king flank is under attack, potentially moving toward the king
|
||||||
score -= FlankAttacks * kingFlankAttacks;
|
score -= FlankAttacks * kingFlankAttack;
|
||||||
|
|
||||||
if (T)
|
if (T)
|
||||||
Trace::add(KING, Us, score);
|
Trace::add(KING, Us, score);
|
||||||
|
@ -484,7 +480,7 @@ namespace {
|
||||||
Score Evaluation<T>::threats() const {
|
Score Evaluation<T>::threats() const {
|
||||||
|
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
|
constexpr Direction Up = pawn_push(Us);
|
||||||
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
|
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
|
||||||
|
|
||||||
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
|
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
|
||||||
|
@ -578,7 +574,7 @@ namespace {
|
||||||
Score Evaluation<T>::passed() const {
|
Score Evaluation<T>::passed() const {
|
||||||
|
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
|
constexpr Direction Up = pawn_push(Us);
|
||||||
|
|
||||||
auto king_proximity = [&](Color c, Square s) {
|
auto king_proximity = [&](Color c, Square s) {
|
||||||
return std::min(distance(pos.square<KING>(c), s), 5);
|
return std::min(distance(pos.square<KING>(c), s), 5);
|
||||||
|
@ -596,7 +592,6 @@ namespace {
|
||||||
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
|
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
|
||||||
|
|
||||||
int r = relative_rank(Us, s);
|
int r = relative_rank(Us, s);
|
||||||
File f = file_of(s);
|
|
||||||
|
|
||||||
Score bonus = PassedRank[r];
|
Score bonus = PassedRank[r];
|
||||||
|
|
||||||
|
@ -606,8 +601,8 @@ namespace {
|
||||||
Square blockSq = s + Up;
|
Square blockSq = s + Up;
|
||||||
|
|
||||||
// Adjust bonus based on the king's proximity
|
// Adjust bonus based on the king's proximity
|
||||||
bonus += make_score(0, ( king_proximity(Them, blockSq) * 5
|
bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
|
||||||
- king_proximity(Us, blockSq) * 2) * w);
|
- king_proximity(Us, blockSq) * 2) * w);
|
||||||
|
|
||||||
// If blockSq is not the queening square then consider also a second push
|
// If blockSq is not the queening square then consider also a second push
|
||||||
if (r != RANK_7)
|
if (r != RANK_7)
|
||||||
|
@ -646,7 +641,7 @@ namespace {
|
||||||
|| (pos.pieces(PAWN) & (s + Up)))
|
|| (pos.pieces(PAWN) & (s + Up)))
|
||||||
bonus = bonus / 2;
|
bonus = bonus / 2;
|
||||||
|
|
||||||
score += bonus - PassedFile * map_to_queenside(f);
|
score += bonus - PassedFile * map_to_queenside(file_of(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (T)
|
if (T)
|
||||||
|
@ -670,7 +665,7 @@ namespace {
|
||||||
return SCORE_ZERO;
|
return SCORE_ZERO;
|
||||||
|
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
|
constexpr Direction Down = -pawn_push(Us);
|
||||||
constexpr Bitboard SpaceMask =
|
constexpr Bitboard SpaceMask =
|
||||||
Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
|
Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
|
||||||
: CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
|
: CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
|
||||||
|
@ -709,6 +704,9 @@ namespace {
|
||||||
int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
|
int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
|
||||||
- distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
|
- distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
|
||||||
|
|
||||||
|
bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
|
||||||
|
|| rank_of(pos.square<KING>(BLACK)) < RANK_5;
|
||||||
|
|
||||||
bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
|
bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
|
||||||
&& (pos.pieces(PAWN) & KingSide);
|
&& (pos.pieces(PAWN) & KingSide);
|
||||||
|
|
||||||
|
@ -720,10 +718,11 @@ namespace {
|
||||||
int complexity = 9 * pe->passed_count()
|
int complexity = 9 * pe->passed_count()
|
||||||
+ 11 * pos.count<PAWN>()
|
+ 11 * pos.count<PAWN>()
|
||||||
+ 9 * outflanking
|
+ 9 * outflanking
|
||||||
+ 18 * pawnsOnBothFlanks
|
+ 12 * infiltration
|
||||||
+ 49 * !pos.non_pawn_material()
|
+ 21 * pawnsOnBothFlanks
|
||||||
- 36 * almostUnwinnable
|
+ 51 * !pos.non_pawn_material()
|
||||||
-103 ;
|
- 43 * almostUnwinnable
|
||||||
|
- 100 ;
|
||||||
|
|
||||||
// Now apply the bonus: note that we find the attacking side by extracting the
|
// Now apply the bonus: note that we find the attacking side by extracting the
|
||||||
// sign of the midgame or endgame values, and that we carefully cap the bonus
|
// sign of the midgame or endgame values, and that we carefully cap the bonus
|
||||||
|
@ -751,11 +750,11 @@ namespace {
|
||||||
{
|
{
|
||||||
if ( pos.opposite_bishops()
|
if ( pos.opposite_bishops()
|
||||||
&& pos.non_pawn_material() == 2 * BishopValueMg)
|
&& pos.non_pawn_material() == 2 * BishopValueMg)
|
||||||
sf = 16 + 4 * pe->passed_count();
|
sf = 22 ;
|
||||||
else
|
else
|
||||||
sf = std::min(sf, 36 + (pos.opposite_bishops() ? 2 : 7) * pos.count<PAWN>(strongSide));
|
sf = std::min(sf, 36 + (pos.opposite_bishops() ? 2 : 7) * pos.count<PAWN>(strongSide));
|
||||||
|
|
||||||
sf = std::max(0, sf - (pos.rule50_count() - 12) / 4 );
|
sf = std::max(0, sf - (pos.rule50_count() - 12) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ScaleFactor(sf);
|
return ScaleFactor(sf);
|
||||||
|
@ -851,6 +850,9 @@ Value Eval::evaluate(const Position& pos) {
|
||||||
|
|
||||||
std::string Eval::trace(const Position& pos) {
|
std::string Eval::trace(const Position& pos) {
|
||||||
|
|
||||||
|
if (pos.checkers())
|
||||||
|
return "Total evaluation: none (in check)";
|
||||||
|
|
||||||
std::memset(scores, 0, sizeof(scores));
|
std::memset(scores, 0, sizeof(scores));
|
||||||
|
|
||||||
pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
|
pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
82
src/misc.cpp
82
src/misc.cpp
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -56,7 +56,7 @@ namespace {
|
||||||
|
|
||||||
/// Version number. If Version is left empty, then compile date in the format
|
/// Version number. If Version is left empty, then compile date in the format
|
||||||
/// DD-MM-YY and show in engine_info.
|
/// DD-MM-YY and show in engine_info.
|
||||||
const string Version = "";
|
const string Version = "11";
|
||||||
|
|
||||||
/// Our fancy logging facility. The trick here is to replace cin.rdbuf() and
|
/// Our fancy logging facility. The trick here is to replace cin.rdbuf() and
|
||||||
/// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We
|
/// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We
|
||||||
|
@ -102,6 +102,13 @@ public:
|
||||||
if (!fname.empty() && !l.file.is_open())
|
if (!fname.empty() && !l.file.is_open())
|
||||||
{
|
{
|
||||||
l.file.open(fname, ifstream::out);
|
l.file.open(fname, ifstream::out);
|
||||||
|
|
||||||
|
if (!l.file.is_open())
|
||||||
|
{
|
||||||
|
cerr << "Unable to open debug log file " << fname << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
cin.rdbuf(&l.in);
|
cin.rdbuf(&l.in);
|
||||||
cout.rdbuf(&l.out);
|
cout.rdbuf(&l.out);
|
||||||
}
|
}
|
||||||
|
@ -144,6 +151,77 @@ const string engine_info(bool to_uci) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// compiler_info() returns a string trying to describe the compiler we use
|
||||||
|
|
||||||
|
const std::string compiler_info() {
|
||||||
|
|
||||||
|
#define STRINGIFY2(x) #x
|
||||||
|
#define STRINGIFY(x) STRINGIFY2(x)
|
||||||
|
#define VER_STRING(major, minor, patch) STRINGIFY(major) "." STRINGIFY(minor) "." STRINGIFY(patch)
|
||||||
|
|
||||||
|
/// Predefined macros hell:
|
||||||
|
///
|
||||||
|
/// __GNUC__ Compiler is gcc, Clang or Intel on Linux
|
||||||
|
/// __INTEL_COMPILER Compiler is Intel
|
||||||
|
/// _MSC_VER Compiler is MSVC or Intel on Windows
|
||||||
|
/// _WIN32 Building on Windows (any)
|
||||||
|
/// _WIN64 Building on Windows 64 bit
|
||||||
|
|
||||||
|
std::string compiler = "\nCompiled by ";
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
compiler += "clang++ ";
|
||||||
|
compiler += VER_STRING(__clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||||
|
#elif __INTEL_COMPILER
|
||||||
|
compiler += "Intel compiler ";
|
||||||
|
compiler += "(version ";
|
||||||
|
compiler += STRINGIFY(__INTEL_COMPILER) " update " STRINGIFY(__INTEL_COMPILER_UPDATE);
|
||||||
|
compiler += ")";
|
||||||
|
#elif _MSC_VER
|
||||||
|
compiler += "MSVC ";
|
||||||
|
compiler += "(version ";
|
||||||
|
compiler += STRINGIFY(_MSC_FULL_VER) "." STRINGIFY(_MSC_BUILD);
|
||||||
|
compiler += ")";
|
||||||
|
#elif __GNUC__
|
||||||
|
compiler += "g++ (GNUC) ";
|
||||||
|
compiler += VER_STRING(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
||||||
|
#else
|
||||||
|
compiler += "Unknown compiler ";
|
||||||
|
compiler += "(unknown version)";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
compiler += " on Apple";
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
compiler += " on Cygwin";
|
||||||
|
#elif defined(__MINGW64__)
|
||||||
|
compiler += " on MinGW64";
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
compiler += " on MinGW32";
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
compiler += " on Android";
|
||||||
|
#elif defined(__linux__)
|
||||||
|
compiler += " on Linux";
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
compiler += " on Microsoft Windows 64-bit";
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
compiler += " on Microsoft Windows 32-bit";
|
||||||
|
#else
|
||||||
|
compiler += " on unknown system";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
compiler += "\n __VERSION__ macro expands to: ";
|
||||||
|
#ifdef __VERSION__
|
||||||
|
compiler += __VERSION__;
|
||||||
|
#else
|
||||||
|
compiler += "(undefined macro)";
|
||||||
|
#endif
|
||||||
|
compiler += "\n";
|
||||||
|
|
||||||
|
return compiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Debug functions used mainly to collect run-time statistics
|
/// Debug functions used mainly to collect run-time statistics
|
||||||
static std::atomic<int64_t> hits[2], means[2];
|
static std::atomic<int64_t> hits[2], means[2];
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
const std::string engine_info(bool to_uci = false);
|
const std::string engine_info(bool to_uci = false);
|
||||||
|
const std::string compiler_info();
|
||||||
void prefetch(void* addr);
|
void prefetch(void* addr);
|
||||||
void start_logger(const std::string& fname);
|
void start_logger(const std::string& fname);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -56,10 +56,11 @@ namespace {
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Bitboard TRank7BB = (Us == WHITE ? Rank7BB : Rank2BB);
|
constexpr Bitboard TRank7BB = (Us == WHITE ? Rank7BB : Rank2BB);
|
||||||
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
|
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
|
||||||
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
|
constexpr Direction Up = pawn_push(Us);
|
||||||
constexpr Direction UpRight = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
|
constexpr Direction UpRight = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
|
||||||
constexpr Direction UpLeft = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
|
constexpr Direction UpLeft = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
|
||||||
|
|
||||||
|
const Square ksq = pos.square<KING>(Them);
|
||||||
Bitboard emptySquares;
|
Bitboard emptySquares;
|
||||||
|
|
||||||
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
|
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
|
||||||
|
@ -84,8 +85,6 @@ namespace {
|
||||||
|
|
||||||
if (Type == QUIET_CHECKS)
|
if (Type == QUIET_CHECKS)
|
||||||
{
|
{
|
||||||
Square ksq = pos.square<KING>(Them);
|
|
||||||
|
|
||||||
b1 &= pos.attacks_from<PAWN>(ksq, Them);
|
b1 &= pos.attacks_from<PAWN>(ksq, Them);
|
||||||
b2 &= pos.attacks_from<PAWN>(ksq, Them);
|
b2 &= pos.attacks_from<PAWN>(ksq, Them);
|
||||||
|
|
||||||
|
@ -130,8 +129,6 @@ namespace {
|
||||||
Bitboard b2 = shift<UpLeft >(pawnsOn7) & enemies;
|
Bitboard b2 = shift<UpLeft >(pawnsOn7) & enemies;
|
||||||
Bitboard b3 = shift<Up >(pawnsOn7) & emptySquares;
|
Bitboard b3 = shift<Up >(pawnsOn7) & emptySquares;
|
||||||
|
|
||||||
Square ksq = pos.square<KING>(Them);
|
|
||||||
|
|
||||||
while (b1)
|
while (b1)
|
||||||
moveList = make_promotions<Type, UpRight>(moveList, pop_lsb(&b1), ksq);
|
moveList = make_promotions<Type, UpRight>(moveList, pop_lsb(&b1), ksq);
|
||||||
|
|
||||||
|
@ -187,7 +184,7 @@ namespace {
|
||||||
ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Color us,
|
ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Color us,
|
||||||
Bitboard target) {
|
Bitboard target) {
|
||||||
|
|
||||||
assert(Pt != KING && Pt != PAWN);
|
static_assert(Pt != KING && Pt != PAWN, "Unsupported piece type in generate_moves()");
|
||||||
|
|
||||||
const Square* pl = pos.squares<Pt>(us);
|
const Square* pl = pos.squares<Pt>(us);
|
||||||
|
|
||||||
|
@ -261,7 +258,7 @@ namespace {
|
||||||
template<GenType Type>
|
template<GenType Type>
|
||||||
ExtMove* generate(const Position& pos, ExtMove* moveList) {
|
ExtMove* generate(const Position& pos, ExtMove* moveList) {
|
||||||
|
|
||||||
assert(Type == CAPTURES || Type == QUIETS || Type == NON_EVASIONS);
|
static_assert(Type == CAPTURES || Type == QUIETS || Type == NON_EVASIONS, "Unsupported type in generate()");
|
||||||
assert(!pos.checkers());
|
assert(!pos.checkers());
|
||||||
|
|
||||||
Color us = pos.side_to_move();
|
Color us = pos.side_to_move();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -56,10 +56,10 @@ namespace {
|
||||||
// is behind our king. Note that UnblockedStorm[0][1-2] accommodate opponent pawn
|
// is behind our king. Note that UnblockedStorm[0][1-2] accommodate opponent pawn
|
||||||
// on edge, likely blocked by our king.
|
// on edge, likely blocked by our king.
|
||||||
constexpr Value UnblockedStorm[int(FILE_NB) / 2][RANK_NB] = {
|
constexpr Value UnblockedStorm[int(FILE_NB) / 2][RANK_NB] = {
|
||||||
{ V( 89), V(-285), V(-185), V(93), V(57), V( 45), V( 51) },
|
{ V( 85), V(-289), V(-166), V(97), V(50), V( 45), V( 50) },
|
||||||
{ V( 44), V( -18), V( 123), V(46), V(39), V( -7), V( 23) },
|
{ V( 46), V( -25), V( 122), V(45), V(37), V(-10), V( 20) },
|
||||||
{ V( 4), V( 52), V( 162), V(37), V( 7), V(-14), V( -2) },
|
{ V( -6), V( 51), V( 168), V(34), V(-2), V(-22), V(-14) },
|
||||||
{ V(-10), V( -14), V( 90), V(15), V( 2), V( -7), V(-16) }
|
{ V(-15), V( -11), V( 101), V( 4), V(11), V(-15), V(-29) }
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
|
@ -69,7 +69,7 @@ namespace {
|
||||||
Score evaluate(const Position& pos, Pawns::Entry* e) {
|
Score evaluate(const Position& pos, Pawns::Entry* e) {
|
||||||
|
|
||||||
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
|
constexpr Direction Up = pawn_push(Us);
|
||||||
|
|
||||||
Bitboard neighbours, stoppers, support, phalanx, opposed;
|
Bitboard neighbours, stoppers, support, phalanx, opposed;
|
||||||
Bitboard lever, leverPush, blocked;
|
Bitboard lever, leverPush, blocked;
|
||||||
|
@ -108,7 +108,7 @@ namespace {
|
||||||
// A pawn is backward when it is behind all pawns of the same color on
|
// A pawn is backward when it is behind all pawns of the same color on
|
||||||
// the adjacent files and cannot safely advance.
|
// the adjacent files and cannot safely advance.
|
||||||
backward = !(neighbours & forward_ranks_bb(Them, s + Up))
|
backward = !(neighbours & forward_ranks_bb(Them, s + Up))
|
||||||
&& (stoppers & (leverPush | blocked));
|
&& (leverPush | blocked);
|
||||||
|
|
||||||
// Compute additional span if pawn is not backward nor blocked
|
// Compute additional span if pawn is not backward nor blocked
|
||||||
if (!backward && !blocked)
|
if (!backward && !blocked)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
160
src/position.cpp
160
src/position.cpp
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -50,41 +50,6 @@ const string PieceToChar(" PNBRQK pnbrqk");
|
||||||
|
|
||||||
constexpr Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
|
constexpr Piece Pieces[] = { W_PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING,
|
||||||
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
|
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING };
|
||||||
|
|
||||||
// min_attacker() is a helper function used by see_ge() to locate the least
|
|
||||||
// valuable attacker for the side to move, remove the attacker we just found
|
|
||||||
// from the bitboards and scan for new X-ray attacks behind it.
|
|
||||||
|
|
||||||
template<PieceType Pt>
|
|
||||||
PieceType min_attacker(const Bitboard* byTypeBB, Square to, Bitboard stmAttackers,
|
|
||||||
Bitboard& occupied, Bitboard& attackers) {
|
|
||||||
|
|
||||||
Bitboard b = stmAttackers & byTypeBB[Pt];
|
|
||||||
if (!b)
|
|
||||||
return min_attacker<PieceType(Pt + 1)>(byTypeBB, to, stmAttackers, occupied, attackers);
|
|
||||||
|
|
||||||
occupied ^= lsb(b); // Remove the attacker from occupied
|
|
||||||
|
|
||||||
// Add any X-ray attack behind the just removed piece. For instance with
|
|
||||||
// rooks in a8 and a7 attacking a1, after removing a7 we add rook in a8.
|
|
||||||
// Note that new added attackers can be of any color.
|
|
||||||
if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
|
|
||||||
attackers |= attacks_bb<BISHOP>(to, occupied) & (byTypeBB[BISHOP] | byTypeBB[QUEEN]);
|
|
||||||
|
|
||||||
if (Pt == ROOK || Pt == QUEEN)
|
|
||||||
attackers |= attacks_bb<ROOK>(to, occupied) & (byTypeBB[ROOK] | byTypeBB[QUEEN]);
|
|
||||||
|
|
||||||
// X-ray may add already processed pieces because byTypeBB[] is constant: in
|
|
||||||
// the rook example, now attackers contains _again_ rook in a7, so remove it.
|
|
||||||
attackers &= occupied;
|
|
||||||
return Pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
PieceType min_attacker<KING>(const Bitboard*, Square, Bitboard, Bitboard&, Bitboard&) {
|
|
||||||
return KING; // No need to update bitboards: it is the last cycle
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -852,7 +817,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||||
st->nonPawnMaterial[us] += PieceValue[MG][promotion];
|
st->nonPawnMaterial[us] += PieceValue[MG][promotion];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update pawn hash key and prefetch access to pawnsTable
|
// Update pawn hash key
|
||||||
st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
|
st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
|
||||||
|
|
||||||
// Reset rule 50 draw counter
|
// Reset rule 50 draw counter
|
||||||
|
@ -979,7 +944,7 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips
|
/// Position::do(undo)_null_move() is used to do(undo) a "null move": it flips
|
||||||
/// the side to move without executing any move on the board.
|
/// the side to move without executing any move on the board.
|
||||||
|
|
||||||
void Position::do_null_move(StateInfo& newSt) {
|
void Position::do_null_move(StateInfo& newSt) {
|
||||||
|
@ -1052,77 +1017,96 @@ bool Position::see_ge(Move m, Value threshold) const {
|
||||||
if (type_of(m) != NORMAL)
|
if (type_of(m) != NORMAL)
|
||||||
return VALUE_ZERO >= threshold;
|
return VALUE_ZERO >= threshold;
|
||||||
|
|
||||||
Bitboard stmAttackers;
|
|
||||||
Square from = from_sq(m), to = to_sq(m);
|
Square from = from_sq(m), to = to_sq(m);
|
||||||
PieceType nextVictim = type_of(piece_on(from));
|
|
||||||
Color us = color_of(piece_on(from));
|
|
||||||
Color stm = ~us; // First consider opponent's move
|
|
||||||
Value balance; // Values of the pieces taken by us minus opponent's ones
|
|
||||||
|
|
||||||
// The opponent may be able to recapture so this is the best result
|
int swap = PieceValue[MG][piece_on(to)] - threshold;
|
||||||
// we can hope for.
|
if (swap < 0)
|
||||||
balance = PieceValue[MG][piece_on(to)] - threshold;
|
|
||||||
|
|
||||||
if (balance < VALUE_ZERO)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Now assume the worst possible result: that the opponent can
|
swap = PieceValue[MG][piece_on(from)] - swap;
|
||||||
// capture our piece for free.
|
if (swap <= 0)
|
||||||
balance -= PieceValue[MG][nextVictim];
|
|
||||||
|
|
||||||
// If it is enough (like in PxQ) then return immediately. Note that
|
|
||||||
// in case nextVictim == KING we always return here, this is ok
|
|
||||||
// if the given move is legal.
|
|
||||||
if (balance >= VALUE_ZERO)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Find all attackers to the destination square, with the moving piece
|
|
||||||
// removed, but possibly an X-ray attacker added behind it.
|
|
||||||
Bitboard occupied = pieces() ^ from ^ to;
|
Bitboard occupied = pieces() ^ from ^ to;
|
||||||
Bitboard attackers = attackers_to(to, occupied) & occupied;
|
Color stm = color_of(piece_on(from));
|
||||||
|
Bitboard attackers = attackers_to(to, occupied);
|
||||||
|
Bitboard stmAttackers, bb;
|
||||||
|
int res = 1;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
stmAttackers = attackers & pieces(stm);
|
stm = ~stm;
|
||||||
|
attackers &= occupied;
|
||||||
|
|
||||||
|
// If stm has no more attackers then give up: stm loses
|
||||||
|
if (!(stmAttackers = attackers & pieces(stm)))
|
||||||
|
break;
|
||||||
|
|
||||||
// Don't allow pinned pieces to attack (except the king) as long as
|
// Don't allow pinned pieces to attack (except the king) as long as
|
||||||
// any pinners are on their original square.
|
// there are pinners on their original square.
|
||||||
if (st->pinners[~stm] & occupied)
|
if (st->pinners[~stm] & occupied)
|
||||||
stmAttackers &= ~st->blockersForKing[stm];
|
stmAttackers &= ~st->blockersForKing[stm];
|
||||||
|
|
||||||
// If stm has no more attackers then give up: stm loses
|
|
||||||
if (!stmAttackers)
|
if (!stmAttackers)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
res ^= 1;
|
||||||
|
|
||||||
// Locate and remove the next least valuable attacker, and add to
|
// Locate and remove the next least valuable attacker, and add to
|
||||||
// the bitboard 'attackers' the possibly X-ray attackers behind it.
|
// the bitboard 'attackers' any X-ray attackers behind it.
|
||||||
nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
|
if ((bb = stmAttackers & pieces(PAWN)))
|
||||||
|
|
||||||
stm = ~stm; // Switch side to move
|
|
||||||
|
|
||||||
// Negamax the balance with alpha = balance, beta = balance+1 and
|
|
||||||
// add nextVictim's value.
|
|
||||||
//
|
|
||||||
// (balance, balance+1) -> (-balance-1, -balance)
|
|
||||||
//
|
|
||||||
assert(balance < VALUE_ZERO);
|
|
||||||
|
|
||||||
balance = -balance - 1 - PieceValue[MG][nextVictim];
|
|
||||||
|
|
||||||
// If balance is still non-negative after giving away nextVictim then we
|
|
||||||
// win. The only thing to be careful about it is that we should revert
|
|
||||||
// stm if we captured with the king when the opponent still has attackers.
|
|
||||||
if (balance >= VALUE_ZERO)
|
|
||||||
{
|
{
|
||||||
if (nextVictim == KING && (attackers & pieces(stm)))
|
if ((swap = PawnValueMg - swap) < res)
|
||||||
stm = ~stm;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(nextVictim != KING);
|
|
||||||
}
|
|
||||||
return us != stm; // We break the above loop when stm loses
|
|
||||||
}
|
|
||||||
|
|
||||||
|
occupied ^= lsb(bb);
|
||||||
|
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((bb = stmAttackers & pieces(KNIGHT)))
|
||||||
|
{
|
||||||
|
if ((swap = KnightValueMg - swap) < res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
occupied ^= lsb(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((bb = stmAttackers & pieces(BISHOP)))
|
||||||
|
{
|
||||||
|
if ((swap = BishopValueMg - swap) < res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
occupied ^= lsb(bb);
|
||||||
|
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((bb = stmAttackers & pieces(ROOK)))
|
||||||
|
{
|
||||||
|
if ((swap = RookValueMg - swap) < res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
occupied ^= lsb(bb);
|
||||||
|
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((bb = stmAttackers & pieces(QUEEN)))
|
||||||
|
{
|
||||||
|
if ((swap = QueenValueMg - swap) < res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
occupied ^= lsb(bb);
|
||||||
|
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
|
||||||
|
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
else // KING
|
||||||
|
// If we "capture" with the king but opponent still has attackers,
|
||||||
|
// reverse the result.
|
||||||
|
return (attackers & ~pieces(stm)) ? res ^ 1 : res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bool(res);
|
||||||
|
}
|
||||||
|
|
||||||
/// Position::is_draw() tests whether the position is drawn by 50-move rule
|
/// Position::is_draw() tests whether the position is drawn by 50-move rule
|
||||||
/// or by repetition. It does not detect stalemates.
|
/// or by repetition. It does not detect stalemates.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,7 +46,6 @@ struct StateInfo {
|
||||||
Square epSquare;
|
Square epSquare;
|
||||||
|
|
||||||
// Not copied when making a move (will be recomputed anyhow)
|
// Not copied when making a move (will be recomputed anyhow)
|
||||||
int repetition;
|
|
||||||
Key key;
|
Key key;
|
||||||
Bitboard checkersBB;
|
Bitboard checkersBB;
|
||||||
Piece capturedPiece;
|
Piece capturedPiece;
|
||||||
|
@ -54,6 +53,7 @@ struct StateInfo {
|
||||||
Bitboard blockersForKing[COLOR_NB];
|
Bitboard blockersForKing[COLOR_NB];
|
||||||
Bitboard pinners[COLOR_NB];
|
Bitboard pinners[COLOR_NB];
|
||||||
Bitboard checkSquares[PIECE_TYPE_NB];
|
Bitboard checkSquares[PIECE_TYPE_NB];
|
||||||
|
int repetition;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A list to keep track of the position states along the setup moves (from the
|
/// A list to keep track of the position states along the setup moves (from the
|
||||||
|
@ -277,16 +277,21 @@ inline int Position::castling_rights(Color c) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Position::castling_impeded(CastlingRights cr) const {
|
inline bool Position::castling_impeded(CastlingRights cr) const {
|
||||||
|
assert(cr == WHITE_OO || cr == WHITE_OOO || cr == BLACK_OO || cr == BLACK_OOO);
|
||||||
|
|
||||||
return byTypeBB[ALL_PIECES] & castlingPath[cr];
|
return byTypeBB[ALL_PIECES] & castlingPath[cr];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Square Position::castling_rook_square(CastlingRights cr) const {
|
inline Square Position::castling_rook_square(CastlingRights cr) const {
|
||||||
|
assert(cr == WHITE_OO || cr == WHITE_OOO || cr == BLACK_OO || cr == BLACK_OOO);
|
||||||
|
|
||||||
return castlingRookSquare[cr];
|
return castlingRookSquare[cr];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<PieceType Pt>
|
template<PieceType Pt>
|
||||||
inline Bitboard Position::attacks_from(Square s) const {
|
inline Bitboard Position::attacks_from(Square s) const {
|
||||||
assert(Pt != PAWN);
|
static_assert(Pt != PAWN, "Pawn attacks need color");
|
||||||
|
|
||||||
return Pt == BISHOP || Pt == ROOK ? attacks_bb<Pt>(s, byTypeBB[ALL_PIECES])
|
return Pt == BISHOP || Pt == ROOK ? attacks_bb<Pt>(s, byTypeBB[ALL_PIECES])
|
||||||
: Pt == QUEEN ? attacks_from<ROOK>(s) | attacks_from<BISHOP>(s)
|
: Pt == QUEEN ? attacks_from<ROOK>(s) | attacks_from<BISHOP>(s)
|
||||||
: PseudoAttacks[Pt][s];
|
: PseudoAttacks[Pt][s];
|
||||||
|
@ -429,7 +434,7 @@ inline void Position::move_piece(Piece pc, Square from, Square to) {
|
||||||
|
|
||||||
// index[from] is not updated and becomes stale. This works as long as index[]
|
// index[from] is not updated and becomes stale. This works as long as index[]
|
||||||
// is accessed just by known occupied squares.
|
// is accessed just by known occupied squares.
|
||||||
Bitboard fromTo = square_bb(from) | square_bb(to);
|
Bitboard fromTo = from | to;
|
||||||
byTypeBB[ALL_PIECES] ^= fromTo;
|
byTypeBB[ALL_PIECES] ^= fromTo;
|
||||||
byTypeBB[type_of(pc)] ^= fromTo;
|
byTypeBB[type_of(pc)] ^= fromTo;
|
||||||
byColorBB[color_of(pc)] ^= fromTo;
|
byColorBB[color_of(pc)] ^= fromTo;
|
||||||
|
|
50
src/psqt.cpp
50
src/psqt.cpp
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -39,24 +39,24 @@ constexpr Score Bonus[][RANK_NB][int(FILE_NB) / 2] = {
|
||||||
{ },
|
{ },
|
||||||
{ },
|
{ },
|
||||||
{ // Knight
|
{ // Knight
|
||||||
{ S(-169,-105), S(-96,-74), S(-80,-46), S(-79,-18) },
|
{ S(-175, -96), S(-92,-65), S(-74,-49), S(-73,-21) },
|
||||||
{ S( -79, -70), S(-39,-56), S(-24,-15), S( -9, 6) },
|
{ S( -77, -67), S(-41,-54), S(-27,-18), S(-15, 8) },
|
||||||
{ S( -64, -38), S(-20,-33), S( 4, -5), S( 19, 27) },
|
{ S( -61, -40), S(-17,-27), S( 6, -8), S( 12, 29) },
|
||||||
{ S( -28, -36), S( 5, 0), S( 41, 13), S( 47, 34) },
|
{ S( -35, -35), S( 8, -2), S( 40, 13), S( 49, 28) },
|
||||||
{ S( -29, -41), S( 13,-20), S( 42, 4), S( 52, 35) },
|
{ S( -34, -45), S( 13,-16), S( 44, 9), S( 51, 39) },
|
||||||
{ S( -11, -51), S( 28,-38), S( 63,-17), S( 55, 19) },
|
{ S( -9, -51), S( 22,-44), S( 58,-16), S( 53, 17) },
|
||||||
{ S( -67, -64), S(-21,-45), S( 6,-37), S( 37, 16) },
|
{ S( -67, -69), S(-27,-50), S( 4,-51), S( 37, 12) },
|
||||||
{ S(-200, -98), S(-80,-89), S(-53,-53), S(-32,-16) }
|
{ S(-201,-100), S(-83,-88), S(-56,-56), S(-26,-17) }
|
||||||
},
|
},
|
||||||
{ // Bishop
|
{ // Bishop
|
||||||
{ S(-44,-63), S( -4,-30), S(-11,-35), S(-28, -8) },
|
{ S(-53,-57), S( -5,-30), S( -8,-37), S(-23,-12) },
|
||||||
{ S(-18,-38), S( 7,-13), S( 14,-14), S( 3, 0) },
|
{ S(-15,-37), S( 8,-13), S( 19,-17), S( 4, 1) },
|
||||||
{ S( -8,-18), S( 24, 0), S( -3, -7), S( 15, 13) },
|
{ S( -7,-16), S( 21, -1), S( -5, -2), S( 17, 10) },
|
||||||
{ S( 1,-26), S( 8, -3), S( 26, 1), S( 37, 16) },
|
{ S( -5,-20), S( 11, -6), S( 25, 0), S( 39, 17) },
|
||||||
{ S( -7,-24), S( 30, -6), S( 23,-10), S( 28, 17) },
|
{ S(-12,-17), S( 29, -1), S( 22,-14), S( 31, 15) },
|
||||||
{ S(-17,-26), S( 4, 2), S( -1, 1), S( 8, 16) },
|
{ S(-16,-30), S( 6, 6), S( 1, 4), S( 11, 6) },
|
||||||
{ S(-21,-34), S(-19,-18), S( 10, -7), S( -6, 9) },
|
{ S(-17,-31), S(-14,-20), S( 5, -1), S( 0, 1) },
|
||||||
{ S(-48,-51), S( -3,-40), S(-12,-39), S(-25,-20) }
|
{ S(-48,-46), S( 1,-42), S(-14,-37), S(-23,-24) }
|
||||||
},
|
},
|
||||||
{ // Rook
|
{ // Rook
|
||||||
{ S(-31, -9), S(-20,-13), S(-14,-10), S(-5, -9) },
|
{ S(-31, -9), S(-20,-13), S(-14,-10), S(-5, -9) },
|
||||||
|
@ -79,14 +79,14 @@ constexpr Score Bonus[][RANK_NB][int(FILE_NB) / 2] = {
|
||||||
{ S(-2,-75), S(-2,-52), S( 1,-43), S(-2,-36) }
|
{ S(-2,-75), S(-2,-52), S( 1,-43), S(-2,-36) }
|
||||||
},
|
},
|
||||||
{ // King
|
{ // King
|
||||||
{ S(272, 0), S(325, 41), S(273, 80), S(190, 93) },
|
{ S(271, 1), S(327, 45), S(271, 85), S(198, 76) },
|
||||||
{ S(277, 57), S(305, 98), S(241,138), S(183,131) },
|
{ S(278, 53), S(303,100), S(234,133), S(179,135) },
|
||||||
{ S(198, 86), S(253,138), S(168,165), S(120,173) },
|
{ S(195, 88), S(258,130), S(169,169), S(120,175) },
|
||||||
{ S(169,103), S(191,152), S(136,168), S(108,169) },
|
{ S(164,103), S(190,156), S(138,172), S( 98,172) },
|
||||||
{ S(145, 98), S(176,166), S(112,197), S( 69,194) },
|
{ S(154, 96), S(179,166), S(105,199), S( 70,199) },
|
||||||
{ S(122, 87), S(159,164), S( 85,174), S( 36,189) },
|
{ S(123, 92), S(145,172), S( 81,184), S( 31,191) },
|
||||||
{ S( 87, 40), S(120, 99), S( 64,128), S( 25,141) },
|
{ S( 88, 47), S(120,121), S( 65,116), S( 33,131) },
|
||||||
{ S( 64, 5), S( 87, 60), S( 49, 75), S( 0, 75) }
|
{ S( 59, 11), S( 89, 59), S( 45, 73), S( -1, 78) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
372
src/search.cpp
372
src/search.cpp
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -62,10 +62,13 @@ namespace {
|
||||||
// Different node types, used as a template parameter
|
// Different node types, used as a template parameter
|
||||||
enum NodeType { NonPV, PV };
|
enum NodeType { NonPV, PV };
|
||||||
|
|
||||||
|
constexpr uint64_t ttHitAverageWindow = 4096;
|
||||||
|
constexpr uint64_t ttHitAverageResolution = 1024;
|
||||||
|
|
||||||
// Razor and futility margins
|
// Razor and futility margins
|
||||||
constexpr int RazorMargin = 661;
|
constexpr int RazorMargin = 531;
|
||||||
Value futility_margin(Depth d, bool improving) {
|
Value futility_margin(Depth d, bool improving) {
|
||||||
return Value(198 * (d - improving));
|
return Value(217 * (d - improving));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reductions lookup table, initialized at startup
|
// Reductions lookup table, initialized at startup
|
||||||
|
@ -73,16 +76,16 @@ namespace {
|
||||||
|
|
||||||
Depth reduction(bool i, Depth d, int mn) {
|
Depth reduction(bool i, Depth d, int mn) {
|
||||||
int r = Reductions[d] * Reductions[mn];
|
int r = Reductions[d] * Reductions[mn];
|
||||||
return (r + 520) / 1024 + (!i && r > 999);
|
return (r + 511) / 1024 + (!i && r > 1007);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr int futility_move_count(bool improving, int depth) {
|
constexpr int futility_move_count(bool improving, Depth depth) {
|
||||||
return (5 + depth * depth) * (1 + improving) / 2;
|
return (5 + depth * depth) * (1 + improving) / 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// History and stats update bonus, based on depth
|
// History and stats update bonus, based on depth
|
||||||
int stat_bonus(Depth d) {
|
int stat_bonus(Depth d) {
|
||||||
return d > 17 ? -8 : 22 * d * d + 151 * d - 140;
|
return d > 15 ? -8 : 19 * d * d + 155 * d - 132;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a small random component to draw evaluations to avoid 3fold-blindness
|
// Add a small random component to draw evaluations to avoid 3fold-blindness
|
||||||
|
@ -151,11 +154,12 @@ namespace {
|
||||||
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth = 0);
|
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth = 0);
|
||||||
|
|
||||||
Value value_to_tt(Value v, int ply);
|
Value value_to_tt(Value v, int ply);
|
||||||
Value value_from_tt(Value v, int ply);
|
Value value_from_tt(Value v, int ply, int r50c);
|
||||||
void update_pv(Move* pv, Move move, Move* childPv);
|
void update_pv(Move* pv, Move move, Move* childPv);
|
||||||
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
|
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
|
||||||
void update_quiet_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietCount, int bonus);
|
void update_quiet_stats(const Position& pos, Stack* ss, Move move, int bonus);
|
||||||
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCount, int bonus);
|
void update_all_stats(const Position& pos, Stack* ss, Move bestMove, Value bestValue, Value beta, Square prevSq,
|
||||||
|
Move* quietsSearched, int quietCount, Move* capturesSearched, int captureCount, Depth depth);
|
||||||
|
|
||||||
// perft() is our utility to verify move generation. All the leaf nodes up
|
// perft() is our utility to verify move generation. All the leaf nodes up
|
||||||
// to the given depth are generated and counted, and the sum is returned.
|
// to the given depth are generated and counted, and the sum is returned.
|
||||||
|
@ -191,7 +195,7 @@ namespace {
|
||||||
void Search::init() {
|
void Search::init() {
|
||||||
|
|
||||||
for (int i = 1; i < MAX_MOVES; ++i)
|
for (int i = 1; i < MAX_MOVES; ++i)
|
||||||
Reductions[i] = int((23.4 + std::log(Threads.size()) / 2) * std::log(i));
|
Reductions[i] = int((24.8 + std::log(Threads.size()) / 2) * std::log(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,6 +365,7 @@ void Thread::search() {
|
||||||
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
|
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
|
||||||
double timeReduction = 1, totBestMoveChanges = 0;
|
double timeReduction = 1, totBestMoveChanges = 0;
|
||||||
Color us = rootPos.side_to_move();
|
Color us = rootPos.side_to_move();
|
||||||
|
int iterIdx = 0;
|
||||||
|
|
||||||
std::memset(ss-7, 0, 10 * sizeof(Stack));
|
std::memset(ss-7, 0, 10 * sizeof(Stack));
|
||||||
for (int i = 7; i > 0; i--)
|
for (int i = 7; i > 0; i--)
|
||||||
|
@ -371,6 +376,16 @@ void Thread::search() {
|
||||||
bestValue = delta = alpha = -VALUE_INFINITE;
|
bestValue = delta = alpha = -VALUE_INFINITE;
|
||||||
beta = VALUE_INFINITE;
|
beta = VALUE_INFINITE;
|
||||||
|
|
||||||
|
if (mainThread)
|
||||||
|
{
|
||||||
|
if (mainThread->previousScore == VALUE_INFINITE)
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
mainThread->iterValue[i] = VALUE_ZERO;
|
||||||
|
else
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
mainThread->iterValue[i] = mainThread->previousScore;
|
||||||
|
}
|
||||||
|
|
||||||
size_t multiPV = Options["MultiPV"];
|
size_t multiPV = Options["MultiPV"];
|
||||||
|
|
||||||
// Pick integer skill levels, but non-deterministically round up or down
|
// Pick integer skill levels, but non-deterministically round up or down
|
||||||
|
@ -392,6 +407,7 @@ void Thread::search() {
|
||||||
multiPV = std::max(multiPV, (size_t)4);
|
multiPV = std::max(multiPV, (size_t)4);
|
||||||
|
|
||||||
multiPV = std::min(multiPV, rootMoves.size());
|
multiPV = std::min(multiPV, rootMoves.size());
|
||||||
|
ttHitAverage = ttHitAverageWindow * ttHitAverageResolution / 2;
|
||||||
|
|
||||||
int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
|
int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
|
||||||
|
|
||||||
|
@ -407,6 +423,8 @@ void Thread::search() {
|
||||||
contempt = (us == WHITE ? make_score(ct, ct / 2)
|
contempt = (us == WHITE ? make_score(ct, ct / 2)
|
||||||
: -make_score(ct, ct / 2));
|
: -make_score(ct, ct / 2));
|
||||||
|
|
||||||
|
int searchAgainCounter = 0;
|
||||||
|
|
||||||
// Iterative deepening loop until requested to stop or the target depth is reached
|
// Iterative deepening loop until requested to stop or the target depth is reached
|
||||||
while ( ++rootDepth < MAX_PLY
|
while ( ++rootDepth < MAX_PLY
|
||||||
&& !Threads.stop
|
&& !Threads.stop
|
||||||
|
@ -425,6 +443,9 @@ void Thread::search() {
|
||||||
size_t pvFirst = 0;
|
size_t pvFirst = 0;
|
||||||
pvLast = 0;
|
pvLast = 0;
|
||||||
|
|
||||||
|
if (!Threads.increaseDepth)
|
||||||
|
searchAgainCounter++;
|
||||||
|
|
||||||
// MultiPV loop. We perform a full root search for each PV line
|
// MultiPV loop. We perform a full root search for each PV line
|
||||||
for (pvIdx = 0; pvIdx < multiPV && !Threads.stop; ++pvIdx)
|
for (pvIdx = 0; pvIdx < multiPV && !Threads.stop; ++pvIdx)
|
||||||
{
|
{
|
||||||
|
@ -443,12 +464,12 @@ void Thread::search() {
|
||||||
if (rootDepth >= 4)
|
if (rootDepth >= 4)
|
||||||
{
|
{
|
||||||
Value previousScore = rootMoves[pvIdx].previousScore;
|
Value previousScore = rootMoves[pvIdx].previousScore;
|
||||||
delta = Value(21 + abs(previousScore) / 128);
|
delta = Value(21 + abs(previousScore) / 256);
|
||||||
alpha = std::max(previousScore - delta,-VALUE_INFINITE);
|
alpha = std::max(previousScore - delta,-VALUE_INFINITE);
|
||||||
beta = std::min(previousScore + delta, VALUE_INFINITE);
|
beta = std::min(previousScore + delta, VALUE_INFINITE);
|
||||||
|
|
||||||
// Adjust contempt based on root move's previousScore (dynamic contempt)
|
// Adjust contempt based on root move's previousScore (dynamic contempt)
|
||||||
int dct = ct + 86 * previousScore / (abs(previousScore) + 176);
|
int dct = ct + (102 - ct / 2) * previousScore / (abs(previousScore) + 157);
|
||||||
|
|
||||||
contempt = (us == WHITE ? make_score(dct, dct / 2)
|
contempt = (us == WHITE ? make_score(dct, dct / 2)
|
||||||
: -make_score(dct, dct / 2));
|
: -make_score(dct, dct / 2));
|
||||||
|
@ -460,7 +481,7 @@ void Thread::search() {
|
||||||
int failedHighCnt = 0;
|
int failedHighCnt = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt);
|
Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt - searchAgainCounter);
|
||||||
bestValue = ::search<PV>(rootPos, ss, alpha, beta, adjustedDepth, false);
|
bestValue = ::search<PV>(rootPos, ss, alpha, beta, adjustedDepth, false);
|
||||||
|
|
||||||
// Bring the best move to the front. It is critical that sorting
|
// Bring the best move to the front. It is critical that sorting
|
||||||
|
@ -553,12 +574,13 @@ void Thread::search() {
|
||||||
&& !Threads.stop
|
&& !Threads.stop
|
||||||
&& !mainThread->stopOnPonderhit)
|
&& !mainThread->stopOnPonderhit)
|
||||||
{
|
{
|
||||||
double fallingEval = (354 + 10 * (mainThread->previousScore - bestValue)) / 692.0;
|
double fallingEval = (332 + 6 * (mainThread->previousScore - bestValue)
|
||||||
|
+ 6 * (mainThread->iterValue[iterIdx] - bestValue)) / 704.0;
|
||||||
fallingEval = clamp(fallingEval, 0.5, 1.5);
|
fallingEval = clamp(fallingEval, 0.5, 1.5);
|
||||||
|
|
||||||
// If the bestMove is stable over several iterations, reduce time accordingly
|
// If the bestMove is stable over several iterations, reduce time accordingly
|
||||||
timeReduction = lastBestMoveDepth + 9 < completedDepth ? 1.97 : 0.98;
|
timeReduction = lastBestMoveDepth + 9 < completedDepth ? 1.94 : 0.91;
|
||||||
double reduction = (1.36 + mainThread->previousTimeReduction) / (2.29 * timeReduction);
|
double reduction = (1.41 + mainThread->previousTimeReduction) / (2.27 * timeReduction);
|
||||||
|
|
||||||
// Use part of the gained time from a previous stable move for the current move
|
// Use part of the gained time from a previous stable move for the current move
|
||||||
for (Thread* th : Threads)
|
for (Thread* th : Threads)
|
||||||
|
@ -579,7 +601,16 @@ void Thread::search() {
|
||||||
else
|
else
|
||||||
Threads.stop = true;
|
Threads.stop = true;
|
||||||
}
|
}
|
||||||
|
else if ( Threads.increaseDepth
|
||||||
|
&& !mainThread->ponder
|
||||||
|
&& Time.elapsed() > Time.optimum() * fallingEval * reduction * bestMoveInstability * 0.6)
|
||||||
|
Threads.increaseDepth = false;
|
||||||
|
else
|
||||||
|
Threads.increaseDepth = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainThread->iterValue[iterIdx] = bestValue;
|
||||||
|
iterIdx = (iterIdx + 1) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mainThread)
|
if (!mainThread)
|
||||||
|
@ -632,17 +663,17 @@ namespace {
|
||||||
Move ttMove, move, excludedMove, bestMove;
|
Move ttMove, move, excludedMove, bestMove;
|
||||||
Depth extension, newDepth;
|
Depth extension, newDepth;
|
||||||
Value bestValue, value, ttValue, eval, maxValue;
|
Value bestValue, value, ttValue, eval, maxValue;
|
||||||
bool ttHit, ttPv, inCheck, givesCheck, improving, doLMR, priorCapture;
|
bool ttHit, ttPv, inCheck, givesCheck, improving, didLMR, priorCapture;
|
||||||
bool captureOrPromotion, doFullDepthSearch, moveCountPruning, ttCapture;
|
bool captureOrPromotion, doFullDepthSearch, moveCountPruning, ttCapture, singularLMR;
|
||||||
Piece movedPiece;
|
Piece movedPiece;
|
||||||
int moveCount, captureCount, quietCount, singularLMR;
|
int moveCount, captureCount, quietCount;
|
||||||
|
|
||||||
// Step 1. Initialize node
|
// Step 1. Initialize node
|
||||||
Thread* thisThread = pos.this_thread();
|
Thread* thisThread = pos.this_thread();
|
||||||
inCheck = pos.checkers();
|
inCheck = pos.checkers();
|
||||||
priorCapture = pos.captured_piece();
|
priorCapture = pos.captured_piece();
|
||||||
Color us = pos.side_to_move();
|
Color us = pos.side_to_move();
|
||||||
moveCount = captureCount = quietCount = singularLMR = ss->moveCount = 0;
|
moveCount = captureCount = quietCount = ss->moveCount = 0;
|
||||||
bestValue = -VALUE_INFINITE;
|
bestValue = -VALUE_INFINITE;
|
||||||
maxValue = VALUE_INFINITE;
|
maxValue = VALUE_INFINITE;
|
||||||
|
|
||||||
|
@ -698,10 +729,13 @@ namespace {
|
||||||
excludedMove = ss->excludedMove;
|
excludedMove = ss->excludedMove;
|
||||||
posKey = pos.key() ^ Key(excludedMove << 16); // Isn't a very good hash
|
posKey = pos.key() ^ Key(excludedMove << 16); // Isn't a very good hash
|
||||||
tte = TT.probe(posKey, ttHit);
|
tte = TT.probe(posKey, ttHit);
|
||||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply, pos.rule50_count()) : VALUE_NONE;
|
||||||
ttMove = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0]
|
ttMove = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0]
|
||||||
: ttHit ? tte->move() : MOVE_NONE;
|
: ttHit ? tte->move() : MOVE_NONE;
|
||||||
ttPv = PvNode || (ttHit && tte->is_pv());
|
ttPv = PvNode || (ttHit && tte->is_pv());
|
||||||
|
// thisThread->ttHitAverage can be used to approximate the running average of ttHit
|
||||||
|
thisThread->ttHitAverage = (ttHitAverageWindow - 1) * thisThread->ttHitAverage / ttHitAverageWindow
|
||||||
|
+ ttHitAverageResolution * ttHit;
|
||||||
|
|
||||||
// At non-PV nodes we check for an early TT cutoff
|
// At non-PV nodes we check for an early TT cutoff
|
||||||
if ( !PvNode
|
if ( !PvNode
|
||||||
|
@ -717,7 +751,7 @@ namespace {
|
||||||
if (ttValue >= beta)
|
if (ttValue >= beta)
|
||||||
{
|
{
|
||||||
if (!pos.capture_or_promotion(ttMove))
|
if (!pos.capture_or_promotion(ttMove))
|
||||||
update_quiet_stats(pos, ss, ttMove, nullptr, 0, stat_bonus(depth));
|
update_quiet_stats(pos, ss, ttMove, stat_bonus(depth));
|
||||||
|
|
||||||
// Extra penalty for early quiet moves of the previous ply
|
// Extra penalty for early quiet moves of the previous ply
|
||||||
if ((ss-1)->moveCount <= 2 && !priorCapture)
|
if ((ss-1)->moveCount <= 2 && !priorCapture)
|
||||||
|
@ -731,7 +765,9 @@ namespace {
|
||||||
update_continuation_histories(ss, pos.moved_piece(ttMove), to_sq(ttMove), penalty);
|
update_continuation_histories(ss, pos.moved_piece(ttMove), to_sq(ttMove), penalty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ttValue;
|
|
||||||
|
if (pos.rule50_count() < 90)
|
||||||
|
return ttValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5. Tablebases probe
|
// Step 5. Tablebases probe
|
||||||
|
@ -824,18 +860,18 @@ namespace {
|
||||||
eval);
|
eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7. Razoring (~2 Elo)
|
// Step 7. Razoring (~1 Elo)
|
||||||
if ( !rootNode // The required rootNode PV handling is not available in qsearch
|
if ( !rootNode // The required rootNode PV handling is not available in qsearch
|
||||||
&& depth < 2
|
&& depth < 2
|
||||||
&& eval <= alpha - RazorMargin)
|
&& eval <= alpha - RazorMargin)
|
||||||
return qsearch<NT>(pos, ss, alpha, beta);
|
return qsearch<NT>(pos, ss, alpha, beta);
|
||||||
|
|
||||||
improving = ss->staticEval >= (ss-2)->staticEval
|
improving = (ss-2)->staticEval == VALUE_NONE ? (ss->staticEval >= (ss-4)->staticEval
|
||||||
|| (ss-2)->staticEval == VALUE_NONE;
|
|| (ss-4)->staticEval == VALUE_NONE) : ss->staticEval >= (ss-2)->staticEval;
|
||||||
|
|
||||||
// Step 8. Futility pruning: child node (~30 Elo)
|
// Step 8. Futility pruning: child node (~50 Elo)
|
||||||
if ( !PvNode
|
if ( !PvNode
|
||||||
&& depth < 7
|
&& depth < 6
|
||||||
&& eval - futility_margin(depth, improving) >= beta
|
&& eval - futility_margin(depth, improving) >= beta
|
||||||
&& eval < VALUE_KNOWN_WIN) // Do not return unproven wins
|
&& eval < VALUE_KNOWN_WIN) // Do not return unproven wins
|
||||||
return eval;
|
return eval;
|
||||||
|
@ -843,10 +879,10 @@ namespace {
|
||||||
// Step 9. Null move search with verification search (~40 Elo)
|
// Step 9. Null move search with verification search (~40 Elo)
|
||||||
if ( !PvNode
|
if ( !PvNode
|
||||||
&& (ss-1)->currentMove != MOVE_NULL
|
&& (ss-1)->currentMove != MOVE_NULL
|
||||||
&& (ss-1)->statScore < 22661
|
&& (ss-1)->statScore < 23397
|
||||||
&& eval >= beta
|
&& eval >= beta
|
||||||
&& eval >= ss->staticEval
|
&& eval >= ss->staticEval
|
||||||
&& ss->staticEval >= beta - 33 * depth + 299 - improving * 30
|
&& ss->staticEval >= beta - 32 * depth + 292 - improving * 30
|
||||||
&& !excludedMove
|
&& !excludedMove
|
||||||
&& pos.non_pawn_material(us)
|
&& pos.non_pawn_material(us)
|
||||||
&& (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
|
&& (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
|
||||||
|
@ -854,7 +890,7 @@ namespace {
|
||||||
assert(eval - beta >= 0);
|
assert(eval - beta >= 0);
|
||||||
|
|
||||||
// Null move dynamic reduction based on depth and value
|
// Null move dynamic reduction based on depth and value
|
||||||
Depth R = (835 + 70 * depth) / 256 + std::min(int(eval - beta) / 185, 3);
|
Depth R = (854 + 68 * depth) / 258 + std::min(int(eval - beta) / 192, 3);
|
||||||
|
|
||||||
ss->currentMove = MOVE_NULL;
|
ss->currentMove = MOVE_NULL;
|
||||||
ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0];
|
ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0];
|
||||||
|
@ -897,7 +933,7 @@ namespace {
|
||||||
&& depth >= 5
|
&& depth >= 5
|
||||||
&& abs(beta) < VALUE_MATE_IN_MAX_PLY)
|
&& abs(beta) < VALUE_MATE_IN_MAX_PLY)
|
||||||
{
|
{
|
||||||
Value raisedBeta = std::min(beta + 191 - 46 * improving, VALUE_INFINITE);
|
Value raisedBeta = std::min(beta + 189 - 45 * improving, VALUE_INFINITE);
|
||||||
MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &thisThread->captureHistory);
|
MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &thisThread->captureHistory);
|
||||||
int probCutCount = 0;
|
int probCutCount = 0;
|
||||||
|
|
||||||
|
@ -933,13 +969,13 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 11. Internal iterative deepening (~2 Elo)
|
// Step 11. Internal iterative deepening (~1 Elo)
|
||||||
if (depth >= 7 && !ttMove)
|
if (depth >= 7 && !ttMove)
|
||||||
{
|
{
|
||||||
search<NT>(pos, ss, alpha, beta, depth - 7, cutNode);
|
search<NT>(pos, ss, alpha, beta, depth - 7, cutNode);
|
||||||
|
|
||||||
tte = TT.probe(posKey, ttHit);
|
tte = TT.probe(posKey, ttHit);
|
||||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply, pos.rule50_count()) : VALUE_NONE;
|
||||||
ttMove = ttHit ? tte->move() : MOVE_NONE;
|
ttMove = ttHit ? tte->move() : MOVE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,7 +994,7 @@ moves_loop: // When in check, search starts from here
|
||||||
ss->killers);
|
ss->killers);
|
||||||
|
|
||||||
value = bestValue;
|
value = bestValue;
|
||||||
moveCountPruning = false;
|
singularLMR = moveCountPruning = false;
|
||||||
ttCapture = ttMove && pos.capture_or_promotion(ttMove);
|
ttCapture = ttMove && pos.capture_or_promotion(ttMove);
|
||||||
|
|
||||||
// Mark this node as being searched
|
// Mark this node as being searched
|
||||||
|
@ -995,9 +1031,50 @@ moves_loop: // When in check, search starts from here
|
||||||
movedPiece = pos.moved_piece(move);
|
movedPiece = pos.moved_piece(move);
|
||||||
givesCheck = pos.gives_check(move);
|
givesCheck = pos.gives_check(move);
|
||||||
|
|
||||||
// Step 13. Extensions (~70 Elo)
|
// Calculate new depth for this move
|
||||||
|
newDepth = depth - 1;
|
||||||
|
|
||||||
// Singular extension search (~60 Elo). If all moves but one fail low on a
|
// Step 13. Pruning at shallow depth (~200 Elo)
|
||||||
|
if ( !rootNode
|
||||||
|
&& pos.non_pawn_material(us)
|
||||||
|
&& bestValue > VALUE_MATED_IN_MAX_PLY)
|
||||||
|
{
|
||||||
|
// Skip quiet moves if movecount exceeds our FutilityMoveCount threshold
|
||||||
|
moveCountPruning = moveCount >= futility_move_count(improving, depth);
|
||||||
|
|
||||||
|
if ( !captureOrPromotion
|
||||||
|
&& !givesCheck)
|
||||||
|
{
|
||||||
|
// Reduced depth of the next LMR search
|
||||||
|
int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0);
|
||||||
|
|
||||||
|
// Countermoves based pruning (~20 Elo)
|
||||||
|
if ( lmrDepth < 4 + ((ss-1)->statScore > 0 || (ss-1)->moveCount == 1)
|
||||||
|
&& (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold
|
||||||
|
&& (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Futility pruning: parent node (~5 Elo)
|
||||||
|
if ( lmrDepth < 6
|
||||||
|
&& !inCheck
|
||||||
|
&& ss->staticEval + 235 + 172 * lmrDepth <= alpha
|
||||||
|
&& thisThread->mainHistory[us][from_to(move)]
|
||||||
|
+ (*contHist[0])[movedPiece][to_sq(move)]
|
||||||
|
+ (*contHist[1])[movedPiece][to_sq(move)]
|
||||||
|
+ (*contHist[3])[movedPiece][to_sq(move)] < 25000)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Prune moves with negative SEE (~20 Elo)
|
||||||
|
if (!pos.see_ge(move, Value(-(32 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth)))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!pos.see_ge(move, Value(-194) * depth)) // (~25 Elo)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 14. Extensions (~75 Elo)
|
||||||
|
|
||||||
|
// Singular extension search (~70 Elo). If all moves but one fail low on a
|
||||||
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
|
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
|
||||||
// then that move is singular and should be extended. To verify this we do
|
// then that move is singular and should be extended. To verify this we do
|
||||||
// a reduced search on all the other moves but the ttMove and if the
|
// a reduced search on all the other moves but the ttMove and if the
|
||||||
|
@ -1021,10 +1098,7 @@ moves_loop: // When in check, search starts from here
|
||||||
if (value < singularBeta)
|
if (value < singularBeta)
|
||||||
{
|
{
|
||||||
extension = 1;
|
extension = 1;
|
||||||
singularLMR++;
|
singularLMR = true;
|
||||||
|
|
||||||
if (value < singularBeta - std::min(4 * depth, 36))
|
|
||||||
singularLMR++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multi-cut pruning
|
// Multi-cut pruning
|
||||||
|
@ -1032,8 +1106,7 @@ moves_loop: // When in check, search starts from here
|
||||||
// search without the ttMove. So we assume this expected Cut-node is not singular,
|
// search without the ttMove. So we assume this expected Cut-node is not singular,
|
||||||
// that multiple moves fail high, and we can prune the whole subtree by returning
|
// that multiple moves fail high, and we can prune the whole subtree by returning
|
||||||
// a soft bound.
|
// a soft bound.
|
||||||
else if ( eval >= beta
|
else if (singularBeta >= beta)
|
||||||
&& singularBeta >= beta)
|
|
||||||
return singularBeta;
|
return singularBeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,65 +1115,23 @@ moves_loop: // When in check, search starts from here
|
||||||
&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
|
&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
|
||||||
extension = 1;
|
extension = 1;
|
||||||
|
|
||||||
// Shuffle extension
|
|
||||||
else if ( PvNode
|
|
||||||
&& pos.rule50_count() > 18
|
|
||||||
&& depth < 3
|
|
||||||
&& ++thisThread->shuffleExts < thisThread->nodes.load(std::memory_order_relaxed) / 4) // To avoid too many extensions
|
|
||||||
extension = 1;
|
|
||||||
|
|
||||||
// Passed pawn extension
|
// Passed pawn extension
|
||||||
else if ( move == ss->killers[0]
|
else if ( move == ss->killers[0]
|
||||||
&& pos.advanced_pawn_push(move)
|
&& pos.advanced_pawn_push(move)
|
||||||
&& pos.pawn_passed(us, to_sq(move)))
|
&& pos.pawn_passed(us, to_sq(move)))
|
||||||
extension = 1;
|
extension = 1;
|
||||||
|
|
||||||
|
// Last captures extension
|
||||||
|
else if ( PieceValue[EG][pos.captured_piece()] > PawnValueEg
|
||||||
|
&& pos.non_pawn_material() <= 2 * RookValueMg)
|
||||||
|
extension = 1;
|
||||||
|
|
||||||
// Castling extension
|
// Castling extension
|
||||||
if (type_of(move) == CASTLING)
|
if (type_of(move) == CASTLING)
|
||||||
extension = 1;
|
extension = 1;
|
||||||
|
|
||||||
// Calculate new depth for this move
|
// Add extension to new depth
|
||||||
newDepth = depth - 1 + extension;
|
newDepth += extension;
|
||||||
|
|
||||||
// Step 14. Pruning at shallow depth (~170 Elo)
|
|
||||||
if ( !rootNode
|
|
||||||
&& pos.non_pawn_material(us)
|
|
||||||
&& bestValue > VALUE_MATED_IN_MAX_PLY)
|
|
||||||
{
|
|
||||||
// Skip quiet moves if movecount exceeds our FutilityMoveCount threshold
|
|
||||||
moveCountPruning = moveCount >= futility_move_count(improving, depth);
|
|
||||||
|
|
||||||
if ( !captureOrPromotion
|
|
||||||
&& !givesCheck
|
|
||||||
&& (!pos.advanced_pawn_push(move) || pos.non_pawn_material(~us) > BishopValueMg))
|
|
||||||
{
|
|
||||||
// Move count based pruning
|
|
||||||
if (moveCountPruning)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Reduced depth of the next LMR search
|
|
||||||
int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0);
|
|
||||||
|
|
||||||
// Countermoves based pruning (~20 Elo)
|
|
||||||
if ( lmrDepth < 4 + ((ss-1)->statScore > 0 || (ss-1)->moveCount == 1)
|
|
||||||
&& (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold
|
|
||||||
&& (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Futility pruning: parent node (~2 Elo)
|
|
||||||
if ( lmrDepth < 6
|
|
||||||
&& !inCheck
|
|
||||||
&& ss->staticEval + 250 + 211 * lmrDepth <= alpha)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Prune moves with negative SEE (~10 Elo)
|
|
||||||
if (!pos.see_ge(move, Value(-(31 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth)))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if ( !(givesCheck && extension)
|
|
||||||
&& !pos.see_ge(move, Value(-199) * depth)) // (~20 Elo)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Speculative prefetch as early as possible
|
// Speculative prefetch as early as possible
|
||||||
prefetch(TT.first_entry(pos.key_after(move)));
|
prefetch(TT.first_entry(pos.key_after(move)));
|
||||||
|
@ -1122,46 +1153,52 @@ moves_loop: // When in check, search starts from here
|
||||||
// Step 15. Make the move
|
// Step 15. Make the move
|
||||||
pos.do_move(move, st, givesCheck);
|
pos.do_move(move, st, givesCheck);
|
||||||
|
|
||||||
// Step 16. Reduced depth search (LMR). If the move fails high it will be
|
// Step 16. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be
|
||||||
// re-searched at full depth.
|
// re-searched at full depth.
|
||||||
if ( depth >= 3
|
if ( depth >= 3
|
||||||
&& moveCount > 1 + 2 * rootNode
|
&& moveCount > 1 + rootNode + (rootNode && bestValue < alpha)
|
||||||
&& (!rootNode || thisThread->best_move_count(move) == 0)
|
&& (!rootNode || thisThread->best_move_count(move) == 0)
|
||||||
&& ( !captureOrPromotion
|
&& ( !captureOrPromotion
|
||||||
|| moveCountPruning
|
|| moveCountPruning
|
||||||
|| ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha
|
|| ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha
|
||||||
|| cutNode))
|
|| cutNode
|
||||||
|
|| thisThread->ttHitAverage < 375 * ttHitAverageResolution * ttHitAverageWindow / 1024))
|
||||||
{
|
{
|
||||||
Depth r = reduction(improving, depth, moveCount);
|
Depth r = reduction(improving, depth, moveCount);
|
||||||
|
|
||||||
|
// Decrease reduction if the ttHit running average is large
|
||||||
|
if (thisThread->ttHitAverage > 500 * ttHitAverageResolution * ttHitAverageWindow / 1024)
|
||||||
|
r--;
|
||||||
|
|
||||||
// Reduction if other threads are searching this position.
|
// Reduction if other threads are searching this position.
|
||||||
if (th.marked())
|
if (th.marked())
|
||||||
r++;
|
r++;
|
||||||
|
|
||||||
// Decrease reduction if position is or has been on the PV
|
// Decrease reduction if position is or has been on the PV (~10 Elo)
|
||||||
if (ttPv)
|
if (ttPv)
|
||||||
r -= 2;
|
r -= 2;
|
||||||
|
|
||||||
// Decrease reduction if opponent's move count is high (~10 Elo)
|
// Decrease reduction if opponent's move count is high (~5 Elo)
|
||||||
if ((ss-1)->moveCount > 15)
|
if ((ss-1)->moveCount > 14)
|
||||||
r--;
|
r--;
|
||||||
|
|
||||||
// Decrease reduction if ttMove has been singularly extended
|
// Decrease reduction if ttMove has been singularly extended (~3 Elo)
|
||||||
r -= singularLMR;
|
if (singularLMR)
|
||||||
|
r -= 2;
|
||||||
|
|
||||||
if (!captureOrPromotion)
|
if (!captureOrPromotion)
|
||||||
{
|
{
|
||||||
// Increase reduction if ttMove is a capture (~0 Elo)
|
// Increase reduction if ttMove is a capture (~5 Elo)
|
||||||
if (ttCapture)
|
if (ttCapture)
|
||||||
r++;
|
r++;
|
||||||
|
|
||||||
// Increase reduction for cut nodes (~5 Elo)
|
// Increase reduction for cut nodes (~10 Elo)
|
||||||
if (cutNode)
|
if (cutNode)
|
||||||
r += 2;
|
r += 2;
|
||||||
|
|
||||||
// Decrease reduction for moves that escape a capture. Filter out
|
// Decrease reduction for moves that escape a capture. Filter out
|
||||||
// castling moves, because they are coded as "king captures rook" and
|
// castling moves, because they are coded as "king captures rook" and
|
||||||
// hence break make_move(). (~5 Elo)
|
// hence break make_move(). (~2 Elo)
|
||||||
else if ( type_of(move) == NORMAL
|
else if ( type_of(move) == NORMAL
|
||||||
&& !pos.see_ge(reverse_move(move)))
|
&& !pos.see_ge(reverse_move(move)))
|
||||||
r -= 2;
|
r -= 2;
|
||||||
|
@ -1170,7 +1207,7 @@ moves_loop: // When in check, search starts from here
|
||||||
+ (*contHist[0])[movedPiece][to_sq(move)]
|
+ (*contHist[0])[movedPiece][to_sq(move)]
|
||||||
+ (*contHist[1])[movedPiece][to_sq(move)]
|
+ (*contHist[1])[movedPiece][to_sq(move)]
|
||||||
+ (*contHist[3])[movedPiece][to_sq(move)]
|
+ (*contHist[3])[movedPiece][to_sq(move)]
|
||||||
- 4729;
|
- 4926;
|
||||||
|
|
||||||
// Reset statScore to zero if negative and most stats shows >= 0
|
// Reset statScore to zero if negative and most stats shows >= 0
|
||||||
if ( ss->statScore < 0
|
if ( ss->statScore < 0
|
||||||
|
@ -1180,31 +1217,35 @@ moves_loop: // When in check, search starts from here
|
||||||
ss->statScore = 0;
|
ss->statScore = 0;
|
||||||
|
|
||||||
// Decrease/increase reduction by comparing opponent's stat score (~10 Elo)
|
// Decrease/increase reduction by comparing opponent's stat score (~10 Elo)
|
||||||
if (ss->statScore >= -99 && (ss-1)->statScore < -116)
|
if (ss->statScore >= -102 && (ss-1)->statScore < -114)
|
||||||
r--;
|
r--;
|
||||||
|
|
||||||
else if ((ss-1)->statScore >= -117 && ss->statScore < -144)
|
else if ((ss-1)->statScore >= -116 && ss->statScore < -154)
|
||||||
r++;
|
r++;
|
||||||
|
|
||||||
// Decrease/increase reduction for moves with a good/bad history (~30 Elo)
|
// Decrease/increase reduction for moves with a good/bad history (~30 Elo)
|
||||||
r -= ss->statScore / 16384;
|
r -= ss->statScore / 16384;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increase reduction for captures/promotions if late move and at low depth
|
||||||
|
else if (depth < 8 && moveCount > 2)
|
||||||
|
r++;
|
||||||
|
|
||||||
Depth d = clamp(newDepth - r, 1, newDepth);
|
Depth d = clamp(newDepth - r, 1, newDepth);
|
||||||
|
|
||||||
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
|
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
|
||||||
|
|
||||||
doFullDepthSearch = (value > alpha && d != newDepth), doLMR = true;
|
doFullDepthSearch = (value > alpha && d != newDepth), didLMR = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
doFullDepthSearch = !PvNode || moveCount > 1, doLMR = false;
|
doFullDepthSearch = !PvNode || moveCount > 1, didLMR = false;
|
||||||
|
|
||||||
// Step 17. Full depth search when LMR is skipped or fails high
|
// Step 17. Full depth search when LMR is skipped or fails high
|
||||||
if (doFullDepthSearch)
|
if (doFullDepthSearch)
|
||||||
{
|
{
|
||||||
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode);
|
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode);
|
||||||
|
|
||||||
if (doLMR && !captureOrPromotion)
|
if (didLMR && !captureOrPromotion)
|
||||||
{
|
{
|
||||||
int bonus = value > alpha ? stat_bonus(newDepth)
|
int bonus = value > alpha ? stat_bonus(newDepth)
|
||||||
: -stat_bonus(newDepth);
|
: -stat_bonus(newDepth);
|
||||||
|
@ -1319,21 +1360,11 @@ moves_loop: // When in check, search starts from here
|
||||||
if (!moveCount)
|
if (!moveCount)
|
||||||
bestValue = excludedMove ? alpha
|
bestValue = excludedMove ? alpha
|
||||||
: inCheck ? mated_in(ss->ply) : VALUE_DRAW;
|
: inCheck ? mated_in(ss->ply) : VALUE_DRAW;
|
||||||
|
|
||||||
else if (bestMove)
|
else if (bestMove)
|
||||||
{
|
update_all_stats(pos, ss, bestMove, bestValue, beta, prevSq,
|
||||||
// Quiet best move: update move sorting heuristics
|
quietsSearched, quietCount, capturesSearched, captureCount, depth);
|
||||||
if (!pos.capture_or_promotion(bestMove))
|
|
||||||
update_quiet_stats(pos, ss, bestMove, quietsSearched, quietCount,
|
|
||||||
stat_bonus(depth + (bestValue > beta + PawnValueMg)));
|
|
||||||
|
|
||||||
update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth + 1));
|
|
||||||
|
|
||||||
// Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted
|
|
||||||
if ( ((ss-1)->moveCount == 1 || ((ss-1)->currentMove == (ss-1)->killers[0]))
|
|
||||||
&& !priorCapture)
|
|
||||||
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1));
|
|
||||||
|
|
||||||
}
|
|
||||||
// Bonus for prior countermove that caused the fail low
|
// Bonus for prior countermove that caused the fail low
|
||||||
else if ( (depth >= 3 || PvNode)
|
else if ( (depth >= 3 || PvNode)
|
||||||
&& !priorCapture)
|
&& !priorCapture)
|
||||||
|
@ -1404,7 +1435,7 @@ moves_loop: // When in check, search starts from here
|
||||||
// Transposition table lookup
|
// Transposition table lookup
|
||||||
posKey = pos.key();
|
posKey = pos.key();
|
||||||
tte = TT.probe(posKey, ttHit);
|
tte = TT.probe(posKey, ttHit);
|
||||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply, pos.rule50_count()) : VALUE_NONE;
|
||||||
ttMove = ttHit ? tte->move() : MOVE_NONE;
|
ttMove = ttHit ? tte->move() : MOVE_NONE;
|
||||||
pvHit = ttHit && tte->is_pv();
|
pvHit = ttHit && tte->is_pv();
|
||||||
|
|
||||||
|
@ -1454,7 +1485,7 @@ moves_loop: // When in check, search starts from here
|
||||||
if (PvNode && bestValue > alpha)
|
if (PvNode && bestValue > alpha)
|
||||||
alpha = bestValue;
|
alpha = bestValue;
|
||||||
|
|
||||||
futilityBase = bestValue + 153;
|
futilityBase = bestValue + 154;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory,
|
const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory,
|
||||||
|
@ -1510,9 +1541,7 @@ moves_loop: // When in check, search starts from here
|
||||||
&& !pos.capture(move);
|
&& !pos.capture(move);
|
||||||
|
|
||||||
// Don't search moves with negative SEE values
|
// Don't search moves with negative SEE values
|
||||||
if ( (!inCheck || evasionPrunable)
|
if ( (!inCheck || evasionPrunable) && !pos.see_ge(move))
|
||||||
&& (!givesCheck || !(pos.blockers_for_king(~pos.side_to_move()) & from_sq(move)))
|
|
||||||
&& !pos.see_ge(move))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Speculative prefetch as early as possible
|
// Speculative prefetch as early as possible
|
||||||
|
@ -1592,11 +1621,11 @@ moves_loop: // When in check, search starts from here
|
||||||
// from the transposition table (which refers to the plies to mate/be mated
|
// from the transposition table (which refers to the plies to mate/be mated
|
||||||
// from current position) to "plies to mate/be mated from the root".
|
// from current position) to "plies to mate/be mated from the root".
|
||||||
|
|
||||||
Value value_from_tt(Value v, int ply) {
|
Value value_from_tt(Value v, int ply, int r50c) {
|
||||||
|
|
||||||
return v == VALUE_NONE ? VALUE_NONE
|
return v == VALUE_NONE ? VALUE_NONE
|
||||||
: v >= VALUE_MATE_IN_MAX_PLY ? v - ply
|
: v >= VALUE_MATE_IN_MAX_PLY ? VALUE_MATE - v > 99 - r50c ? VALUE_MATE_IN_MAX_PLY : v - ply
|
||||||
: v <= VALUE_MATED_IN_MAX_PLY ? v + ply : v;
|
: v <= VALUE_MATED_IN_MAX_PLY ? VALUE_MATE + v > 99 - r50c ? VALUE_MATED_IN_MAX_PLY : v + ply : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1610,6 +1639,51 @@ moves_loop: // When in check, search starts from here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// update_all_stats() updates stats at the end of search() when a bestMove is found
|
||||||
|
|
||||||
|
void update_all_stats(const Position& pos, Stack* ss, Move bestMove, Value bestValue, Value beta, Square prevSq,
|
||||||
|
Move* quietsSearched, int quietCount, Move* capturesSearched, int captureCount, Depth depth) {
|
||||||
|
|
||||||
|
int bonus1, bonus2;
|
||||||
|
Color us = pos.side_to_move();
|
||||||
|
Thread* thisThread = pos.this_thread();
|
||||||
|
CapturePieceToHistory& captureHistory = thisThread->captureHistory;
|
||||||
|
Piece moved_piece = pos.moved_piece(bestMove);
|
||||||
|
PieceType captured = type_of(pos.piece_on(to_sq(bestMove)));
|
||||||
|
|
||||||
|
bonus1 = stat_bonus(depth + 1);
|
||||||
|
bonus2 = bestValue > beta + PawnValueMg ? bonus1 // larger bonus
|
||||||
|
: stat_bonus(depth); // smaller bonus
|
||||||
|
|
||||||
|
if (!pos.capture_or_promotion(bestMove))
|
||||||
|
{
|
||||||
|
update_quiet_stats(pos, ss, bestMove, bonus2);
|
||||||
|
|
||||||
|
// Decrease all the non-best quiet moves
|
||||||
|
for (int i = 0; i < quietCount; ++i)
|
||||||
|
{
|
||||||
|
thisThread->mainHistory[us][from_to(quietsSearched[i])] << -bonus2;
|
||||||
|
update_continuation_histories(ss, pos.moved_piece(quietsSearched[i]), to_sq(quietsSearched[i]), -bonus2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
captureHistory[moved_piece][to_sq(bestMove)][captured] << bonus1;
|
||||||
|
|
||||||
|
// Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted
|
||||||
|
if ( ((ss-1)->moveCount == 1 || ((ss-1)->currentMove == (ss-1)->killers[0]))
|
||||||
|
&& !pos.captured_piece())
|
||||||
|
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -bonus1);
|
||||||
|
|
||||||
|
// Decrease all the non-best capture moves
|
||||||
|
for (int i = 0; i < captureCount; ++i)
|
||||||
|
{
|
||||||
|
moved_piece = pos.moved_piece(capturesSearched[i]);
|
||||||
|
captured = type_of(pos.piece_on(to_sq(capturesSearched[i])));
|
||||||
|
captureHistory[moved_piece][to_sq(capturesSearched[i])][captured] << -bonus1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// update_continuation_histories() updates histories of the move pairs formed
|
// update_continuation_histories() updates histories of the move pairs formed
|
||||||
// by moves at ply -1, -2, and -4 with current move.
|
// by moves at ply -1, -2, and -4 with current move.
|
||||||
|
|
||||||
|
@ -1621,32 +1695,9 @@ moves_loop: // When in check, search starts from here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// update_capture_stats() updates move sorting heuristics when a new capture best move is found
|
// update_quiet_stats() updates move sorting heuristics
|
||||||
|
|
||||||
void update_capture_stats(const Position& pos, Move move,
|
void update_quiet_stats(const Position& pos, Stack* ss, Move move, int bonus) {
|
||||||
Move* captures, int captureCount, int bonus) {
|
|
||||||
|
|
||||||
CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
|
|
||||||
Piece moved_piece = pos.moved_piece(move);
|
|
||||||
PieceType captured = type_of(pos.piece_on(to_sq(move)));
|
|
||||||
|
|
||||||
if (pos.capture_or_promotion(move))
|
|
||||||
captureHistory[moved_piece][to_sq(move)][captured] << bonus;
|
|
||||||
|
|
||||||
// Decrease all the other played capture moves
|
|
||||||
for (int i = 0; i < captureCount; ++i)
|
|
||||||
{
|
|
||||||
moved_piece = pos.moved_piece(captures[i]);
|
|
||||||
captured = type_of(pos.piece_on(to_sq(captures[i])));
|
|
||||||
captureHistory[moved_piece][to_sq(captures[i])][captured] << -bonus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// update_quiet_stats() updates move sorting heuristics when a new quiet best move is found
|
|
||||||
|
|
||||||
void update_quiet_stats(const Position& pos, Stack* ss, Move move,
|
|
||||||
Move* quiets, int quietCount, int bonus) {
|
|
||||||
|
|
||||||
if (ss->killers[0] != move)
|
if (ss->killers[0] != move)
|
||||||
{
|
{
|
||||||
|
@ -1667,13 +1718,6 @@ moves_loop: // When in check, search starts from here
|
||||||
Square prevSq = to_sq((ss-1)->currentMove);
|
Square prevSq = to_sq((ss-1)->currentMove);
|
||||||
thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] = move;
|
thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] = move;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrease all the other played quiet moves
|
|
||||||
for (int i = 0; i < quietCount; ++i)
|
|
||||||
{
|
|
||||||
thisThread->mainHistory[us][from_to(quiets[i])] << -bonus;
|
|
||||||
update_continuation_histories(ss, pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When playing with strength handicap, choose best move among a set of RootMoves
|
// When playing with strength handicap, choose best move among a set of RootMoves
|
||||||
|
@ -1762,7 +1806,7 @@ string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) {
|
||||||
|
|
||||||
for (size_t i = 0; i < multiPV; ++i)
|
for (size_t i = 0; i < multiPV; ++i)
|
||||||
{
|
{
|
||||||
bool updated = (i <= pvIdx && rootMoves[i].score != -VALUE_INFINITE);
|
bool updated = rootMoves[i].score != -VALUE_INFINITE;
|
||||||
|
|
||||||
if (depth == 1 && !updated)
|
if (depth == 1 && !updated)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (c) 2013 Ronald de Man
|
Copyright (c) 2013 Ronald de Man
|
||||||
Copyright (C) 2016-2019 Marco Costalba, Lucas Braesch
|
Copyright (C) 2016-2020 Marco Costalba, Lucas Braesch
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -684,7 +684,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||||
bool blackStronger = (pos.material_key() != entry->key);
|
bool blackStronger = (pos.material_key() != entry->key);
|
||||||
|
|
||||||
int flipColor = (symmetricBlackToMove || blackStronger) * 8;
|
int flipColor = (symmetricBlackToMove || blackStronger) * 8;
|
||||||
int flipSquares = (symmetricBlackToMove || blackStronger) * 070;
|
int flipSquares = (symmetricBlackToMove || blackStronger) * 56;
|
||||||
int stm = (symmetricBlackToMove || blackStronger) ^ pos.side_to_move();
|
int stm = (symmetricBlackToMove || blackStronger) ^ pos.side_to_move();
|
||||||
|
|
||||||
// For pawns, TB files store 4 separate tables according if leading pawn is on
|
// For pawns, TB files store 4 separate tables according if leading pawn is on
|
||||||
|
@ -707,9 +707,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||||
|
|
||||||
std::swap(squares[0], *std::max_element(squares, squares + leadPawnsCnt, pawns_comp));
|
std::swap(squares[0], *std::max_element(squares, squares + leadPawnsCnt, pawns_comp));
|
||||||
|
|
||||||
tbFile = file_of(squares[0]);
|
tbFile = map_to_queenside(file_of(squares[0]));
|
||||||
if (tbFile > FILE_D)
|
|
||||||
tbFile = file_of(squares[0] ^ 7); // Horizontal flip: SQ_H1 -> SQ_A1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DTZ tables are one-sided, i.e. they store positions only for white to
|
// DTZ tables are one-sided, i.e. they store positions only for white to
|
||||||
|
@ -733,8 +731,8 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||||
|
|
||||||
// Then we reorder the pieces to have the same sequence as the one stored
|
// Then we reorder the pieces to have the same sequence as the one stored
|
||||||
// in pieces[i]: the sequence that ensures the best compression.
|
// in pieces[i]: the sequence that ensures the best compression.
|
||||||
for (int i = leadPawnsCnt; i < size; ++i)
|
for (int i = leadPawnsCnt; i < size - 1; ++i)
|
||||||
for (int j = i; j < size; ++j)
|
for (int j = i + 1; j < size; ++j)
|
||||||
if (d->pieces[i] == pieces[j])
|
if (d->pieces[i] == pieces[j])
|
||||||
{
|
{
|
||||||
std::swap(pieces[i], pieces[j]);
|
std::swap(pieces[i], pieces[j]);
|
||||||
|
@ -765,7 +763,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||||
// piece is below RANK_5.
|
// piece is below RANK_5.
|
||||||
if (rank_of(squares[0]) > RANK_4)
|
if (rank_of(squares[0]) > RANK_4)
|
||||||
for (int i = 0; i < size; ++i)
|
for (int i = 0; i < size; ++i)
|
||||||
squares[i] ^= 070; // Vertical flip: SQ_A8 -> SQ_A1
|
squares[i] ^= SQ_A8; // Vertical flip: SQ_A8 -> SQ_A1
|
||||||
|
|
||||||
// Look for the first piece of the leading group not on the A1-D4 diagonal
|
// Look for the first piece of the leading group not on the A1-D4 diagonal
|
||||||
// and ensure it is mapped below the diagonal.
|
// and ensure it is mapped below the diagonal.
|
||||||
|
@ -1063,8 +1061,8 @@ void set(T& e, uint8_t* data) {
|
||||||
|
|
||||||
enum { Split = 1, HasPawns = 2 };
|
enum { Split = 1, HasPawns = 2 };
|
||||||
|
|
||||||
assert(e.hasPawns == !!(*data & HasPawns));
|
assert(e.hasPawns == bool(*data & HasPawns));
|
||||||
assert((e.key != e.key2) == !!(*data & Split));
|
assert((e.key != e.key2) == bool(*data & Split));
|
||||||
|
|
||||||
data++; // First byte stores flags
|
data++; // First byte stores flags
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (c) 2013 Ronald de Man
|
Copyright (c) 2013 Ronald de Man
|
||||||
Copyright (C) 2016-2019 Marco Costalba, Lucas Braesch
|
Copyright (C) 2016-2020 Marco Costalba, Lucas Braesch
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -71,13 +71,13 @@ void Thread::clear() {
|
||||||
captureHistory.fill(0);
|
captureHistory.fill(0);
|
||||||
|
|
||||||
for (bool inCheck : { false, true })
|
for (bool inCheck : { false, true })
|
||||||
for (StatsType c : { NoCaptures, Captures })
|
for (StatsType c : { NoCaptures, Captures })
|
||||||
for (auto& to : continuationHistory[inCheck][c])
|
for (auto& to : continuationHistory[inCheck][c])
|
||||||
for (auto& h : to)
|
for (auto& h : to)
|
||||||
h->fill(0);
|
h->fill(0);
|
||||||
|
|
||||||
for (bool inCheck : { false, true })
|
for (bool inCheck : { false, true })
|
||||||
for (StatsType c : { NoCaptures, Captures })
|
for (StatsType c : { NoCaptures, Captures })
|
||||||
continuationHistory[inCheck][c][NO_PIECE][0]->fill(Search::CounterMovePruneThreshold - 1);
|
continuationHistory[inCheck][c][NO_PIECE][0]->fill(Search::CounterMovePruneThreshold - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +182,7 @@ void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
|
||||||
main()->wait_for_search_finished();
|
main()->wait_for_search_finished();
|
||||||
|
|
||||||
main()->stopOnPonderhit = stop = false;
|
main()->stopOnPonderhit = stop = false;
|
||||||
|
increaseDepth = true;
|
||||||
main()->ponder = ponderMode;
|
main()->ponder = ponderMode;
|
||||||
Search::Limits = limits;
|
Search::Limits = limits;
|
||||||
Search::RootMoves rootMoves;
|
Search::RootMoves rootMoves;
|
||||||
|
@ -210,7 +211,7 @@ void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
|
||||||
|
|
||||||
for (Thread* th : *this)
|
for (Thread* th : *this)
|
||||||
{
|
{
|
||||||
th->shuffleExts = th->nodes = th->tbHits = th->TTsaves = th->nmpMinPly = 0;
|
th->nodes = th->tbHits = th->TTsaves = th->nmpMinPly = 0;
|
||||||
th->rootDepth = th->completedDepth = 0;
|
th->rootDepth = th->completedDepth = 0;
|
||||||
th->rootMoves = rootMoves;
|
th->rootMoves = rootMoves;
|
||||||
th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th);
|
th->rootPos.set(pos.fen(), pos.is_chess960(), &setupStates->back(), th);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -61,7 +61,8 @@ public:
|
||||||
|
|
||||||
Pawns::Table pawnsTable;
|
Pawns::Table pawnsTable;
|
||||||
Material::Table materialTable;
|
Material::Table materialTable;
|
||||||
size_t pvIdx, pvLast, shuffleExts;
|
size_t pvIdx, pvLast;
|
||||||
|
uint64_t ttHitAverage;
|
||||||
int selDepth, nmpMinPly;
|
int selDepth, nmpMinPly;
|
||||||
Color nmpColor;
|
Color nmpColor;
|
||||||
std::atomic<uint64_t> nodes, tbHits, TTsaves, bestMoveChanges;
|
std::atomic<uint64_t> nodes, tbHits, TTsaves, bestMoveChanges;
|
||||||
|
@ -95,6 +96,7 @@ struct MainThread : public Thread {
|
||||||
|
|
||||||
double previousTimeReduction;
|
double previousTimeReduction;
|
||||||
Value previousScore;
|
Value previousScore;
|
||||||
|
Value iterValue[4];
|
||||||
int callsCnt;
|
int callsCnt;
|
||||||
bool stopOnPonderhit;
|
bool stopOnPonderhit;
|
||||||
std::atomic_bool ponder;
|
std::atomic_bool ponder;
|
||||||
|
@ -116,7 +118,7 @@ struct ThreadPool : public std::vector<Thread*> {
|
||||||
uint64_t tb_hits() const { return accumulate(&Thread::tbHits); }
|
uint64_t tb_hits() const { return accumulate(&Thread::tbHits); }
|
||||||
uint64_t TT_saves() const { return accumulate(&Thread::TTsaves); }
|
uint64_t TT_saves() const { return accumulate(&Thread::TTsaves); }
|
||||||
|
|
||||||
std::atomic_bool stop;
|
std::atomic_bool stop, increaseDepth;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StateListPtr setupStates;
|
StateListPtr setupStates;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
2
src/tt.h
2
src/tt.h
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
12
src/types.h
12
src/types.h
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -180,10 +180,10 @@ enum Value : int {
|
||||||
VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY,
|
VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY,
|
||||||
|
|
||||||
PawnValueMg = 128, PawnValueEg = 213,
|
PawnValueMg = 128, PawnValueEg = 213,
|
||||||
KnightValueMg = 782, KnightValueEg = 865,
|
KnightValueMg = 781, KnightValueEg = 854,
|
||||||
BishopValueMg = 830, BishopValueEg = 918,
|
BishopValueMg = 825, BishopValueEg = 915,
|
||||||
RookValueMg = 1289, RookValueEg = 1378,
|
RookValueMg = 1276, RookValueEg = 1380,
|
||||||
QueenValueMg = 2529, QueenValueEg = 2687,
|
QueenValueMg = 2538, QueenValueEg = 2682,
|
||||||
|
|
||||||
MidgameLimit = 15258, EndgameLimit = 3915
|
MidgameLimit = 15258, EndgameLimit = 3915
|
||||||
};
|
};
|
||||||
|
@ -341,7 +341,7 @@ inline Score operator*(Score s, int i) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiplication of a Score by an boolean
|
/// Multiplication of a Score by a boolean
|
||||||
inline Score operator*(Score s, bool b) {
|
inline Score operator*(Score s, bool b) {
|
||||||
return Score(int(s) * int(b));
|
return Score(int(s) * int(b));
|
||||||
}
|
}
|
||||||
|
|
23
src/uci.cpp
23
src/uci.cpp
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -147,7 +147,7 @@ namespace {
|
||||||
uint64_t num, nodes = 0, cnt = 1;
|
uint64_t num, nodes = 0, cnt = 1;
|
||||||
|
|
||||||
vector<string> list = setup_bench(pos, args);
|
vector<string> list = setup_bench(pos, args);
|
||||||
num = count_if(list.begin(), list.end(), [](string s) { return s.find("go ") == 0; });
|
num = count_if(list.begin(), list.end(), [](string s) { return s.find("go ") == 0 || s.find("eval") == 0; });
|
||||||
|
|
||||||
TimePoint elapsed = now();
|
TimePoint elapsed = now();
|
||||||
|
|
||||||
|
@ -156,13 +156,18 @@ namespace {
|
||||||
istringstream is(cmd);
|
istringstream is(cmd);
|
||||||
is >> skipws >> token;
|
is >> skipws >> token;
|
||||||
|
|
||||||
if (token == "go")
|
if (token == "go" || token == "eval")
|
||||||
{
|
{
|
||||||
if (Cluster::is_root())
|
if (Cluster::is_root())
|
||||||
cerr << "\nPosition: " << cnt++ << '/' << num << endl;
|
cerr << "\nPosition: " << cnt++ << '/' << num << endl;
|
||||||
go(pos, is, states);
|
if (token == "go")
|
||||||
Threads.main()->wait_for_search_finished();
|
{
|
||||||
nodes += Cluster::nodes_searched();
|
go(pos, is, states);
|
||||||
|
Threads.main()->wait_for_search_finished();
|
||||||
|
nodes += Threads.nodes_searched();
|
||||||
|
}
|
||||||
|
else if (Cluster::is_root())
|
||||||
|
sync_cout << "\n" << Eval::trace(pos) << sync_endl;
|
||||||
}
|
}
|
||||||
else if (token == "setoption") setoption(is);
|
else if (token == "setoption") setoption(is);
|
||||||
else if (token == "position") position(pos, is, states);
|
else if (token == "position") position(pos, is, states);
|
||||||
|
@ -234,12 +239,14 @@ void UCI::loop(int argc, char* argv[]) {
|
||||||
|
|
||||||
// Additional custom non-UCI commands, mainly for debugging.
|
// Additional custom non-UCI commands, mainly for debugging.
|
||||||
// Do not use these commands during a search!
|
// Do not use these commands during a search!
|
||||||
else if (token == "flip") pos.flip();
|
else if (token == "flip") pos.flip();
|
||||||
else if (token == "bench") bench(pos, is, states);
|
else if (token == "bench") bench(pos, is, states);
|
||||||
else if (token == "d" && Cluster::is_root())
|
else if (token == "d" && Cluster::is_root())
|
||||||
sync_cout << pos << sync_endl;
|
sync_cout << pos << sync_endl;
|
||||||
else if (token == "eval" && Cluster::is_root())
|
else if (token == "eval" && Cluster::is_root())
|
||||||
sync_cout << Eval::trace(pos) << sync_endl;
|
sync_cout << Eval::trace(pos) << sync_endl;
|
||||||
|
else if (token == "compiler" && Cluster::is_root())
|
||||||
|
sync_cout << compiler_info() << sync_endl;
|
||||||
else if (Cluster::is_root())
|
else if (Cluster::is_root())
|
||||||
sync_cout << "Unknown command: " << cmd << sync_endl;
|
sync_cout << "Unknown command: " << cmd << sync_endl;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||||
Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
Loading…
Add table
Reference in a new issue