💾 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

View Raw

More Information

-=-=-=-=-=-=-

JustChess 2.3 – Fixing a castle.

">

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.