Projects

ChessChoices

ChessChoices is a puzzle web app I developed entirely by myself to learn a variety of coding languages. I learned a ton doing this project, but I’ll give a quick overview of the main skills I utilized in publishing and maintaining ChessChoices.

What is ChessChoices?

I came up with the idea after playing 25,000+ chess puzzles on Chess.com, Lichess, ChessTempo, and other sites. After so many puzzles, I realized that no matter how complex they get, you ALWAYS know that you’re winning. It felt like I was almost cheating when I figured this out. In fact, I’ve heard many grandmasters talk about cheating in chess (if you know the chess community, you’ll understand why), and many say that at the highest level, all a GM needs to cheat is a vibration at the right time telling them there’s an only-move or that they’re suddenly winning. A simple awareness that they’re in a winning situation is enough for them to spot what they need to spot. When you’re doing traditional puzzles, you always have this awareness. 

So instead of having puzzles where you know for certain that you’re winning, I thought it would be cool to create a puzzle variant where players are tested on what they think of a position. The comparison puzzle, where I show the user two boards, was my initial idea for the project. But after making the first version, I realized I could also add a single board variant.

The site revolves around asking the user to position themselves as Stockfish, currently the best chess engine in the world and what’s used on major chess sites to evaluate a chess position’s strength. For example, if Stockfish evaluates a position as +5, it’s saying white has an advantage equivalent to one rook over black (in chess, pawns are worth 1 point, bishops/knights are 3 points, rooks are 5 points, and queens are 9 points.) This advantage could be because white has more material than black, but white could also be down pieces yet have a sequence of moves so powerful that Stockfish rates the position as advantageous to white because a sequence of moves will win white more material. Essentially, by analyzing tens of millions of moves per second, Stockfish gives us a numerical rating for any position.

What my puzzle asks the user is: given this random position, do you think Stockfish the side playing is winning or losing? Because Stockfish is hands down the best Chess player in the world with a rating  of 3643  (as of this writing), I challenge the user to think like Stockfish does by intermingling normal positions and puzzles to train their awareness of tactics when looking at a position. 

HTML/CSS

Besides chessboard.js’ CSS and a handful of borrowed components, all of the CSS and design was done by myself without a framework. If there’s one thing I learned from this project, it was never to do what I did. Frameworks like Tailwind exist for a reason. Making all the pages responsive took a lot of time and gave me a newfound respect for a lot of frontends that use CSS. 

Screenshot 2025-06-09 004627
A look at responsive homepage

Crafting the HTML was pretty straightforward. However, one thing I realized as the project grew was proper tag management became extremely important, especially as I added more stylesheets for different elements.  Now that I’ve worked with HTML in this project, I’m much more comfortable with markup languages like XML in general.

JavaScript

JavaScript handles all the logic of the puzzles and switching out HTML elements as the puzzles go on. This is where most of the project’s code resides, essentially the soul of everything that happens. It sends requests/data through the REST API  to store and retrieve chess positions, then serves the positions and handles the user’s inputs. It then essentially stores the data in the puzzle log, then puts everything back into place when the user hits next. 

This was the part of the project I enjoyed the most. Coding for functionality rather than the logistics or design felt like the purest form of software development, and seeing that logic come to life was very satisfying. 

The HTML/CSS/JS is deployed together to GitHub, where it then Netlify grabs it and publishes it to chesschoices.com.

Backend (Lambda/RDS)

The backend has two key components. First is a Python script running on AWS Lambda that handles requests from the frontend. Learning AWS was particularly challenging, requiring a lot of time testing alternatives (Firebase, Heroku) before just hunkering down and drilling IAM/EB/Lambda into my head.

The second component is the database of moves that serves the frontend. There are three separate databases of data from Lichess that I curated myself from a public 15GB Lichess file using Python. At first, I wanted to work with JSON/JSONL as it was the format the file was provided in, but that proved difficult as the data was too large and I didn’t have enough experience to really navigate handling it appropriately. So I turned to SQL and SQLite initially, but as I started to use AWS and RDS, I eventually transferred my data to PostgreSQL, where it lives now on RDS.

Snapshot of one of my endpoints

Depending on the endpoint, right now I’ll either pull 10 different chess positions and its associated data for my single board puzzle, or I’ll pull 2 positions at a time for my comparison puzzle. At first, I had my single puzzle pulling one puzzle at a time, but I ran into an issue where my Lambda function (at the time an Elastic Beanstalk deployment) was taking 15 seconds per a request. To get around this, I curated a small local database that loads with the frontend of single puzzle, and then load a queue of positions to fund the frontend. I fixed the Python issue, but I’m testing to see which method I prefer. I think eventually I’ll switch back to loading a single position, as loading 1MB of data every time the single puzzle loads is just not as efficient as the comparison puzzle’s method, even though you are saving 10 Lambda requests. 

The Lambda function is routed through AWS API Gateway as a REST API, which handles authentication/authorization for RDS and external endpoints for Lambda. Once RDS receives the GET request, data is sent back to the frontend, where JavaScript uses the FEN and associated data to create the puzzle.

When the user finishes a puzzle, data about user’s rating and puzzle success/failure routed to an RDS database so I can curate data for future users.

Art

The chessboards, all of the fish images, browser logos, everything artistic was also handled by myself in GIMP. Since the user is trying to outsmart Stockfish, I thought it would be funny to have it as a type of “mascot” for the site (maybe also a little because Stockfish and it’s associated imagery is completely open source). I wanted to keep everything relatively minimalistic design-wise, but not so minimalistic that it looked barren.

Major Takeaways

I learned A LOT of coding through this project. I am very comfortable coding with HTML/CSS/JavaScript now. Since Python wasn’t really the main focus of the project, I didn’t learn as much. AWS was a huge component, with deploying to Elastic Beanstalk and then transferring to Lambda taking up probably the bulk of the project’s time beyond designing the frontend and scripting the functionality.

Overall, I’m very happy I did it and hope people enjoy playing it.


Nurse Overhaul

Nurse Overhaul is a Terraria mod I authored which does a couple of things:

  1. Adds a hotkey for the Nurse heal 
  2. Adds a shop at the Nurse 
  3. Adds recipes for healing potions

If you want to learn more about the specifics, check out the Terraria community post or the Steam Workshop page.

Or, if you’re more interested in checking out the work itself, take a peek at the GitHub repository.

Example of healing
Items in shop
Custom sprites!
New recipes
Custom pricing for boss fights (and Calamity pricing compatibility!)
Enable and disable what you want


Walk in the Woods

After getting lost on a walk through the forest, you discover a secret long held in this dark land. Can you outwit the traps held within and escape with your life? 

Very small text-based C++ game I wrote for fun while learning the language.

Check it out on GitHub!