Fixing the Square Off Board

A few months ago, my Square Off chess board arrived. It’s a chess board that’s capable of moving the pieces on its own. You connect to it with your phone using the Square Off app and you can play against the built-in engine, play against other people online over the board, or stream and watch games being played.

To make a move, you press down on the piece you want to move, move it to the square you want then press down again. There’s a series of pressure sensors under the board used to detect when you’re pressing down on it. Underneath that is an electromagnet (a magnet that can be turned on and off) that’s hooked up to a 2D rail system similar to 3D printers. The pieces have some sort of metal in them that’s magnetic, and with it the electromagnet is capable of moving the pieces. 

The board itself isn’t capable of detecting where the pieces are or where the electromagnet currently is. When you boot it up, the board calibrates the rail system and it assumes the starting position is on the board. From there, it simply keeps track of where everything is as moves are played. If it ever shuts off, you’re on your own resetting the board.

The board is very cool and I love it, but there are a few things that disappointed me. First, when moving pieces, the paths the board chooses to take often isn’t very efficient and it occasionally knocks over pieces even when they could’ve been easily avoided. Second, there are a lot of basic and straight forward features that it doesn’t have, like the ability to set up custom positions, or the ability to re-calibrate the position of the electromagnet mid-game. Third, I’m not a huge fan of the system for promoting pawns; you have to select the piece you’re promoting to using the app and you also have to swap out the pawn for the piece yourself.

Thankfully, the people who made the board are capable of pushing firmware updates onto the board. Theoretically, it may be possible for them to fix these issues without having to swap to a new board. This is where I come in.

The way the board works is very similar to a project I did in college. We built a box with a series of switches on it. When you flipped one of the switches on, the box would open, a robotic arm controlled by a rail system similar to the one in the Square Off board would move to the switch and flip it off. My experience from that project has given me a solid intuition over how the Square Off board works, thus making me fully qualified to fix the Square Off board.

So let’s break down how I would redesign the algorithms used to move pieces in the Square Off board.

Overview

The rail system is moved using motors inside the board. When a motor moves, what direction it moves in and how fast it moves is dependent on electrical signals sent to it. All of the motors are connected to a microprocessor, which is a tiny computer. We can program the microprocessor to generate specific electrical signals and send them to the motors, effectively making them do what we want them to do. In other words, we can control the motors using the microprocessor. Same goes for the electromagnet; we can connect it to the microprocessor and control it. I don’t know what specific parts they use for the electromagnet and motors, so I can’t go into any more detail than that. For now, we’ll assume they work great and skip that part.

So we can turn the electromagnet on and off and we can move it wherever we want underneath the board. Now we need to create a program that generates a list of commands for the rail system to follow in order to move the pieces to where we want them.

When dealing with systems like this, it’s best to break it down into multiple smaller systems, or functions, that all function independently of each other. This makes it simpler, easier to work with, and less likely to break. 

Making a piece move

First, we’ll create a function that can move a piece from its current spot to a new spot. We’ll tell it where it currently is and where we want it to go. Using this information, it will move the electromagnet to underneath the piece, turn it on, move it to the piece’s new square, and turn it off (while it’s on, the piece is magnetically attracted to it and will move with it).

First, the electromagnet will have to move from its current position straight to where the piece is. As established earlier, we’re assuming this works great already.

Once the electromagnet is underneath the piece we want to move, we need to move it to the new square. However, this part is trickier. We can’t just move it straight to the new square; we need it to take a path that avoids knocking over other pieces on the board. 

Here’s how we’ll do it: we’ll designate a number of “nodes” onto the board, like this: 

Each blue dot represents a node

From one node, we can travel straight to any empty node adjacent to it vertically, horizontally or diagonally. From here, there are plenty of pathfinding algorithms out there we could use to find the shortest path from one node to another. However, as I’ve observed, when moving pieces, the pieces on the board tend to accelerate and decelerate. So the fastest route won’t necessarily be the shortest route, but rather the route that takes the least number of turns. So we’ll have to bend the rules a little. Let’s say this red node is our starting node, and yellow nodes are nodes with pieces on them (see below). Here, all of the nodes in green would be considered to have a distance of 1 between it and the red node: 

The red dot is the starting node, the yellow dots are pieces on the board and green dots are nodes that can be reached from the red node without turning

Using these rules, we can run a simple pathfinding algorithm to find the path with the least number of turns between the starting node and the finishing node. The way it works is every node will be given a distance value. The starting node’s distance value is set to 0 and all others are set to infinity. Next, it looks at all nodes “adjacent” to the starting node (in other words, the green nodes above) and sets their distance value to 1. Next, from each node with a distance of 1, it looks at all of their adjacent nodes (except for the ones that already have been assigned a value) and give them a distance value of 2. Then nodes adjacent to those are given a value of 3 and so on. This repeats until the the finishing node is reached. From here, it simply retraces its steps using the distance values it left behind and thus finds the path with the fewest turns possible. 

