Porting syzgy/tb to an old version chess (shatranj)

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

ayunus
Posts: 5
Joined: Tue Sep 10, 2024 8:33 am
Full name: Yunus Emre Ayhan

Porting syzgy/tb to an old version chess (shatranj)

Post by ayunus »

Hi I am here to find a way to reuse tb code of SF.
Trying to port tb code to shatranj but it was hard for me to fully cover details of tb code.

made a fork and a few position updates regarding shatranj (https://en.wikipedia.org/wiki/Shatranj) type move generation
https://github.com/syzygy1/tb/commit/02 ... 780bbc5cf5

What I also need is game endings, in shatranj when opponents do not have any piece we win.
Also when we capture last piece of opponent, if opponent could also capture our last piece, then draw.

Need guidiance for fully implementing last two sentence (at least for tbgen.c), have seen tb author is a kind of active still, maybe @syzgy could guide to me? From architectural point of view, how to approach for example?
User avatar
hgm
Posts: 28010
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by hgm »

Six years ago I generated 4- and 5-men EGT for Shatranj. See https://kirill-kryukov.com/chess/discus ... 15a517963c . This describes what I had to change in the generator to implement that bare-king rule.
ayunus
Posts: 5
Joined: Tue Sep 10, 2024 8:33 am
Full name: Yunus Emre Ayhan

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by ayunus »

I see thanks for your answer. No code from your attemp left as far as I understand.

Reading mentioned forum link, also I need to make a tablebase where stealmate is a loss for fully adapted shatranj variant of course, I missed that part in my above comment.

I have ported some portion of stockfish to shatranj so having syzygy/tb adapted would be simpler at first glance.
But reading syzygy code progressing really slow. Maybe I will attempt writing something simple from scratch.
User avatar
hgm
Posts: 28010
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by hgm »

Even if there was code left, it would probably be of no use to you. (I could probably easily reconstruct the code, as it was only a small modification of the FairyGen code, which is still available.) Because the generated tables were not in syzygy format, and Stockfish would not know what to do with them. The tables were not even compressed, as I never intended to use them in an engine. I was just interested in the statistics of the end-games, to see which piece combinations could beat which other combinations in Shatranj.

If you want to have EGTs that Stockfish could understand, your best bet is to modify the code of the syzygy generator. I have never looked at that generator. But the way I did it started with identifying the positions that could be won by immediate King capture. (That is, where black was in check and white on move.) Then all those were tested for having black moves to a position where black was not in check, and if none were found, the position was a checkmate, lost with black to move.

If stalemate is also a win, you would have to apply that not only to the in check positions, but test all positions for having black moves to a not-in-check position. That takes a bit longer, as in most positions you are usually not in check. (Depends on how many and how powerful pieces white has.) But it is not essentially different; you just cannot skip positions where black is not in check when performing the test for legal evasions.

After that, if the end-game had a successor, positions that could be won by immediate conversion (i.e. capture) to a won position in that earlier-calculated successor can be added as won with white to move as well. And from that point on it is just iterating retrogradely.

I suppose that the syzygy generator produces one EGT at the time, one for each material combination, and that you first have to calculate all successor EGT to know the result of conversions from the one that you want to generate next. Then the effect of the baring rule can be implemented just by altering the calculation of the EGT with a bare King. All positions with the player that is not bare on move would be won there, and only the positions with black to move where he can capture the King or can legally capture white's last non-royal piece would be draw. The latter can occur only in 3-men tables, where the non-royal piece is adjacent to the bare King, and not to its own.So you would just need a program to calculate these EGT, and then you can run the syzygy generator to work starting from those.
syzygy
Posts: 5646
Joined: Tue Feb 28, 2012 11:56 pm

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by syzygy »

ayunus wrote: Sun Sep 15, 2024 3:30 pm Hi I am here to find a way to reuse tb code of SF.
Trying to port tb code to shatranj but it was hard for me to fully cover details of tb code.
I am not familiar with Shatranj, but based on what I see on Wikipedia it should be possible.

Most importantly, it is played on an 8x8 board.
Pieces apparently move and capture as in chess, just with slightly different sets of target squares.
The initial calculation of win/loss-in-0 positions should not pose too many problems.
made a fork and a few position updates regarding shatranj (https://en.wikipedia.org/wiki/Shatranj) type move generation
https://github.com/syzygy1/tb/commit/02 ... 780bbc5cf5
I'm not sure what kind of fork you made, but it might be helpful to create a fork in your own github account?
What I also need is game endings, in shatranj when opponents do not have any piece we win.
Also when we capture last piece of opponent, if opponent could also capture our last piece, then draw.
The tables you generate will themselves not have positions where one side has no pieces (obviously). But they will have positions from where such lost or drawn positions are reachable.

What you need to do is to loop through the pieces that can be captured.
Then for each piece, you loop through all the resulting "no pieces" positions after it was captured. Then you "undo" the capture in all possible ways, which results in the positions in the table that you are generating which have a win-in-1 (namely the capture that you "undid").

The complication is that some of those "no pieces" positions are not lost but drawn because the lone king can capture the last piece (so this only happens if you start with 4 pieces (including kings)). When you undo captures into these positions, you land in table positions that have a forced draw (by capturing). You have to mark those positions are "draw-by-capture" (CAPT_DRAW in rtbgen.c).

If a position is both "win-in-1" and "draw-by-capture", then "win-in-1" of course takes precedence. (The "draw-by-capture" positions can later still turn out to be e.g. win-in-30.)

At first sight it looks like you can reuse the position "states" defined in rtbgen.c and most of that code.

If you want multithreading to work correctly, you have to use the correct atomic operation here. So if two threads simultaneously try to write win-in-1 and draw-by-capture, then it will be win-in-1. (I guess either of SET_CAPT_VALUE() and SET_WIN_VALUE() in rtbgen.c should do, They seem identical. I'm not sure why there are not the same macro.)
Need guidiance for fully implementing last two sentence (at least for tbgen.c), have seen tb author is a kind of active still, maybe @syzgy could guide to me? From architectural point of view, how to approach for example?
After writing the above, I think it should be quite easy... at least if you can somewhat manage to decipher the code.
And pawns also seem strictly simpler.
syzygy
Posts: 5646
Joined: Tue Feb 28, 2012 11:56 pm

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by syzygy »

First you have to decide what letter to use for shatranj.

r = regular
s = suicide/losing
a = atomic
? = shatranj
edit: it seems I reseved "l" for (ICC-rules) losing chess but never implemented it (or never merged it, I'm not sure).

Perhaps j? You choose.

Then you copy rtbgen.c and rtbgenp.c to, say, jtbgen.c and jtbgenp.c, and you do some copy and paste in the Makefile.
rtbver.c and rtbverp.c can be useful to verify your tables, but you can do that later.

Piece movement is in board.h. You will have to modify that for your version of chess (#ifdef SHATRANJ etc.)
It seems easiest to keep the same piece names. The mapping seems obvious.
Last edited by syzygy on Wed Sep 18, 2024 12:09 am, edited 1 time in total.
syzygy
Posts: 5646
Joined: Tue Feb 28, 2012 11:56 pm

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by syzygy »

What is also helpful is that kings move the same, and - if I understand correctly - can never be in adjacent positions. This means the same indexing scheme as for REGULAR can be used (with KK in 462 positions).
syzygy
Posts: 5646
Joined: Tue Feb 28, 2012 11:56 pm

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by syzygy »

syzygy wrote: Tue Sep 17, 2024 11:51 pmWhat you need to do is to loop through the pieces that can be captured.
Then for each piece, you loop through all the resulting "no pieces" positions after it was captured. Then you "undo" the capture in all possible ways, which results in the positions in the table that you are generating which have a win-in-1 (namely the capture that you "undid").

The complication is that some of those "no pieces" positions are not lost but drawn because the lone king can capture the last piece (so this only happens if you start with 4 pieces (including kings)). When you undo captures into these positions, you land in table positions that have a forced draw (by capturing). You have to mark those positions are "draw-by-capture" (CAPT_DRAW in rtbgen.c).
This should be done in calc_captures_w() and calc_captures_b(). These functions already loop through the opponent's pieces and generate the "uncaptures". If the captured piece is the opponent's last piece, the function should not call probe_captures_w/b() but something like probe_last_capture_w/b(), similar to what is done in stbgen.c.

The probing code in probe.c also needs work.

I will probably give it a try myself.
User avatar
hgm
Posts: 28010
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by hgm »

syzygy wrote: Tue Sep 17, 2024 11:51 pm
What I also need is game endings, in shatranj when opponents do not have any piece we win.
Also when we capture last piece of opponent, if opponent could also capture our last piece, then draw.
The tables you generate will themselves not have positions where one side has no pieces (obviously). But they will have positions from where such lost or drawn positions are reachable.
Note that 'does not have any pieces' here should be read as 'has only a king'. I suppose such positions do occur in some of the generated tables.
ayunus
Posts: 5
Joined: Tue Sep 10, 2024 8:33 am
Full name: Yunus Emre Ayhan

Re: Porting syzgy/tb to an old version chess (shatranj)

Post by ayunus »

syzygy wrote: Tue Sep 17, 2024 11:51 pm After writing the above, I think it should be quite easy... at least if you can somewhat manage to decipher the code.
And pawns also seem strictly simpler.
While It is a nice challenge to understand tb code, it takes time of course.
syzygy wrote: Wed Sep 18, 2024 2:03 am I will probably give it a try myself.
So that would be awesome, because even understanding your suggestions would take a while for me :), having another option inside tb repo for shatranj would be really usefull (jtbgen.c).

My progress on understanding code is like this so far:
  • Checkmate in tbgen is controlling if anything not illegal exist, so how is illegal is marked.
  • Still was not fully understood how illegal marking working but we use king king notation during visitation, illegal marking use some different nottion with work_priv1
  • While it is ignoring adjacent kings, and mirrors, it still produce combinations from all white pieces like they are kings, and marked them as illegal.
  • Maybe each position intended to be marked as illegal durring calc_illegal_bw calls, did not read rest of the code yet.
I really find King King (462) approach complicated even with explanations in here https://www.talkchess.com/forum/viewtopic.php?t=59947 if any paper exist in this topic, I would appriciate, since topic is fun.

Maybe you can verify my understanding about it also but please ignore if it will be hard to explain. We consider white king inside a triangle, and all other possibilities are ignored where white king could be placed because it is considered we have already covered its scenario with our triangle, via mirroring it into that triangle. Mirror table is used for deciding if position of kings is one of these ignored mirrors. Than question comes to my mind is like (sorry if stupid ignore me) what about other pieces, are them still covered for scenarios where white king outside of the triangle?

If mentioned changes could be done without knowing all above details, that would still need expertise of codebase IMHO.

On the other hand it sounds wise to not delving into seperate tables for 3 pieces.
Not sure but having 3 piece tables seperately, could be hypothetically helpfull for keeping same interface with regular contrarily?