I haven’t worked on the JustChess app in about 5 years. However, I was recently made aware that there was a custom ROM, named DivestOS, which suggested my old app as a good open source chess playing app. Unfortunately, when I left off working on this app 5 years ago, it had a few bugs in it, that I never got around to fixing. With a surge of new attention, I thought it best to revisit the app and clean up some of my old mistakes, and smash a few bugs.

One of the biggest bugs had to do with en passant. By the rules of en passant, or “in passing”, a pawn will not allow an opposing pawn to take a double step past them without attacking that fast moving pawn. In JustChess, there was an issue where either the attacking pawn became doubled, meaning there were now extra pawns, or simply sidestepped around the fast moving pawn, but without capturing it. You can read the issue tracker about it here:

https://gitlab.com/alaskalinuxuser/app_JustChess/-/issues/3

Either way, it was not very helpful when trying to play, as the results were not in accordance with the rules of chess, nor was it consistent, making the game difficult to play.

With a bit of renewed vigor, inspired by the surge of new interest, I decided to try to tackle a few of the bugs in the app, starting with this one. You can see the fixed changes here:

https://gitlab.com/alaskalinuxuser/app_JustChess/-/commit/7b04af53c97f7eeaff22efb950ef96e484f358d3?page=2

Most of the fix actually revolved around three problems: bad math, the wrong ‘taken’ piece, and a misuse of the last move.

The bad math was easy to fix. Since I made the board a string of letters, the computer believes that the board is a flat line, rather than a square. Moving pieces then becomes a mathematical function. If you go “up” a row, you add 8, if you go “down and left”, you minus 7, and so forth. The first issue of this bug, as seen in line 692 of TheEngine.java was a simple math error on my part. I had transposed left and right for plus/minus 7 and 9, causing the computer to move the pawn or take the pawn from the wrong place.

The second issue, that of the wrong ‘taken’ piece, is that on lines such as 694 form TheEngine.java, I was asking the computer to reference a ‘taken’ piece, but it was coming up with the wrong answer because of my inexperience at programing. However, in this case, I don’t need to reference any taken piece, as I know what pieces were taken, and which squares will be given the empty character ‘*’, so rather than have a programmatic way of asking the computer for the asterisk. I just put in an asterisk. Much simpler and that problem was resolved.

The final issue was a bit more complicated for someone of my limited knowledge to figure out. I had to add a lot of debugging lines (which I then commented out after the fix was implemented), trying to find what the fail really was. Essentially, it comes down to a variable called ‘lastMove’. This variable was intended to allow the computer to think about the next move by remembering what the last move was. This last move is important for calculating en passant, because you can only en passant if your opponent did a quick step on their turn, moving their pawn two steps forward.

This issue was two fold, however, because the first problem with this variable was that I did not consider other possible moves that the string/character comparison would have to make. Moves like promoting a pawn had different letters than expected, causing a strange outcome when parsed without logic. So, by my own programming error, it would return bogus information which would mess up my follow up instructions trying to parse the information. This was quickly fixed with some more logic to further check the move before parsing it. The code was simple and went like this:

if (lastMove.charAt(1) == 'E' || lastMove.charAt(1) == 'u' || lastMove.charAt(1) == 'l' || lastMove.charAt(1) == 'r') {
                    // Do nothing.
                } else { //Check for en passant.

This line of code simply prevents the lastMove variable from being parsed for en passant if there are characters in the move that correspond to pawn promotion or other non en passant moves.

The second half of this issue was that the last move was only recorded for that particular move, and then the computer would overwrite last move while it calculated the next move. This problem caused it to forget that the last actual move was a double stepped pawn, and thus would deny you the ability to perform en passant. Essentially I fixed this with a new variable called playedLastMove, which was only incremented when a move was played, allowing the engine to continue calculating with it’s various lastMove variable.

Essentially, it all boiled down to some pretty petty and grievous mistakes on my part, but, to God be the Glory, it is now all fixed! You can download version 2.1 from gitlab directly, or wait for it to hopefully come out on F-Droid.

Linux – keep it simple.

Leave a Reply

Your email address will not be published. Required fields are marked *