May 01, 2025

Chess

The challenge to designing any architecture is to strike the balance between long term and short term goals. I’m not interested in discussing agile and the project management related matters. The general rule of thumb is to keep things simple and don’t do more than you need to. Generally, I’m not involved in a project unless it needs my unique viewpoint and very careful eye. I always say that the closer to real life your system is, the better. The more structurally accurate the modularity and isolation the fewer concerns you will have. A very decoupled architecture will have a great deal more moving pieces. For those who are unfamiliar with that type of system, it can be overwhelming and quite simply wrong. The interfaces for those isolated perspectives are important, not attempting to implement every possible contingency and scenario.

The need to refactor isn’t a sign of weakness or lack of foresight. However, iderally refactoring should really only be needed when an actual business case changes. Let’s look at the classical board game of chess for a moment. I’m not the best player around but I have a strong appreciation for the game. I have used this as an interviewing technique. I’d ask the candidate to begin to design a chess game. How would they start? What would the general system look like? Now I would never expect the candidate to anticipate what if we want to change the chess board to three dimensions. What if we added additional players? What if we created new pieces? Some of these items may be so intrinsic to chess that the thought of considering one way or another was simply not considered. Functional programming is very populuar now. Much like agile, functional can be a crutch for poor architecture. That should not be the case. Even a functional approach should have strong isolation of concerns. The terminology of your approach is not as important as the approach itself. Whether its a callback, observer, factory, facade, etc.. it’s not the name but what the approach provides you. You don’t need an object oriented language to write good clean code, but it helps. A statically typed language for enterprise application isn’t an option, it isn’t a debate, it is simply the law. Luckily the compilers today have evolved and are quite advanced. They are able to follow inferences and eliminate a great deal of extraneous boilerplate code.

So what is the trick to always start off with the best architecture and limit the number of times you need to refactor? It is quite simple. Design reality.

Let’s start with chess. If you look at some chess boards they have letters and numbers. These are used to accurately depict a position without having to use your fingers to point. In general with computers and engineering if you need to point or make a gesture for a reference, the resolution of detail is lacking. Hopefully you are familiar with the cartesian coordinate system that you learned in grade school. Even if you aren’t familiar with it, even without a formal definition of the system you are most likely acquinted with it already. Simply enough, you have a range of numeric values each associated with a given axis. There is a great deal more to it, and if you take the time you will appreciate a lot of what probably put you to sleep at one time. Sadly, most of the math that I learned in school was memorization and whatever was needed to pass state exams. I’m not really a math guy, so be warned I’m out of my element, and welcome any useful comments.

The standard chess board has axises. Each with eight positions. Totalling sixty-four total positions. A unique position is defined at the intersection of a point within each axis. There are several pieces, each with their own rules. I always start off by trying to establish the objective of the system. Chess is a game, an amusement…but let’s talk about the objective of playing the game and not to have fun. The objective of chess is to prevail either by your opponents resignation or putting them into checkmate. Chess is a turn based game. That means that each player must move a piece each sucessive turn. In some turn-based games a player can “pass”, that is not an option in chess. Without even getting into specifics the important thing to establish is that the game of chess can be represented as a state machine. Chess has absolutely no random component associated with it such as a rolling a dice. Why is a state machine significant? A state machine means that you can represent the exact moment in time of the game in a way such that you can replay the game from its inception and recover the exact state. For our purposes the information you would need to retain to replay the game to its current state will help you establish the essential data. Now you can assess what each state and its transition looks like. If you are smart enough you will realize that once you have a given state of chess at that point you can technically calculate all the possible variations that will yield checkmate. This is not realistic as far as computation as this would be in polynomial time. When you look at an application or a system from a state machine perspective it is a very simple way to capture its essence.

The important detail is where the major logic should be defined. Each piece should have the ability in a given board return a list of all valid moves. Most of the information may be interpreted from the current state of the board and its pieces. Certain things like if you moved the king or not would not be evident since the king may be moved away and then returned to its inital location. We need to assume that a board may have rules and state. Like was the king moved or not, or is there a piece here or not. The game and its players have some rules and state. The color pieces of each player. Most importantly is the rules of each individual piece type.

For some of the attributes you may find yourself creating lots of boolean attributes to represent what appears to be property. Don’t do the equivalency of creating a ton of columns in a single table. That is the opportunity to create proper and fitting classifications.