Since you’re here...

We hope you will consider supporting us today. We need your support to continue to exist, because good entries are more and more work time. Every reader contribution, however big or small, is so valuable. Support "Chess Engines Diary" even a small amount– and it only takes a minute. Thank you.
============================== My email: jotes@go2.pl



Chal 1.3.1 - new version chess engine

Chal - UCI Chess Engine
Author: Naman Thanki

Strength

v1.3.0 is estimated at ~2100 Elo, validated across thousands of games
against known reference engines. The headline result is a convincing win over
Stash v14 (~2054 Elo) by a good margin in gauntlet play.

SPRT test against the previous version:

Results of ChalTest vs ChalBase (8+0.08, UHO_Lichess_4852_v1.epd):
Elo: +224.27 ± 51.54  |  LOS: 100%  |  DrawRatio: 19.61%
Wins: 144  Losses: 28  Draws: 32  (78.43%)
LLR: 2.94 (100.0%) [-2.94, 2.94] — SPRT [0.00, 10.00] H1 accepted

Evaluation — PeSTO tapered eval

The evaluation function has been completely replaced. The old hand-crafted
piece-square tables and MAX_PHASE material blend give way to Rofchade's
Texel-tuned PeSTO MG/EG tables with a proper 0–24 phase counter.

  • Separate mg_pst / eg_pst tables (6 piece types × 64 squares each)
  • Separate mg_val / eg_val material values; piece_val[] kept for MVV-LVA
  • Tapered blend: (mg * phase + eg * (24 - phase)) / 24
  • Mobility centered on mob_center[] so inactive pieces are penalised rather
    than all pieces receiving a flat bonus
  • Pawn shield MG-only; EG king centralisation handled by the EG king PST
  • Rook open/semi-open file and 7th-rank bonuses applied to both MG and EG
  • Passed-pawn bonus removed — it double-counted the PeSTO EG pawn table
  • Eval loop replaced with a 64-square rank×file pass; occupied squares cached
    in pseudo_list[] so the rook activity pass never visits an empty square

Search — correctness and architecture

search() signature change (breaking):

int search(int depth, int alpha, int beta, int was_null, int sply);

A new explicit sply (ply-from-root) parameter replaces the
#define sply (ply - root_ply) macro. Killer moves are now unambiguously
indexed by ply-from-root and null-move pruning passes sply + 1 cleanly
with no global mutation needed.

BugFix
Double null movewas_null parameter; NMP skips when was_null=1
Fail-hard / fail-soft mixAll returns use actual scores throughout
TT mate score corruptionEncode/decode relative to node sply
TT cutoffs on PV nodesis_pv guard prevents hash cutoffs narrowing the PV window
LMR is_cap read after make_moveSaved before make_move
LMR gives-check directionIN_CHECK(side) after make_move tests the right side
NMP returns beta not scFixed to return sc (fail-soft)
QS stand-pat fail-hardReturns best_sc throughout
QS null-window before first move(caps_only || legal==1) guard
KRK / KQK falsely drawnhas_major flag in insufficient-material check
Repetition — in-tree vs historyIn-tree: 1 prior = draw; history: 2 prior = draw
PVS first-move window|| best_sc == -INF sentinel covers first legal move

Move ordering

  • sort_moves() (full O(n²) upfront sort) replaced by score_moves() +
    pick_move(): moves are pre-scored once then selected lazily, paying O(n)
    only for moves actually searched
  • EP captures now scored as pawn captures under MVV-LVA (previously fell
    through to quiet move ordering)
  • Score tiers raised to eliminate overlap and give each category an unambiguous bucket:
ScoreCategory
30000Hash move
20000 – 28900Captures (20000 + 10×cap_val − atk_val)
19999Promotion
19998Killer slot 0
19997Killer slot 1
0 – 19996History heuristic

Chal 1.3.1 download


Comments