Jacobi: Fairy Chess Helpgame Solver
by François Labelle
Launch the latest version
Jacobi is a program to solve fairy chess proof game problems. Here's an example:
Proof game in 9.5 moves (15+16)
Circe Rex Inclusive
The solution is 1.g3 d5 2.Bg2 d4 3.Bc6+ Kd7 4.Sf3 d3 5.O-O dxe2 6.d3 exf1=R [+wRh1] 7.Sbd2 Rxg1 [+wKe1]+ 8.Sf1 Rxg3 [+wPg2] 9.Se3 e5 10.O-O.
Jacobi solves this in a few minutes:
- 814s with v0.1 in Firefox 52 on an i7-6700 CPU @ 3.40GHz
Jacobi can also solve some ordinary help stipulations but there is very little reason to do that because Jacobi is on average 5x slower than Popeye for this type of problem. In addition, Popeye and WinChloe support more stipulations, fairy conditions, and fairy pieces.
Jacobi can also solve orthodox proof games, but there is very little reason to do that because Jacobi should be slower than Natch or Euclide which are optimized for the orthodox case.
It cannot solve stipulations containing defensive moves, like directmates or selfmate, which is why the subtitle calls it a "helpgame solver". As an exception, Jacobi will accept one defensive halfmove at the very end of the problem.
- solves fairy proof games faster than Popeye in most cases,
- solves proof games with undefined pieces (letter X),
- supports special proof game options like AddPieces and ColorThePieces,
- supports chaining multiple stipulations together.
For now, Jacobi only supports entering problems in a text format similar to Popeye's. Eventually I plan to add a graphical editor, but the text format is still useful to make it possible to keep track of problems in a text file, or to easily exchange problems with others in a forum or by e-mail.
Here are some examples.
By default the initial position is the standard one, so the following will list every possible way to play Fool's mate.
option FirstToMove white
In the example above we had to add "option FirstToMove white" to undo the convention that black plays first in a helpmate of integer length. (This option is different from Popeye's WhiteToPlay which would also remove 0.5 moves from the helpmate.) If you prefer, you can instead use Jacobi's elementary commands, play and test, which aren't loaded with a baggage of conventions:
play help 2.0
Most of the time, input in Popeye's format can be used as is. This is by design so that you can more easily test the same problem in both programs. Since Jacobi can only handle one problem at a time, it accepts but doesn't require BeginProblem and EndProblem. P0527811 by Christopher John Feather in 1975 is a h#2 problem. It would be entered as
P1225028 by Milos Tomasevic and Radovan Tomasevic in 1992 is a ser-sx 126. It would be entered as
stipulation ser-sx 126
In the case of proof games, Jacobi is a bit picky and it requires the forsyth statement to appear immediately after the stipulation statement so it doesn't get confused with an initial position declaration. Technically the diagram is extra data attached to the dia stipulation, which is why I like to put it on the same line (but you can also insert a line break). The example problem at the top of the page is P1068521, entered as
stipulation dia9.5 forsyth rsbq1bsr/pppk1ppp/2B5/4p3/8/3PSSr1/PPP2PPP/R1BQ1RK1
condition Circe RexInclusive
P1000770 by Thierry Le Gleuher in 2000 is a PG 8.5 with the condition EinsteinChess. For fun, let's enter it using French notation. Since v0.3.1, condition names can be entered in French or German in addition to English.
enonce dia8.5 forsyth tc2r2t/ppp1p1pp/3p4/5p2/8/8/PPPPPPPP/TCFDRCFT
The 1st prize of Retros Problemaz 2007 by Paul Rãican is a PG 21.0 with the condition BerolinaChess (available since v0.4.1) and DoubleMaximummer. Fairy pieces with 2-letter symbols can't be specified in forsyth, so we have to use the pieces notation.
stipulation dia 21.0 pieces white Kf2 Se5 BPa2b4c4e4g2g3 black Ke8 Ra8h8 Bc8a3 Sb8f6 BPa7b7d5f5g7
P1243719 by Andrew Buchanan and Richard Stanley in 2001, part (1), is an A-to-B in 5.5 moves. In Jacobi we could still use dia5.5 but to increase compatibility with Popeye we can also write a=>b5.5. Popeye requires the option WhiteToPlay to solve this problem but not Jacobi. The problem would be entered as
stipulation a=>b5.5 forsyth 6k1/3pP1p1/6P1/5PP1/2p5/2p2p2/P4p2/rb1K4
Special proof games
P1305233 by Alexandre Leroux in 2015 is a PG 7.0 with the option AddPieces. Since we no longer care for compatibility with Popeye we can write PG instead of dia if we want (they are synonyms). It would be entered as
stipulation PG 7.0 pieces white Ka5 Pa6 black Re4 AddPieces
P1068165 by Peter Fayers in 2005 is a PG 6.0 with the condition Kriegspiel which (in this case) means the PG option AddWhitePieces. It would be entered as
stipulation PG 6.0 forsyth r6r/pppqkppp/2bp1s2/8/8/8/8/8 AddWhitePieces
P1189482 by François Gouze in 2010 is a PG 10.5 with the condition "Add one piece" which can be solved with option Add white X (available since v0.4.8). (To prove C+ one also has to solve with Add black X.) It would be entered as
stip PG 10.5 forsyth 1s1q1b1r/p1pppp1p/6ps/8/3k3P/3PR1P1/PPP1PP2/RS1QK1S1 Add white X
Chaining multiple stipulations together
P0001674 by Vasile I. Tacu in 1991 is a PG 6.0 with undefined pieces, followed by a mate in 1. In Jacobi, the piece X is a white undefined piece, which is why we need to add the PG option ColorThePieces. The problem would be entered as
stipulation PG 6.0 forsyth XXXXXXXX/XXXXX1XX/8/5X2/8/8/XXXXXXXX/XXXXXX1X ColorThePieces
P1338763 by myself in 2017 is a PG 5.0 with the option AddPieces, followed by immediate checkmate. It would be entered as
stipulation PG 5.0 pieces white Kf1 Sb6 AddPieces
P0574859 by Franz Pachl and Markus Manhart in 1993 is a h##3.5. A double-mate requires putting oneself in check which is illegal in orthodox Chess, so in Jacobi this problem requires the fairy condition AllowTerminalAutoChecks (automatically added if you forget). This particular double-mate problem is of the variety that requires the previous move to be checkmate. Starting the problem with h#3.0 would start with the wrong player and mess with the move numbers. A clever way to enter it is
P1067987 by Mark Kirtley in 2004 is a synthetic game problem which requires the move "5... e1=S" in the middle of the game. It's a bit crazy, but it can be entered as
play help 4.5
test dia pieces black Pe2 AddPieces
test not dia pieces black Se1 AddPieces
play help 0.5
test not dia pieces black Pe2 AddPieces
test dia pieces black Se1 AddPieces
P1292590 part (b) by Raffi Ruppin in 1964 is a ser-r#4. It would be entered as
This is shorthand for the following code, where the reflex condition has been pulled out:
set test # reflex
The set test # command creates a persistent checkmate test for every subsequent move. The command must be followed by an option such as reflex to have any effect on the game.
P1318357 by Peter Rösler in 1992 is a h#6 with the condition
Semireflex-check. It would be entered as
pieces white Ka8 Pc2 black Kc8 Pd2g2h2
set test + black reflex
JF-1257 by Nicolas Dupont in 2017 is a PG 17 with the condition
Black reflex #. It would be entered as
set test # black reflex
stipulation PG 17 forsyth rbq4r/pK1pp1sp/2s3bp/2p2pk1/8/5P2/PP1PP1PR/RSBQ1BS1
Jacobi will accept a defensive move if the situation being defended against can be directly tested. So a s#1 is fine because Black is defending against checkmate, but a s#2 is not, because the first black move is defending against a s#1, which is not an instant verification.
This means that Jacobi can handle stipulations where the only defensive move is at the very end of the problem, but it can also handle some other cases too. The stipulation hsx5 followed by the stipulation hs#2 works, but it requires elaboration. Black's 5th move is defensive in the sense that Black will avoid capturing if he can, but Black's choice among possible capturing moves will be helpful.
PG demolition mode
The solver option "PG demolition mode" searches the most likely moves first and then progressively tries less likely moves in multiple passes. It should find a cook faster if there is one. On the other hand, if the problem is sound then it will take much longer to prove it, so you should not use the option if you expect the problem to be sound. Many people ask me how many passes it makes but there's no easy way to answer that. It is best to imagine that this mode takes infinite time, so you stop it when your patience runs out.
The option is for proof games only. If the problem doesn't have a proof game component ("dia" or equivalent), then there will be just one pass which will be identical to a search with the option off. If the solver is doing more than one pass then the option is working. The option is famous for having been able to cook JF-1146 in less than 1 hour.
stipulation dia16.5 forsyth r1Bs1rs1/ppP1k2p/7b/8/p7/3K1S1r/1P5P/3S2R1
The solver runs quickly in recent versions of Firefox and Chrome. One exception is Internet Explorer which is from 3x to 20x slower than the competition, even with IE 11. Its successor, Edge, is supposed to be faster.
As a way to test your performance, the first example (listing solutions to Fool's mate) should take about 0.2s on a reasonable machine.
If you get poor performance, you could consider installing a second browser (different from your favorite one) that you'd use only for running Jacobi.
Jacobi uses a transposition table with hash keys of 86 bits, which gives a theoretically very tiny chance of missing a solution. Jacobi may also contain bugs, which is a more likely source of incorrect results. If you believe that Jacobi returned a wrong result for a problem, then please tell me by e-mail.
Keep in mind that fairy conditions are not always perfectly defined, especially in the way they interact when a problem uses more than one. My goal is to copy the behavior of the latest version of Popeye so that a problem that is C+ in Popeye will be C+ in Jacobi, and vice-versa. If you find a difference in behavior which is not a bug in Popeye, then tell me and I'll try to match what Popeye does.
Currently, Jacobi only searches for solutions of the exact specified length, as if each stipulation had the "exact-" prefix in Popeye. Solvers are divided on this issue, with Popeye and WinChloe reporting shorter solutions, but not Natch and Euclide. I plan to add a way to automatically search for shorter solutions, and maybe make it the default.
Jacobi does a lot of internal consistency checks and it prefers to crash rather than give you wrong results. If Jacobi crashes and you don't think it should have, then please e-mail me the problem you were trying to solve and approximately how long it took before the crash, so I can try to reproduce it.
One known way to crash Jacobi is with a Checkless Chess loop, like this one adapted from Popeye's BEISPIEL/exklohne.inp
auto Gerd Rinder
quel Seite 9, Die Schwalbe, X/1969
weis kd7 td8h8 la1h1
schw ke5 nc3f3
Just bookmark the latest version page so you can get to it directly. This page contains an AppCache manifest which tells your browser to store every file needed by Jacobi on your computer/device so that the page still "loads" when offline in that particular browser. Some browsers even offer the option "Add to homescreen", which will turn Jacobi into a Web App that you can launch by clicking on an icon (as long as the browser remains installed and its application cache is not cleared).
Zip archives of Jacobi are available.
Here are the features I'm planning to add soon, so don't bother suggesting them! Jacobi will reach v1.0 when they are all implemented.
- Add a graphical editor for diagrams.
- Add an editor for stipulations with dropdown menus to select from available stipulations and aims.
- Add a graphical viewer for solutions.
Add a few more aims (%, 00, ep).
- Add a few more fairy conditions (
Chess960, FollowMyLeader, Duelist, Chameleon).
Warn of self-check in the initial position instead of crashing.
Teach the PG solver that doubled pawns imply a capture nearby when the fairy conditions are close to orthodox.
- Teach the PG solver that the path traversed by a pawn appearing in the goal diagram can't be vertically crossed in some cases when fairy conditions are close to orthodox.
- Rewrite the PG-demolition-mode code, hopefully making it faster.
Add a WebAssembly version of the chess engine for a speed increase of maybe 50% in modern browsers, with fallback to asm.js for the rest.
- Document the "elementary commands".
Jacobi is freeware, which means that you are free to use it and make a copy for personal use, but not to redistribute copies as I retain the Copyright on it.
Here I keep links to old versions. Useful to you if I break something with an update.
- Changed the application order of Masand, OscillatingKings, #R Chess, #C Chess, and Kk Chess.
- Fixed a crash with #C Chess and Bicapture.
- Fixed a crash with Kk Chess and Circe variants where a rebirth can promote.
- Added the PG option "Add" to add specific pieces. See the example in the "Special proof games" section above.
- Fixed a crash with Knightmate.
- Added the condition #R Chess.
- Added the condition #C Chess.
- Added the condition Kk Chess. These were introduced in feenschach 212 (2015). Definitions are also given in Quartz 44 (2017).
- Added the condition WhiteOscillatingKings.
- Added the condition BlackOscillatingKings.
- Added the condition SwappingKings (implemented as WhiteOscillatingKings TypeC + BlackOscillatingKings TypeC).
- Accidentally improved the speed of Circe RexInclusive.
- Fixed a bug introduced in v0.4.4 causing some rare crashes when solving PGs.
- Fixed a crash with Chess960 + RoyalDynasty.
- Added the condition BlackCap (implemented as BlackMustCapture SemiUltra + BlackPassesIfStuck).
- Added the condition BlackChecks (implemented as BlackMustCheck SemiUltra + BlackPassesIfStuck). The text box also accepts the alternative name "Checking".
- Added the condition Zigzag (implemented as WhiteMustCapture Anti SemiUltra + WhiteMustCheck Anti SemiUltra) and the variants ZigzagStapff and ZigzagUltra.
- Fixed a crash with PromOnly P and Circe variants where a rebirth can promote.
- Fixed a crash with AdversePromotions + Tibet.
- Fixed a crash with RoyalDynasty + KobulKings.
- Changed the behavior of PromOnly + ChameleonChess to correspond to Popeye.
- Fixed a display bug introduced in v0.4.4 that produced strange notation for RelegationChess and ChameleonChess.
- Improved the solving speed of PGs by about 10%.
- Improved the solving speed of some series PGs.
- Fixed degraded performance for PGs with two rooks of the same color ending on files d and f.
- Fixed e.p. notation in output language "French-çé".
- Removed the warning "Keep this window visible when solving...", except for Safari. For other browsers it seems this is not an issue since v0.2.
- Improved the solving speed of some PGs with doubled pawns some more. Invisible promotions (Phoenix, Prenix and Ceriani-Frolkin) can now sometimes be deduced.
- Fixed a crash with Madrasi.
- Fixed a crash when solving Chess960 + VerticalCylinder PGs.
- Fixed a crash when solving Circe Parrain PGs in demolition mode.
- Fixed a bug causing a check by a pawn to be counted as a multiple check when the pawn would otherwise promote, in some fairy conditions.
- Fixed a bug introduced in v0.2.3 causing the stipulations s#1 and r#1 to no longer work.
- Added the condition RoyalDynasty.
- Added the condition PromOnly.
- Added the condition AdversePromotions.
- Fixed two bugs introduced in v0.4.2 that caused some crashes when solving PGs, and potentially caused missing solutions with LosingChess and Extinction.
- Fixed a bug that prevented the "test" command from applying to the initial position. This is useful for adding constraints to the initial position in Chess960.
- Replaced the "Flood protection" checkbox with a menu with a new option "Count only" which is more efficient for path enumeration problems with more than 1000 solutions.
- Improved the solving speed of some PGs with doubled pawns. For example, P1273714 improved 100000x.
- Allow PGs with more than 32 pieces on the diagram. This can happen when promoting pawns in Sentinels.
- Fixed a bug affecting ChameleonChess PGs.
- Fixed a performance bug affecting PGs with Berolina pawns.
- Fixed a crash when solving Chigorin + Einstein Reversal + AntiAndernach PGs.
- Fixed a crash in v0.4.1 when attempting to solve a PG with two kings and the option ColorThePieces.
- Renamed MoveAnyPiece to FreeForAll (Jed Stone, 1982).
- Fixed a crash when solving Circe Parrain Assassin PGs.
- Fixed a crash when solving AntiAndernach + NonRoyalKings PGs.
- Fixed a bug in EiffelChess (there was paralysis of fairy pieces).
- Fixed a bug in Woozles + White/BlackEdgemover.
- Fixed bugs in Masand when combined with Disparate, Circe Rexinclusive, NewKoeko, or Isardam.
- Changed the behavior of Sentinels + BackHome and Sentinels + Circe Diagram to correspond to Popeye and WinChloe. Sentinels no longer have an origin square.
- Improved the solving speed of Isardam by 3-12x for non-PGs, and 12x for PGs.
- Added the fairy piece Berolina pawn.
- Moved the condition Circe ContraParrain to the bottom section as Circe Parrain Mirror, following Popeye.
- Added the condition ChigorinChess (special starting position and promotions).
- Added the condition AlmostChess (special starting position and promotions).
- Added the condition Knightmate (special starting position and promotions).
- Added the condition BerolinaChess (special starting position).
- Added the condition ImmunChess.
- Added the option Sentinels Berolina.
- Added the aims ++, +++, ... , ++++++++. The number of checks is now displayed in the solution, unless also mate.
- Made the PG solver a bit smarter and optimized the code. PG solving speed has improved by 2% to 60% depending on the problem, and a lot more for PWC and Sentinels.
- Fixed a crash with Bicapture + Multicapture.
- Fixed a crash with Masand.
- Fixed a crash with VerticalCylinder + Maximummer. Distance now takes into account the board topology.
- Fixed a crash with VerticalCylinder + BlackMustCapture Ultra.
- Fixed a crash when solving Tibet PGs.
- Fixed a crash when solving ChameleonChess PGs.
- Fixed a crash when solving KobulKings + Einstein PGs.
- Fixed a crash when solving FaceToFace + BackToBack PGs.
- Fixed a crash when solving Circe Turncoats + Masand PGs.
- Fixed a crash when solving Circe Turncoats RexInclusive PGs.
- Fixed a crash when solving AntiAndernach + NonRoyalKings PGs.
- Fixed a crash when solving Bicapture + Circe Couscous PGs.
- Fixed a crash with Tibet. The condition was unusable.
- Fixed a crash when chaining more than 5 PG stipulations.
- Moved the condition Bichromatic to the bottom section as "Monochromatic Anti", for technical reasons.
- Added the condition GenevaChess.
- Added the condition NormalPawn (which can be added to Annan, PWC and others to let a pawn on its first rank move).
- Added the condition Circe Strict.
- Added the condition Circe Assassin.
- Added the aims %, 00, and ep.
- Fixed a bug introduced in v0.3 causing demolition mode to crash with almost every condition.
- Fixed a crash with Circe Turncoats RexInclusive.
- Fixed a bug causing NoImmediateRepetition to wrongly accept some repetitions mid-game when solving PGs.
- Improved the solving speed of Vogtlaender by 6x (for non-PGs).
- Added extra checkboxes for conditions like LosingChess, to aid discoverability.
- Made the Text representation box understand condition names written in French or German.
- Fixed the figurine color when displaying AllInChess solutions.
- Added the condition MulticaptureChess.
- Added the condition UnicaptureChess (implemented as Multicapture Anti).
- Added the condition Tibet.
- Added the condition DoubleTibet.
- Added the condition Koeko.
- Added the condition AntiKoeko.
- Added the condition NewKoeko.
- Got for free the condition AntiNewKoeko.
- Added the condition ContactGridChess (implemented as Grid + Koeko AffectedByGrid AppliesToRebirth).
- Reordered the conditions to better reflect the order in which they are applied. For example (following Popeye), Monochromatic affects Madrasi paralysis and Madrasi paralysis affects the definition of observation of Patrol, so these three conditions are listed in the order Monochromatic, Madrasi, Patrol.
- Changed the behavior of Madrasi to correspond to Popeye: test for royal units instead of the king piece.
- Changed the behavior of Circe Clone to correspond to Popeye: test for royal units instead of the king piece (change detectable by adding KobulKings or LosingChess).
- Fixed a bug in Monochromatic + Madrasi causing some missing en-passant paralysis.
- Fixed some missing king moves in Monochromatic + FaceToFace.
- Correctly apply Monochromatic and Bichromatic to castling rook in Chess960.
- Fixed castling distance in Chess960 + Maximummer.
- Improved the solving speed of some Monochromatic and Bichromatic PGs. For example, P0008928 improved 250x.
- Warn if the side to play can capture the king (instead of crashing).
- Fixed a bug causing no solutions in Masand PGs when the goal diagram hides a king as an undefined piece without ColorThePieces.
- Fixed a crash when solving Masand PGs.
- Fixed a crash when solving Tacu enigmas with AntiAndernach.
- Added the condition GridChess.
- Added the condition WhiteEdgemover.
- Added the condition BlackEdgemover.
- Added the condition Woozles.
- Added the condition BiWoozles.
- Added the condition AllInChess (implemented as
MoveAnyPieceFreeForAll + NoImmediateRepetition).
- Added the condition Bicapture.
- Added the condition Cannibal.
- Added the condition RelegationChess.
- Added the option Madrasi RexInclusive.
- Added the option Isardam RexInclusive.
- Notate the starting file of a vertical pawn move if ambiguous (common in Annan).
- Generalized stipulation closure to any sequence of "h" and "*", with "s" or "r" allowed as the last character. This covers 8 of the 12 series genres listed in an article by Nicolas Dupont in issue 13 of the ChessProblems.ca Bulletin.
- Generalized reflex stipulations, with examples given in the new "Reflex stipulations" section above.
- Fixed a bug affecting Hypervolage PGs.
- Fixed a bug affecting Einstein + VerticalCylinder PGs.
- Fixed a crash with Circe RexInclusive Chameleon + KobulKings.
- Fixed a crash with Extinction.
- Changed the behavior of Circe Chameleon + CavalierMajeur to correspond to Popeye.
- Added the condition ChameleonChess.
- Fixed a crash in v0.2 and v0.2.1 when solving VerticalCylinder PGs. Notate extended castling O-O-O-O.
- Fixed a bug in v0.2.1 with Vogtlaender.
- Added the condition Chess960.
- In reflex series, reject solutions when the idle side can reach the aim during the series. With this change there is a unique solution to the ser-hr#8 by Meinking and Petkov, StrateGems 2011, reproduced on p.44 of Dan Meinking's Chess Problem Collection ("forsyth 1S6/pK1R4/3Bk3/r5P1/6P1/8/1PB5/8 stip ser-hr#7" in Jacobi).
Temporarily hardcoded the version number in the "Launch the latest version" button until I resolve issues Firefox has with the auto-updating version.
Bug fixes only. Most of the crashes were found by myself through automated testing.
- Fixed a crash when solving Circe Chameleon PGs.
- Fixed a crash when a rook able to castle comes from a rebirth promotion, for example the rebirth [+bPa1=wR] in PWC + Volage.
- Fixed a crash when a king is reborn in Circe Clone RexInclusive.
- Fixed a crash when a king is reborn in Circe RexInclusive + Hypervolage.
- Fixed a crash with Circe Parrain + Andernach.
- Fixed a crash with Volage + Einstein.
- Fixed a bug causing a complete lack of solutions when the initial position had a missing king in Circe RexInclusive.
- Fixed a crash in v0.2 when solving Tacu enigmas with Sentinels.
- Fixed a performance regression in v0.2 when solving Tacu enigmas with Circe or Annan.
- Fixed a crash with Circe Parrain + Annan.
- Fixed a bug causing stalemate notation (=) to appear mid-series after a parry move.
- Added the ability to specify the hash table size.
- Dramatically improved the performance when solving PGs with diagrams similar to the homebase position.
- Fixed a bug causing some castling solutions to be missing in PGs with Hypervolage and a few other conditions. See details.
- Update the explored variation on screen less often, and other small performance improvements.
- Fixed Disparate behavior in series. Can now solve JF-996.
Many planned features have been postponed to get something out as fast as possible. For now, the problems can only be input in text representation, apart from conditions which can be set by clicking checkboxes.
Fairy condition definitions
Please use these definition lists. None is truly complete, but combined they cover pretty much everything.
Page created: October 16, 2017
Page last updated: August 4, 2018
back to François Labelle's homepage