Chess

This was a very exciting project for me. I only started learning how to program two weeks earlier. I didn't get caught in tutorial hell or in memorizing syntax. I had a very basic knowledge of programming tools like arrays, objects and conditionals and dove right in! This is where I forged a strong foundation for thinking like a programmer. I spent a lot of time being creative and thinking of different ways I could combine the small number of tools that I had at my disposal.

The first thing I had to figure out was how to create the board. I found out I could use HTML tables and CSS. Today, I would use css grid, dynamically create the DOM nodes within Javascript, and then attach them to a single HTML defined node. This way I could easily implement my chess game anywhere and I wouldn't have to deal with too much HTML.

I created an object for each square and gave it keys like "pieceType" and "pieceColor". I also gave each square a key with coordinates. Today the first thing I would do is put those objects into a 2d array. This would do away with adding the coordinates as keys into the objects themselves. Also I wouldn't have to use a find method to get the object I need. Instead, I could say for instance square[0][4].

Then I created a function that loops through each square and changes the innerHTML to an image of the current piece and piece colour that a square contains. Now I had a board that had all the pieces on it, but it didn't really do anything yet.

In order to find possible moves for a piece, I used a recursive function to traverse the squares by their coordinates. The base case was encountering a square with the same color piece, or a different color piece, or if the coordinates returned null. As the recursive function traversed my objects, it would mark squares as "possible" or "encounter", which were keys on my square objects. Today I would use iteration instead of recursion to determine movement possibilities. Simply because there are more ways to go wrong using recursion over iteration, and it wouldn't have been much harder to read using iteration. The better time complexity is nice too.

I then had to determine who could move and when. I created different states the game could be in and used those states to constrain what clicking on a piece would do in different situations and I created a simple turn system. Now I was able to move pieces during their respective turn and trade with other pieces.

The next big challenge for me was the chess rule En Passant. This ended up being fairly straightforward once I wrapped my head around it. It was as simple enough as setting the conditions for the move and then translating the move sequence into Javascript. I did the same for castling Castling

Then I had to figure out how to stop a move if it would result in putting yourself into check (In chess, you can not put yourself into check). Before I could do that, I had to build some other functionality into my program. I had already had the idea when thinking about checkmate, that I needed a second board to play through possible moves. Adding a new board was as simple as adding "alternativePieceType" and "alternativePieceColor" keys to my square objects and copying the main board to the alternative. Now I could run through possibilities without changing the actual board state. I also created another board that was always one move in the past so I could get the past board state when I neeed it. Today I would use something called a FEN number to keep track of past board states. A FEN number is a string that can be interpolated into a board state. With the FEN number, I wouldn't need the alternative boards. I could do any calculations on one board and simply retrieve my real board state from my FEN number. This would simplify my code and make my project overall easier to understand.

I also needed a way to mark if a square could be attacked by any given piece, so I added a key "count" to the squares objects and assigned it 0. I then ran the movement possibilities of every piece and added +1 to the "count" of any square which was under vision of a piece. This way, I didn't just know a square was under attack, I knew exactly how many pieces were attacking it. Now that I had a way to determine if a king was in check, and a way to restore past board states, I could simply see if a player moving a piece put themself in check, and if so, simply go back in time one move.

Now it was time for checkmate. A king was in checkmate if a square it was on, and all the squares that were one square away, had a "count" greater than 0 and the piece that was delivering a check could not be taken or blocked by another piece. This required me to make all possible moves, and check if it was still mate after each move. If any move resulted in the king not being in check, searching for a checkmate immediately ceased. If we checked all moves and the king was still in check, the game was over.

I am quite pleased with how this project turned out. Obviously because this was my first project, that quality of some of the code is quite convoluted and could be simplified, but overall I think I did a good job. At the very least, I got it working! :)