lichess.org
Donate

I'm trying to create my own Python endgame engine. Please do not recommend to me StockFish.

I've created a code for endgame like this:

pastebin.com/ULvpsP5Q

**But I'm getting this error**

Mate found in 3 move(s), time taken: 0.00 seconds.
Initial board state:
. . . . . . k .
. . . . . . . .
. . . . . K . .
. . Q . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .

---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[19], line 55
52 print("No mate found.")
54 if __name__ == "__main__":
---> 55 main()

Cell In[19], line 50, in main()
48 board.reset()
49 board.set_fen(initial_fen) # Reset the board to initial state
---> 50 print_move_sequence(board, mate_sequence)
51 else:
52 print("No mate found.")

Cell In[19], line 32, in print_move_sequence(board, move_sequence)
30 if board.is_legal(move):
31 board.push(move)
---> 32 print(f"Move {board.san(move)}:")
33 print(board, "\n")
34 else:

File ~\myenvGPU32\Lib\site-packages\chess\__init__.py:2866, in Board.san(self, move)
2861 def san(self, move: Move) -> str:
2862 """
2863 Gets the standard algebraic notation of the given move in the context
2864 of the current position.
2865 """
-> 2866 return self._algebraic(move)

File ~\myenvGPU32\Lib\site-packages\chess\__init__.py:2879, in Board._algebraic(self, move, long)
2878 def _algebraic(self, move: Move, *, long: bool = False) -> str:
-> 2879 san = self._algebraic_and_push(move, long=long)
2880 self.pop()
2881 return san

File ~\myenvGPU32\Lib\site-packages\chess\__init__.py:2884, in Board._algebraic_and_push(self, move, long)
2883 def _algebraic_and_push(self, move: Move, *, long: bool = False) -> str:
-> 2884 san = self._algebraic_without_suffix(move, long=long)
2886 # Look ahead for check or checkmate.
2887 self.push(move)

File ~\myenvGPU32\Lib\site-packages\chess\__init__.py:2920, in Board._algebraic_without_suffix(self, move, long)
2917 return "O-O"
2919 piece_type = self.piece_type_at(move.from_square)
-> 2920 assert piece_type, f"san() and lan() expect move to be legal or null, but got {move} in {self.fen()}"
2921 capture = self.is_capture(move)
2923 if piece_type == PAWN:

AssertionError: san() and lan() expect move to be legal or null, but got f6g6 in 6k1/8/6K1/2Q5/8/8/8/8 b - - 1 1

**Where is the problem** ?
In the print statement
print(f"Move {board.san(move)}:"),
board.san(move) is the SAN representation of the move in move, but only if move is valid. However, on the line before you've already executed that move with
board.push(move),
so in the new state of the board, that move is not valid anymore. A hint to this is in the error message, where it says
AssertionError: san() and lan() expect move to be legal or null, but got f6g6 in 6k1/8/6K1/2Q5/8/8/8/8 b - - 1 1.
f6g6 is the first move of the mating sequence, but black has the move in the position of the error message.
Somebody already did but I forgot the name of author/programmer. There is Endgame Turbo. Set-up, copy-paste any endgame position and knows the best move in an instant.
I recommend looking at the Syzygy endgame tablebases, all endgame positions up to 7 or 8 pieces have been computed already via retrograde analysis. Attempting to make a solver that doesn't use these tablebases isn't really worth it due to the branching factor.
@PawncompleX said in #4:
> I recommend looking at the Syzygy endgame tablebases, all endgame positions up to 7 or 8 pieces have been computed already via retrograde analysis. Attempting to make a solver that doesn't use these tablebases isn't really worth it due to the branching factor.

That's very true. It's sort of like how ray tracers only simulate the photons that matter, not the ones that aren't captured by the camera. The photons come from the camera, not the other way around like in real life. Similar to how EGTBs are solved backwards. Kind of. It's a vague analogy.

This topic has been archived and can no longer be replied to.