💾 Archived View for alaskalinuxuser.ddns.net › 2023-10-05.gmi captured on 2024-09-29 at 00:21:55. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
">
97w, https://alaskalinuxuser3.ddns.net/wp-content/uploads/2023/10/
Screenshot_2023-10-04_09-01-19-161x300.png 161w" sizes="(max-width: 297px)
100vw, 297px" />
Well, rather fixing castling, I suppose. There were quite a few problems with
castling in my JustChess engine. In fact, it was so bad, I probably should have
removed the function altogether until I fixed it. However, to God be the glory,
it is fixed now. You can download the latest and greatest version on F-Droid
(hopefully soon) or here directly:
https://gitlab.com/alaskalinuxuser/app_JustChess/-/tree/master/
app?ref_type=heads
Castling caused three main problems in the original code that I wrote.
1. \n
2. Castling would often replace a rook with an opponent’s king.
3.
4. Castling would magically move your king somewhere else, but make him
invisible.
5.
6. Castling could happen even if the king moved, or allow the king to be
captured by the enemy.
7. \n
That’s actually a big problem! Most of these were discussed in these two issues
on the issue tracker:
https://gitlab.com/alaskalinuxuser/app_JustChess/-/issues/12
https://gitlab.com/alaskalinuxuser/app_JustChess/-/issues/13
The first issue, replacing a rook with your opponents king was actually the
hardest to figure out. I started by adding debugging lines into each function
to see when the board replaced the rook with the king, and then had to play
through numerous games. It was tedious and time consuming. What I found was
that the problem was not in the kingmoves/bkingmoves function, nor in the
allmoves function, nor in the engine at all.
Actually, the problem was in the main activity, where after making a move, I
wanted to ask the engine to list all available moves to see if there was a
checkmate or stalemate condition. For this I should have called the terminal
command of:
moveOptions= terminal("availMoves,black");
But instead I called:
moveOptions= terminal("suggestMove,black");
The suggest move option is a rated move suggestion, singular, based on ply and
various evaluation criteria. The available moves option is a simple request of
all currently available moves for that color. Thus, rather than getting a list
of moves to check for stalemate or checkmate, it was getting a string about a
specific suggested move. Ultimately, this should still have worked, except the
last move function would get confused (due to my poor programming skills) about
which move was really the last move, leading to a pretty bad return which
resulted in switching the rook at A1 (the first square of the board, on the
left bottom, numbered 00 in the engine) with a king piece of the color of the
last person to castle!
While it took me forever to figure this out, the fix took about 30 seconds. I
just changed the command from suggestMove to availMoves.
The second issue, moving the king and making him invisible, well, let’s just
say I was not doing a great job at checking the king’s safety. And I’m not sure
it put him back where he was supposed to be. Essentially, king safety during
castling was always returning true, till it wasn’t. So you could capture him,
or he might disappear, or some other unexpected error. It’s a lot of code that
you can check out in this commit:
https://gitlab.com/alaskalinuxuser/app_JustChess/-/commit/
f85839de525297712c10941b0e98ea538344fafe
And finally, the third issue was that the king or rooks could move and then
still castle, as long as they were back at their original square. This was
really some sloppy work on my part. I put in code to check if the kings or
rooks moved, but didn’t call it into question before castling. So the engine
knew that they moved, but didn’t realize that was a criteria for castling. So I
added some statements like this:
if (wKingNeverMove == 0) {\n\n// and\n\nif (theBoard[7] == 'R' && theBoard[5]
== '*' && theBoard[6] == '*' && wKRNeverMove == 0)\n\n// and\n\nif (theBoard[0]
== 'R' && theBoard[1] == '*' &&\n theBoard[2] == '*' &&
theBoard[3] == '*' && wQRNeverMove == 0)\n
And so on for the black pieces as well. All the variable were there and in
place, but the castling rules were not checking them before allowing/suggesting
the move. Fortunately it now does check this, and the game play is much
smoother.
Linux – keep it simple.