Sudokube
Sudokube
2024-04-23 - Web Development, Data Visualization, Computer Science, Gaming
Developer
URL

Background

The origin of this project is a discussion with a friend in which I said that I enjoyed the mental challenges that come with coding: "it’s like solving multidimensional sudokus". But on second thought, it wasn’t obvious to me that multidimensional sudokus were even possible.

What I meant by multidimensional is the following: if you pick any 2 dimensions, the resulting table must respect the sudoku rules. Each row and each column must contain all integers between 1 and 9, and each 3x3 sub-square must also contain all integers. There should be no duplicates and no missing integer.

Verifying the existence of such matrices became a logical puzzle on its own, which I thought I could solve in a week during my commute to/from work. As it turned out, it’s an extremely hard problem to solve. I couldn’t solve it through pure math and my limitations in that domain were not to blame: the brightest mathematicians have hit a wall on an adjacent problem. So I turned to brute force, that is, building an algorithm to generate all possible matrices meeting the constraints.

Despite months of trial-and-error, optimizations or complete overhaul of the algorithm, settling this issue seems desperately out of reach, even for 9x9x9 cubes : my last run lasted 3 weeks, utilizing 100% of the computing power of a top-spec MacStudio… and I could not even get the list of all possible sudokus in 2D, which was a pre-requisite for more dimensions. If you want to get into matrix frameworks like numpy, pytorch, tensorflow, or more recently mlx, this project constitutes a very good introduction.

My only source of satisfaction is that the algorithm works as expected.

In order to check the results of my algorithm, I designed it to build Sudokubes (sudokus in 3D) of different sizes. Cubes of smaller sizes are less computationally-intensive so they are faster to generate, but their key advantage is that it’s much easier to get your head around them when checking the outputs. A typical sudoku has edges of size 9, which corresponds to the square of 3 ; 3 being the size of the sub-squares. As you need an edge size that is the square of an integer, there are only two options below the typical size of a sudoku: 1, the square of 1, is useless for our problem, but 4, the square of 2, is much more interesting. There are 768 size-4 Sudokubes and they take less than 2 seconds to generate on my machine.

The Sudokube game

Size-4 Sudokubes did not only validate the algorithm, they also appeared to constitute a very good base for an actual game. Neither too easy nor too hard:

  • there are 64 values (vs. 81 values in a typical sudoku)
  • there are 96 conditions to meet (vs. 27 in a typical sudoku)
  • 3D is a bit unsettling at first but you quickly ignore the visual representation and use the third dimension to your advantage

Once the first prototype was put together, I quickly realized that we could not choose the seeding values of a Sudokube randomly; I had to identify the unique combinations for each Sudokube to avoid seeding a game with multiple solutions. Using brute-force once again, I learnt that the smallest combination size guaranteeing uniqueness is 5: if you seed with any set of 4 values, there will be several solutions whereas a set of 5, if chosen appropriately, guarantees uniqueness. Any size-4 Sudokube has either ~1m unique combinations of 5 values or ~91k of such sets. I did not try to understand why it was either one or the other; I just used this piece of information to set the most difficult level of the game : a Sudokube seeded with only 5 values. Overall, there are over 500m seeding combinations to choose from.

We came up with seven levels of difficulty:

  • at introduction level, the Sudokube is seeded with 10 values
  • at beginner level, it is seeded with 9 values
  • at easy level, it is seeded with 8 values. Up the this point, you can expect on average 4-5 minutes to complete a Sudokube
  • at intermediate level, it is seeded with 7 values
  • at advanced level, it is seeded with 6 values
  • at pro level, it is seeded with 5 values, the minimum size guaranteeing uniqueness of the solution
  • at expert level, helping features, such as assisted 3D navigation or validation animations, are disabled. This basically requires a full mental model of the cube in 3D, it’s really hard.

Tech details

  • Backend : minimal at first, it essentially consists in a Flask app serving a random Sudokube and an associated unique combination at each API call. Hosted on Digital Ocean : we went for a droplet even though a serverless function would have been sufficient (no Flask or Gunicorn). Droplets are more expensive but functions could not be protected with an Access-Control-Allow-Origin header ; only though an API token which would have been exposed on the frontend.
  • Frontend : React app, built with Vite, and hosted on Vercel. The 3D engine is powered by Three.js.

Next steps

  • Mobile app, addressing the shortcomings of the responsive web design
  • Monetisation : I learnt a lot during building this app which, in essence, creates value, but I am a firm believer that a project MUST be sustainable to be considered a GOOD project. Stating the obvious, monetisation primarily requires a good product, which means that [more] effort should be put into game design to achieve breakeven. Helping features (such as rewinding) also look like good candidates to base monetisation on.
We care about your privacy so we do not store nor use any cookie unless it is stricly necessary to make the website to work
Got it
Learn more