With the path identified, we’ll send all the electrical signals to the motors needed to make it follow that path.

So now, with this function, we can feed the board a starting square and ending square and it will move the piece on the starting square to the ending square. With this, if we make a function that can check whether a move is legal or not per the rules of chess, we can already have the board accepting inputs from users.

Setting full positions

But what if instead of just moving a single piece, we want to change the entire position on the board? How do we make it do that?

As it currently is, the Square Off app does have a “Reset Board” button that moves all of the pieces from their current squares to the starting position. However, it always moves the pieces in the same order: white rooks, white minor pieces, white king & queen, black rooks, black minor pieces, black king & queen, white pawns, black pawns. Watching it, I see it moving the electromagnet moving back and forth the length of the entire board a lot.

Let’s try to fix it and also 1-up it. We’ll make a function that, given a position that we want to see on the board, will generate a list of moves that will efficiently convert the current position on the board to the position we want. With this, we could easily set up whatever position we want. We could also use it to reset the pieces by setting the desired position to the starting position.

First, how do we feed it a position? Well, in chess, there’s things called FENs. Forsyth-Edwards Notation (FEN) is a system to very concisely describe a position on the board. We won’t talk about how it works in this post, but suffice to say we could create a function that can interpret FENs (which we also won’t talk about now).

So we know the current position on the board, and we know what the desired position is. First, we’ll go over each square on the board and check if the correct piece (or lack thereof) is already on it. We’ll have several lists, one for squares that need white rooks on them, one for squares that need white knights on them, one for squares that need black bishops on them and so on.

With this information, we now have all of the ending squares for our move list, now we need starting squares for each. Let’s start with the list of squares that need white rooks. If one of the rooks is already in the correct square, then there’s only one square needing a white rook. The starting square is therefore the square that currently has a white rook on it and the ending square is the square that needs a white rook. That’s one move down, and we’ll add it to the move list.

But what if neither rook had been on the correct square? We could just assign each to a square at random, but there are plenty of scenarios in which that could be inefficient. For example, if the white rooks are on a8 and h8 and we want to move them to a1 and h1, it wouldn’t make sense to move the rook on h8 to a1 and the rook on a8 to h1. They’d both be traveling needlessly long distances. So we’ll calculate the distances from each white rook to each square that needs a white rook, take the sum of distances in each possible combination and then pick the one that has the least distance total. It’s not a perfect system as it assumes straight paths and not paths that avoid other pieces, but it’ll be good enough.

We’ll do this for every type of piece. Each square that needs a piece will effectively be paired with a square that has the piece it needs. Our move list is effectively complete and with it, we can simply feed the moves to that other function we made one by one and we’d be done. However, I want to take it a step further.

With our unorganized list, we may still run into the problem the board currently has where the electromagnet goes back and forth the length of the board a lot more than it needs to. We can fix this by reorganizing our move list to minimize the distance that the electromagnet has to travel.

We’ll start with the current position of the electromagnet and we’ll calculate the distance between it and every starting square in our list of moves. The move whose starting square is closest to where the electromagnet’s current position is will go first. At the end of that move, we’ll know that the position of the electromagnet is at the ending square of that move. With this information, we can repeat this process for the remaining moves and thus have completely reorganized the list to optimize the electromagnet’s movement. Again, this system isn’t perfect, but it’ll be good enough.

After thinking about this some, I realized we’ll have to add a couple of failsafes. When we find the move whose starting square is closest to the electromagnet’s current position, we’ll have to verify that the ending square of that move is unoccupied. If there’s a piece already on it, we’ll have to skip that move and go on to the next closest move so we don’t just knock the piece over.

Also, while it probably won’t ever happen unless someone does it on purpose, we’ll have to consider a scenario in which all of the ending squares in the move list are already occupied by pieces. In such a scenario, we’ll need to generate a new move to put at the top of the list takes one of the pieces and moves it to a different square (doesn’t matter which one) in order to free up a square and allow the other pieces to be moved to the correct squares one by one. 

Now we have an optimized list of moves that convert a given position to a new position. To execute it, we just need to feed each of the moves to the function we made earlier one by one.

Summing up

We’ve done it! We’ve created a system for moving pieces on the Square Off board that’s much better than the one currently in it. Of course, actually making all of the code for this system is a whole other beast, and the labor for it would be quite expensive. Also, there’s a lot it has to calculate, and depending on how powerful the microprocessor is, the amount of time it takes to execute all of this might be too slow to be worth it. And we didn’t even touch the problem of pawn promotions.

But hey, kudos for us (or me really) regardless.

1 comment

Comments are closed.