Wasp Release Notes Feb 28, 2023 Author: John Stanback License: This chess engine is free for anyone to use. Most Recent Executable files: Wasp650-windows-avx.exe : Windows 64-bit, for Intel Haswell or newer CPU (uses popcnt, ctz, clz, 256-bit MM registers) Wasp650-windows.exe : Windows 64-bit, for Intel Nehalem or newer CPU (uses popcnt, bsf, bsr, 128-bit MM registers) Wasp650-windows-ancient.exe : Windows 64-bit, for older CPU's (uses software popcnt, ctz, clz) Wasp650-linux-avx : Linux 64-bit, for Intel Haswell or newer CPU Wasp650-linux-sse : Linux 64-bit, for Intel Nehalem or newer CPU Wasp650-linux-ancient : Linux 64-bit, for older CPU's Wasp650-RPi3 : Raspberry Pi 3 Wasp650-RPiZ : Raspberry Pi Z Benchmark data (Ryzen 7950x): command: Wasp650-windows-avx.exe -bench total time= 16.89 seconds, nodes= 36394688, nps= 2155376 (~5.4 Ghz) command: Wasp650-windows-avx.exe -bench -d 21 -threads 32 total time= 34.07 seconds, nodes= 1251254016, nps= 36729788 (~4.8 Ghz) UCI Options: Name Default Description Value ---------------------------------------------------------------------------- ConfigFilePath none Path to a file containing UCI commands (optional) Hash 64 Main Hash table size in Mbytes. Threads 1 Number of search threads. Clear_Hash NA Clear the main Hash table. NN_file embedded Path to neural network weights file Use_NN_eval true Enable or disable using NN eval. If false then the hand-crafted eval (hce) is used. OwnBook false Enable or disable opening book. OwnBook_File Path to OwnBook file (polyglot .bin format). OwnBook_Depth 24 Book probe depth in half-moves. OwnBook2_File 2nd OwnBook file, probed if no move in 1st book. OwnBook2_Depth 0 2nd book probe depth in half-moves. OwnBook_Variety 25 Adjusts how Wasp chooses book moves based on the "weight" value for each move. Increasing OwnBook_Variety causes moves with lower weight to be played more frequently while reducing the value gives more priority to higher weighted moves. SyzygyPath Path to Syzygy tablebases. SyzygyProbeDepth6 1 Minimum probe depth for 6-piece TB's. If Syzygy TB's are on a hard drive, this parameter should probably be increased to 3 or 4. Log false Write UCI output to the file "wasp.log". Ponder true Enable or disable thinking on opponent's time. MultiPV 1 Wasp will do searches to find this number of best moves (and associated principle variations). UCI_Chess960 false Set to true if playing Chess960. MoveOverhead 50 This number of milliseconds is subtracted from from the target search time for each move to account for I/O overhead or lag. UCI_LimitStrength false If set to true, Wasp will limit playing strength by reducing the nodes searched per second. UCI_Elo XXXX The default is the maximum Elo estimated from the nodes/second for a short search done at program startup. If a value below this is given and the UCI_LimitStrength parameter is set to true, Wasp will reduce playing strength by searching at a slower rate. Contempt 0 When nearly all the pieces and pawns are on the board, Wasp will add this value to it's own score. As material is traded, this penalty/bonus is pulled toward 0. A negative value encourages Wasp to play for a draw while a positive value encourages it to avoid a draw. Selectivity 100 Increase to search more deeply, decrease for a wider search. Optional Command Line options -cfg config_file # Wasp will read UCI commands from a configuration file -log # Wasp will log UCI I/O to the file "wasp.log" -bench [-d N] # Wasp will run a benchmark test to depth d (default d=17) -hash hashsize # Wasp will use hashsize Mbytes for main hashtable -threads N # Wasp will search using N threads Release notes for Wasp 6.50, Feb 28, 2023 I estimate that Wasp 6.50 is about 50 Elo stronger than Wasp 6.00. The neural network for evaluation is similar to Wasp 6.00 except that the number of neurons in the hidden layer has been increased to 1536. Positions from games played in the last 6 months were added to the training data bringing the total to about 220M positions. The positions were re-scored using a fixed 35K node search and a recent net. The target used to train the net is now based 80% on the search score and 20% on the game result. To create the final network, two 1024 nets were created and each were trained using about 300 "epochs" of 500M positions. These networks were then merged to create a 2048 neuron net and trained with about 50 additional "epochs". This net was then pruned to 1536 neurons and trained with about 50 more "epochs". I have no idea if this merging and pruning technique is actually better than just creating and training several 1536 node nets and picking the best one. Several relatively minor changes were made to the search: - slightly less aggressive LMR at PV nodes - slightly more aggressive LMR at non-PV nodes - less aggressive LMP and LMR if eval is improving - allow static eval and null-move pruning even if beta is a "mated" score - slight change to the move history statistics calculation - increased the aspiration window when the score from the previous iteration is a TB win/loss or mate/mated to eliminate search failing high then low and speed up mates - changed the conditions where slave threads skip search iterations: if more than 15 threads are already searching at a given depth, skip to depth+1, more than 45 threads, skip to depth+2 Wasp now usses the "Pyrrhic" library to probe Syzygy TB's. Many thanks to Basil Fucinelli, Jon Dart, Andrew Grant, and of course Ronald de Man. This library allows Wasp to use TB's for endings up to 7 pieces. Release notes for Wasp 6.00, August 22, 2022 I estimate that Wasp 6.00 is about 65 Elo stronger than Wasp 5.50. The Neural Network structure is as follows: - 768 inputs for piece/square combinations with kings on same flank - 768 inputs for piece/square combinations with kings on opposite flanks - 36 inputs for material difference - One hidden layer with 896 nodes, using "leaky ReLU" activation. - Seven outputs using Sigmoid activation. Non-pawn material is used to select one of these 7 outputs. For example, output 0 is used if 2 or fewer minors have been traded, output 6 is used for king and pawn endings. NN processing now uses integer math when playing (floating point math is used for training). This gave a speedup of about 18%. Wasp was trained using about 170 million positions taken from games between Wasp and engines of similar strength. The positions were analyzed by a recent version of WaspNN using a fixed 30K node search. The target score for training was based 25% on game result and 75% on the search score. A total of about 1500 passes through the training positions (over 250 billion samples altogether) were used to train the net. No changes were made to the search. Release notes for Wasp 5.50, April 12, 2022 I estimate Wasp 5.50 to be about 50 Elo stronger than Wasp 5.20. The Neural Network used for position evaluation is now embedded int the Wasp binary file, so an nn.bin file is no longer required. The Neural Network structure is as follows: - 1824 Inputs (2x2x7x64 for piece/square combinations plus 32 for material difference). - Only one hidden layer with 640 nodes, using "leaky ReLU" activation. - Three outputs, using sigmoid activation. If either side has any non-pawn pieces the evaluation is interpolated from the first two outputs. For king and pawn endgames the third output is used. The NN was trained on a dataset of about 130M positions taken from games between Wasp and various engines of roughly similar strength (including previous versions of Wasp). The target value used for training is based 50% on game result and 50% on Wasp's score from a 10K node search. The net was trained using a total of about 150 billion samples which took about 56 hours using 24 threads. I continue to add positions to the training dataset and hope that this will give some improvement for future versions. A few small changes were made to the search. These include modifications to the criteria used for static null move pruning, constants used for updating the move history counters, and late-move reduction criteria. ***** Previous release notes ************************************************ Wasp 5.20, Jan 1, 2022 I estimate Wasp 5.20 to be about 20 Elo stronger than Wasp 5.00. Changes since Version 5.00 are: - Implemented Fischer Random Chess (Chess 960) - Neural Network for evaluation is different 1792 piece/square inputs (2x14x64) (6 pieces plus passed pawns for white and black, different sets of inputs for kings on same or opposite flanks.) 38 non-pawn material difference inputs 256 nodes in 1st hidden layer 24 nodes in 2nd hidden layer 6 nodes in 3rd hidden layer The Layer 3 nodes are used to feed the output as follows: node 1 and : for most positions the output is interpolated node 2 between nodes 1 and 2 based on material node 3 : king + pawns endgame node 4 : king + pawns + 1 minor per side node 5 : king + pawns + 1 rook per side node 6 : king + pawns + 1 queen per side - NN evaluation code contains some speedup - NN training set includes more positions from recent Wasp games including a relatively small number (~300K) of FRC games. - Wasp gets a slight bonus with all material remaining which decreases to a slight penalty when no material is left. This encourages Wasp to avoid trades early in the game and to try to draw in the endgame unless it has an advantage. - Wasp now uses a hybrid evaluation where the NN eval is used unless either side has a material advantage of at least 4 pawns in which case the old "hand-crafted eval" is used. This gives a speedup in most positions since the search often contains a lot of unbalanced positions. - Wasp now defaults to looking for the nn.bin file in the same directory as the executable file rather than in directory from which it was launched. Wasp 5.00, Nov 17, 2021 I estimate Wasp 5.0 to be about 70 Elo stronger than Wasp 4.5. The strength increase is due to use of a neural network for position evaluation. Changes to Search include: - Instead of having a thread pool Wasp now creates/destroys search threads at the start/end of each search. - The search depth is extended by one ply after a passed pawn is pushed to the 6th or 7th rank, if depth is 2 or less. - Slight modification to late move reduction formula. - Eliminated pruning of winning captures that fail-high with a reduced depth search and margin (usually called ProbCut pruning). - Modified static eval pruning to detect hung pieces for the side to move and threats by enemy pawns on 6th and 7th ranks and adjust the pruning margin accordingly (hung pieces were previously detected during the evaluation). Changes to Evaluation: The hand-crafted evaluation function has been replaced with two small neural networks. The structure of each neural network is: - 1792 piece/square inputs (2x14x64) (6 pieces plus passed pawns for white and black, different sets of inputs for kings on same or opposite flanks.) - 38 non-pawn material difference inputs - 192 nodes in 1st hidden layer - 16 nodes in 2nd hidden layer - 2 nodes in 3rd hidden layer The first NN is a "general" NN and is used for most positions. The second NN is for king and pawn endgames. For the general NN the weights from the third hidden layer to the output are set based on the non-pawn material on the board, similar to a typical hand-crafted eval. All weights and hidden-layer node values are 4-byte floating point. Eventually I will probably try to speed up the eval by converting the weights and calculations to integers. The first hidden layer node values are incrementally updated, but this only increases the nodes/second by about 10%. Creating training positions: To generate training positions I used positions from about 5M games played between Wasp and engines within about 100 Elo of Wasp in strength. Most of these games were played at very fast time controls such as Game in 15 seconds with a 0.15 second increment. About 10% of the positions from these games were extracted, searched to a depth of 2, and the quiescent positions from the end of the PV were saved along with the game result. These positions were then searched to a depth of 5 and the score was saved along with the game result. This resulted in an EPD file of about 75M positions. The target win-fraction for each position is a weighted avergage of the win probability for the depth 5 search score and the game result. Training the NN: All weights are initially set to random values between -1.0 and +1.0. A position from the training set is randomly chosen, evaluated by the NN, and the error between the NN eval and the target eval is back-propogated to calculate an adjustment for all relevant weights in the network. To improve coverage for all possible piece/sq combinations, some of the training positions are not directly used but instead an 8-ply "random move" playout is done and the Wasp hce is used as the target. Fully training the network takes about 100 passes of 500M positions each for a total of about 50B positions. This takes about 35 hours using 24 threads. For the early passes, half of the training positions used are from the "random-move" playouts. This fraction is reduced for later passes. The learn-rate is exponentially decayed during training. The NN can have some crazy evaluations, for example it typically evaluates a KRK ending as less than 250cp for the winning side and Wasp doesn't make progress unless the search is more than 10 plies deep. I suspect that a better or larger set of training positions will improve this. Wasp 4.5, Dec 29, 2021 I estimate Wasp 4.5 to be about 50 Elo stronger than Wasp 4.0. Most of the strength increase comes from a re-write of the evaluation function and re-tuning of all the evaluation terms. A new tuning algorithm allows all eval parameters to be tuned simultaneously at a rate of about 250K positions per second. Changes to Search include: - Always extend search by 1 ply when in check even if checking piece can be safely captured. - Limit reduction for tactical moves to 1 ply for safe moves, 2 plies if unsafe. - Simplified time management and increased the fraction of remaining time that can be used when failing low or high or when score has dropped during the current or previous iteration. - Code cleanup and slight speedups to Swapoff(), MoveGivesCheck() and MoveIsSafe() functions. - Fixed a bug in HashMoveIsLegal() function which could cause an occasional crash at long time control with many threads. Changes to Evaluation: The entire evaluation function was re-written to allow for much faster parameter tuning. The eval uses conventional features such as material, piece-square tables, mobility, and king-safety etc... Most of the eval terms are similar or identical to those in Wasp 4.0, but a few have been modified. A second set of PST's is now used when the kings are on opposite wings. Tuning is now done in a similar fashion to back-propogation for neural networks rather than the gradient-descent method that was previously used. Tuning was done on a set of 28M positions randomly selected from about 2M games between Wasp and engines of similar strength. I use Andrew Grant's method of doing a shallow (only depth 2) search and storing the quiet position at the end of the PV along with the game result. All evaluation parameters are initialized to what I feel are "reasonable" values, then the parameters are tuned with about 40 passes through a 28M position EPD file, which takes around an hour using 1 thread. During tuning, for each position in the data set the evaluation is done and a counter is incremented for each feature that is used in computing the eval. The error between the eval (converted to win-probabilty) and the game result (0.0/0.5/1.0 for loss/draw/win) is computed and each pertinent term is tweaked by a small amount in the direction to reduce error. The improved tuning increased Wasp's strength by about 40 Elo. Wasp 4.0, June 13, 2020 Benchmark nodes= 22505886 (run wasp -bench from command prompt) I estimate Wasp 4.0 to be about 45 Elo stronger than Wasp 3.75. A new wasp_book.bin file (polyglot format) was generated from about 790K games between Wasp and various other engines, mostly at very fast time control. This is not intended to be a competitive tournament book, but contains a good variety of openings. Some of the changes in this version are: - The move from hash table is checked thoroughly for legality to prevent crashes, although illegal moves are extremely rare due to use of 32 bits of verification (apart from index). - Eliminated generation of most illegal moves when in-check. This gives a small speedup. - Added "countermove" History table indexed by color, piece type for previous move, piece type for current move, and to-square. - Increased depth for late-move pruning from 5 to 6 and slightly reduced late-move count. - Allow more than one ply reduction for tactical moves. - Modified late-move reduction formula to give slightly higher depth reduction as depth and move count increase. - Removed increase in reduction when static evaluation is decreasing. - Added 1 ply depth reduction (prior to moveloop) for non-pv nodes if at least 5 moves have already tried at previous node and the static eval minus a threat term is greater than beta. This is similar to the depth reduction I used in Zarkov starting with version 2.5 :) - Increased null-move reduction to 4 plies for depth >= 10. - Modified formula used to determine nodes/sec for reduced Elo levels. Also, for Elo < 2200 a depth reduction of 3 plies is applied at a fraction of nodes to try to introduce some blunders. - Made slight modifications to king safety and passed pawn routines. - Added threat by pawn-push term somewhat similar to Stockfish. - Modified evaluation scaling when winning side has 3 or fewer pawns and few pieces. - Re-tuned all evaluation parameters using "texel" method on a ~2M position EPD file from Wasp gauntlet games. Manually tweaked various eval parameters after this. - Did a lot of code clean-up. Wasp 3.75, Sep 1, 2019 Benchmark nodes= 23528944 (run wasp -bench from command prompt) I estimate about 45 Elo improvement for Wasp 3.75 over Wasp 3.6. This is based mostly on lots of games at ultra-fast time control. Wasp no longer uses the wasp.rc resource configuration file. Instead, some search and evaluation parameters are now available via UCI options. These additional uci options are invoked using the command-line option "-uci_extra", for example: "Wasp375-x64-modern.exe -uci_extra". Wasp now uses the Polyglot *.bin book format for it's OwnBook. An opening book can be created from a PGN file using the "-mkbook" command-line option. For example, to create a .bin book from the file "mybook.pgn", from a command prompt type: "Wasp375-x64-modern.exe -mkbook mybook.pgn" Wasp will read games from mybook.pgn and create the file "tmp_book.bin". You can rename this file to whatever you want and use it as a Wasp OwnBook or with other chess software that supports the Polyglot .bin format. The "weight" parameter for each move is based on frequency of occurance and game result using this formula: weight = 4*nwins - 2*nlosses + ndraws Moves with weight less than 10 or fewer than 3 wins are pruned. The included "wasp_book.bin" file was created from a bunch of engine-engine games, mostly at very fast time control. To achieve a lot of variety and cover the ECO codes well, most of the games started with 6 moves randomly played from Frank Quisinsky's FEOBOS openings. Some of the changes for this version are: - Changed main hash table minimum store/probe depth from 1 to 0. - Modified formula for late move reduction. - Modified formula for updating the history table. - Eliminated depth extension for safe pawn to 7th rank moves. - Reduced size of pawn hash table entry and doubled the #entries. - Added a bonus to encourage keeping pawns when ahead. - Added a non-linear positional score bonus of K*positional_score^2. - Modified some passed pawn and king safety heuristics. - Assign pinned pieces a mobility of 0 instead of giving a penalty. - Tweaked most of the evaluation parameters. Wasp 3.6: April 6, 2019 - Benchmark data: Windows, command "Wasp360-x64-modern -bench" nodes= 36064868 nps= 1694274 (core i5-4690K at 3.9 Ghz) nps= 1542985 (Ryzen 7-1700 at 3.7 Ghz) Linux, command "Wasp360-linux -bench" nps= 1625507 (Ryzen 7-1700 at 3.7 Ghz) RPi3b, command "Wasp360-RPi3b -bench" nps= 148992 - Wasp 3.6 is only about 10 Elo stronger than Wasp 3.5, the main purpose for this release was to add the features to enable setting reduced strength. - Implemented new parameters UCI_LimitStrength and UCI_Elo Setting UCI_LimitStrength to "true" and setting a value for UCI_Elo causes Wasp to insert delays to reduce nodes/sec to an "appropriate" value to try to achieve the requested Elo level. The formulas for converting between Elo and nps are: Elo = 111*LN(nps-20) + 1337 nps = EXP((Elo-1337)/111) + 20 Elo NPS 1500 24 1600 31 1700 46 1800 85 1900 180 2000 413 2100 987 2200 2400 2300 5879 2400 14443 2500 35527 2600 87431 2700 215211 2800 529780 2900 1304195 3000 3210664 - The wasp.rc file is now optional and only needed if user wants to create a custom personality. - Did a lot of code cleanup, but nothing that increases engine speed. - Fixed possible race condition in handling UCI commands that might have could caused Wasp to hang under certain situtations. - Allow maximum of 80 threads instead of 64. - Added UCI "Contempt" parameter. The contempt value represents the evaluation for Wasp when all pieces and pawns are on the board. As material is reduced, the evaluation for an equal position will trend toward 0. The eval for repetition or 50-move rule is always 0. So in an equal position, if contempt is positive Wasp will try to avoid exchanging pieces or drawing while if contempt is negative Wasp will try to exchange pieces or draw. - Modified lazy SMP to skip an iteration if 1+0.65*total_threads are already searching at this iteration. - Modified LMR formula - Allow pruning at PV nodes if ply > 12 and hash table contains an exact score. - Many small tweaks to evaluation function parameters. Wasp 3.5: Dec 13, 2018 - Benchmark data: Windows, command= "Wasp350-x64-modern -bench" nodes = 33042778 nps = 1664833 (core i5-4690K at 3.9 Ghz) nps = 1526541 (Ryzen 7-1700 at 3.7 Ghz) Linux, command= "Wasp350-linux -bench" nps = 1622393 (Ryzen 7-1700 at 3.7 Ghz) - Added Syzygy endgame tablebase support. Many thanks to Ronald de Man for creating these tablebases and to Basil Falcinelli and Jon Dart for the Fathom library that made it easy to access the TB's. - Modified lazy SMP iteration skipping: skip to iteration N+1 if 1+nthreads/2 threads are already searching at iteration N - Only use hash table score to prune at PV nodes if score is a mate value - Razor/futility pruning: if eval << alpha and depth is low, simply return quiescence search score. Note: Qsearch() is called with the current depth so that at this ply only active moves are tried, but if depth >= 2, the opponent may try both active and quiet moves. - Modified LMR formula, also increase reduction 1 extra ply if move is not safe (based on SEE) or if score dropped at least 1.5 pawns from 2 plies earlier - Modified extensions: at PV nodes extend 1 ply for safe checks and pawn to 7th, 0.5 ply for captures near root and 0.25 ply for other captures. Extension is divided by 2 for non-pv nodes. - Increased positional eval by about 15% relative to material eval - Increased bonus for connected pawns - Changed formula for calculating mobility as function of # attacked squares. The values in wasp.rc represent the score difference in centipawns between mobility on empty board and no mobility. - Minor changes to passed pawn and king safety eval. - Minor changes to endgame scaling factor for winner having few pieces and 1 or more pawns - Tweaks to many eval parameters - Cleaned up code in many places Wasp 3.0: May 10, 2018 - added "wasp.rc" runtime configuration file to allow users to modify some search and evaluation parameters - added "-bench" command-line option. bench nodes = 40907656 bench speed = 1665 Knps on i5-4690K at 3.9 Ghz 1542 Knps on Ryzen7-1700 at 3.7 Ghz - modified lazy SMP. slave threads skip an iteration if 2/3 of total threads are already searching at that iteration - limit search extension for safe checks and pawn to 7th to pv nodes or for depth <= 8. - combined razor and futility pruning -- at low depth, if eval is well below alpha prune if qsearch cannot bring score near alpha, otherwise search using normal lmp rules - allow cutoff from hash table at pv nodes if hash depth >= depth+2 - reduced minimum aspiration window at root from 24cp to 15cp - allow search to play moves which have unresolved fail-high when the (extended) time limit is reached - added static null-move pruning for depth <= 2 and eval >= beta+25cp if enemy has no capture good enough to prevent cutoff (sort of similar to Senpai). - added ProbCut pruning for depth >= 4 and static eval >= beta. safe captures are searched to depth-3 and node is pruned if score >= beta+100 - tweaked lmp and lmr formulas - modified hash replacement strategy slightly - improved candidate passed pawn evaluation - tweaked king safety algorithm - tweaked many evaluation function parameters - simplified code in quite a few places Wasp 2.60: Nov 21, 2017 - added UCI option MultiPV - added UCI output for hashfull, currmove, currmovenumber - added "easy" move to save time when only one legal move or capture that appears to be much better than any other move - modified king safety evaluation - tuned piece values, piece square tables and many other eval parameters - tweaked lmp and lmr rules and formula - search speedup for positions with lots of mate positions by enabling hash cutoffs for mate scores regardless of depth searched - modified time management routine - modified lazy SMP implementation to designate the first thread as the "master" thread which updates the PV and score. other threads do iterative deepening loop on root position, but skip an iteration if more than half the threads are already searching that iteration. if master thread completes an iteration and another thread has a different move with better score it will redo that iteration hoping to pick up the better move quickly due to many hash table cutoffs. Wasp 2.01: May 3, 2017 - fixed bug when pondering and search times out (usually due to mate score) - fixed typo in blocked passed pawn penalty Wasp 2.00: April 18, 2017 - added multi-threading using very lazy SMP approach where each thread simply does an iterative deepening loop on the root position and the only communication between threads is the shared main hash table. as others have found, this works surprisingly well. - modified futility pruning, late-move pruning, and late-move reduction formulas to increase selectivity and reduce effective branching factor slightly - simplified extensions-- extend safe checks, safe pawn to 7th, and capture of last enemy piece by one ply. - tweaked many evaluation parameters - move generator now has 3 stages where moves are generated & searched: 1. hash move, 2. captures/promotions, 3. quiet moves Wasp 1.25: Sep 29, 2016 - compiled using new version of gcc (6.1.0) - generate and try hash move (if any) before generating all other moves - slight change to history table updating - slight change to pruning in quiescence search - allow late move pruning and reduction for unsafe checks - changed late move pruning: prune non-tactical moves after 1+3*depth moves have been tried prune if moves_searched >= 3 and eval < alpha-100*depth (futility pruning) - changed late move reduction to reduce by 3 plies if depth >= 6 and moves_searched >= 40 - 2*depth - minor tweaks to most evaluation parameters such as piece values, mobility, king safety, passed pawns ... - added term for king mobility in endgame - removed special KRPKR evaluation function - modified draw adjustment calculation Wasp 1.02: July 1, 2016 fixed bug with sudden-death time control when no "ucinewgame" received compiled 32-bit version for older architecture (use -march=athlon-xp) Wasp 1.01: June 21, 2016, Initial release. **************************************************************************** Here is a bit of info about Wasp John Stanback, updated 20180419 The following Windows compiles are supplied: wasp280-x64-modern.exe : for CPU's with popcnt and ctlz/cttz instructions (haswell) wasp280-x64.exe : for CPU's with popcnt and bsf/bsr instructions (nehalem) wasp280-x64-ancient.exe : for older 64 bit CPU's wasp280-x32.exe : for 32 bit CPU's The UCI options are: Hash = N Mbytes default is 64, max is 8192 Ponder = true/false default is true MultiPV = N default is 1 Clear Hash Communication Overhead = N ms default is 25 OwnBook = true/false default is false Log = true/false default is false Wasp is a chess engine which uses the UCI protocol. It is a complete rewrite of my previous chess engine called Zarkov. Although some search and evaluation ideas are similar, most things have been improved. While Wasp is at least 300 ELO better than any versions of Zarkov it is much weaker than the current top programs. Although I've been doing chess programming for about 40 years, I obviously still have a lot to learn! The search and evaluation concepts used in Wasp are not unique, but the implementation is original, giving Wasp it's own "personality". Wasp supports multi-threading (up to 64 threads) and large hash tables (up to 8192 Mbyte). It does not use endgame tablebases other than a built-in KPK table that is created when the program starts. Bitboards are used for move generation, attacks, and evaluation. The Bitboard implementation is simple with no magic or rotated bitboards. Wasp uses a standard alpha-beta search framework with PVS and aspiration window. A quiescence search is used for depth <= 0 unless the side to move is in check in which case the main search routine is used. The hash table is used only for the main search, not for quiescence, and is not cleared between moves. To improve move ordering, if no hash move is available, internal iterative deepening is done with R=3 for PV nodes and R=4 for non-PV nodes. Wasp generates and tries moves in stages to save time when a cutoff occurs. Moves are generated and tried in the following order: 1. hash move or iid_move (if available) 2. captures and promotions, sorted in MVV-LVA order 3. pawn to 7th rank 4. quiet moves, sorted by killer and history score Unsafe tactical moves are not tried in stages 1-3, but deferred until stage 4 after killers and moves with good history have been tried. To detect whether moves are safe, Wasp uses a recursive swapoff routine (a very simple alpha-beta search on a single square) to determine the expected gain or loss for a move. Wasp extends the search depth by one ply for safe checks, pawn to 7th, and captures of the last remaining enemy piece. The extension is limited to 2 plies except at PV nodes or for depth <= 4. Wasp also extends captures and moves at PV nodes by 1/10 ply. I have not yet been able to get improvements when trying various singular extension methods. Wasp has an effective branching factor of about 1.75 which is achieved using the selective search methods listed below. 1. Cut Node Pruning (CNP) is done at expected CUT nodes which are likely to fail high. This is similar to the forward pruning used in all versions of Zarkov, except that Zarkov pruned at depth 1 and reduced the search depth by one ply at depths 2-5. The primary conditions used for CNP are: depth <= 3 eval >= beta+margin (margin = MAX(hung_material/2,75*depth) !in_check !mate_or_promotion threat !pawn_ending 2. If CNP does not give a cutoff, Static Null Move pruning is tried. The conditions are the same as for CNP except that the margin becomes either 25 centipawns or the swapoff value of the best safe capture the enemy could make plus 100 centipawns. 3. Null move pruning is done at expected CUT nodes with these conditions: depth >= 3 eval >= beta !in_check !pawn_ending For the null move search, depth is reduced by 3 plies for depth < 8, otherwise 4 plies. If the null move fails high and depth >= 5, a verification search with depth reduced by 4 plies is done. 4. Futility pruning is done at non-PV nodes and low depth when eval < alpha-margin (margin = 100+100*depth). For these nodes the move generator only generates captures, checks, promotions, and pawn to 7th. Quiet moves are not generated or searched. 5. Late move pruning is done at non-PV nodes. The conditions are: depth <= 4 moves_searched >= 1+3*depth !in_check !pv_node !tactical (capture,check,promotion,pawn to 6th or 7th) !move_gives_check !move_is_safe_attack_to_bigger_piece 6. Late move reduction is done with these conditions: depth >= 3 moves_searched >= 1 !in_check The depth reduction varies from 0 to 3 plies and is a function of depth and #moves already searched. Tactical moves such as captures, checks, promotions, and pawn to 7th rank are not reduced at PV nodes and the reduction is limited to one ply at non_PV nodes. PV nodes get about one ply less reduction than non-PV nodes. I've tried more aggressive LMR, but for Wasp the size of the search tree is not reduced enough to warrant the additional risk. Wasp has a rather simple evaluation function, but includes the terms that are of highest importance. A small evaluation hash table of 16K positions and a small pawn hash table of 8K positions are used to save time. Each thread has its own Eval and Pawn hash tables. The hit rate for the eval hash table is about 15-25% and the hit rate for the pawn hash table is over 95% on average. The evaluation function uses units of centipawns. The values for material in opening/ending are: pawn = 80 / 102 knight = 335 / 325 bishop = 335 / 330 rook = 470 / 550 queen = 1000 / 1080 bishop_pair = 35 / 35 Passed pawn evaluation depends on the pawn rank, whether it can safely advance one or more squares, friendly and enemy king proximity to the square in front, whether it is blocked, and whether the enemy king is in the square of pawn. The bonus for a pawn on the 7th rank can range from about 80 to 250 centipawns. Pawn evaluation terms include Piece-Square tables (PST), penalties for doubled, isolated, backward, and weak pawns, and a bonus for candidate pawns. Knight evaluation includes only PST, mobility, and outpost bonus and the total value typically falls between about -25 and +25 centipawns. Bishop evaluation includes only PST, mobility, outpost bonus, and a penalty if trapped on squares a7, b8, h7, g8 (mirrored for black). The evaluation is generally between about -15 and +30 centipawns. Rook evaluation includes only PST, mobility, open/half-open file bonus, 7th rank bonus, and trapped penalty. The rook eval typically falls within a range from about -30 to +50 centipawns. Queen evaluation includes only PST, mobility, and 7th rank bonus and the value typically falls between about -15 to +25 centipawns. King evaluation includes PST, king safety, mobility and distance to pawns in endgame. The king safety eval is fairly complex, taking into account the number and type of enemy pieces attacking nearby squares, pieces defending each attacked square, friendly pawn shield, and safe checks by the enemy. The king safety term ranges from about +100 to over -300 centipawns. Wasp assigns a penalty for hung and/or pinned pieces. Wasp assigns a draw value to very simple endgames such as KK, KBK, KNK, KBKN, and KNNK. The only special endgame functions are for KBNK and a mopup function when one side has major pieces and the other side has only a king. Wasp multiplies the evaluation by a scale factor from 0.0 to 1.0 to scale the evaluation for drawish endings such as when the winning side has a minor or less advantage and no pawns or where the losing side can capture the last pawn with a minor, and endings with bishops of opposite color. I've tried tuning evaluation function parameters using very large numbers of super-fast or fixed depth games but without much success. I periodically use the "Texel" parameter tuning method where the average error between a quiescence search score (adjusted to a range of 0..1 using sigmoid function) and the game result (either 0.0, 0.5, or 1.0) is minimized over a large set of positions. I used a few sets of about 2M positions each taken from ultra-blitz games between Wasp and several other engines. My preferred method for optimization is to use a binary search to find the optimum value for each parameter (with all other parameters fixed at the best-known value), then manually change a few parameters part-way toward their optimum value, and repeat the procedure. To determine with some degree of confidence whether changes to the engine are beneficial to playing strength I run ultra-blitz matches against a handful of other engines. I usually run a match of 4000-10000 games at Game/5s + 0.080s and if the results are decent I run a match of 10000+ games at Game/15s + 0.280s. I have two Ryzen7-1700 computers, but it still takes a long time. And most changes are rejected... Thanks very much to Frank Quisinsky for hosting Wasp on his web site and for testing Wasp against a large number of chess engines at a more rational time control than I usually use.