# HG changeset patch # User Mike Becker # Date 1788792649 -7200 # Node ID 338795f5837b8f240e86754ad492053fb98629c9 # Parent 04da225a5677ffb3f75b4e1c546e3dc432437446 fixes parsing of en-passant threat in fen_parse() relates to #939 diff -r 04da225a5677 -r 338795f5837b src/chess/fen.c --- a/src/chess/fen.c Sat Sep 05 13:03:09 2026 +0200 +++ b/src/chess/fen.c Mon Sep 07 16:50:49 2026 +0200 @@ -265,6 +265,7 @@ } /* the threat is applied to the pawn, not the field it passed */ enpassant_threat_add(gamestate, f, r); + str += 2; } else { return 1; } diff -r 04da225a5677 -r 338795f5837b test/test-fen.c --- a/test/test-fen.c Sat Sep 05 13:03:09 2026 +0200 +++ b/test/test-fen.c Mon Sep 07 16:50:49 2026 +0200 @@ -191,6 +191,32 @@ gamestate_cleanup(&gs); } +static CX_TEST(test_fen_enpassant) { + /* this test contains a full game where white is checkmated */ + const char * fen = "rnQ4r/pp4kp/3p2pn/1BpPp1N1/5P2/2BK4/P1P3qP/8 w - e6 0 19"; + GameState gs; + int result = fen_parse(fen, &gs); + CX_TEST_DO { + CX_TEST_ASSERT(result == 0); + /* verify that only e5 has an active enpassant threat */ + for (File f = 0 ; f < 8 ; f++) { + for (Rank r = 0 ; r < 8 ; r++) { + if (f == fileidx('e') && r == rankidx('5')) { + CX_TEST_ASSERT(enpassant_threat_exists(&gs, f, r)); + } else { + CX_TEST_ASSERT(!enpassant_threat_exists(&gs, f, r)); + } + } + } + + /* check that we get the original FEN back */ + char fen_chk[FEN_MAX_LENGTH]; + fen_compute(fen_chk, &gs); + CX_TEST_ASSERTM(strcmp(fen, fen_chk) == 0, fen_chk); + } + gamestate_cleanup(&gs); +} + CxTestSuite* test_fen_suite(void) { CxTestSuite* suite = cx_test_suite_new("Test FEN API"); @@ -198,7 +224,7 @@ cx_test_register(suite, test_fen_with_castling_rights); cx_test_register(suite, test_fen_checkmate); // TODO: test FENs that describe stalemate, threefold, no-material positions - // TODO: test FEN with en-passant threat + cx_test_register(suite, test_fen_enpassant); return suite; }