Dancing Links Sudoku Solver and Explorer

Published on: Download DLXSudokuSolver Source Code

Dancing Links Sudoku Solver and Explorer - TGMDev

Introduction

Dancing Links is an algorithm introduced by the brilliant American computer scientist Donald Knuth. This technique is well known for efficiently solving Sudoku grids and assessing their validity — including detecting unsolvable puzzles or those with multiple solutions.

The first version of the application was based on the Sudoku solver ZeroDlx written by Jim Schirle. The code was updated to be used as a C++ class and modified to use the Hungarian notation. The new release V2.0 was thouroughly re-written to use STL (ISO C++ 20) and to allow the display of the progress of the solving algorithm.

A Word of Caution to Fellow Devs

The application is based on the MFC (Microsoft Foundation Classes) framework. I know that many people find MFC programming complex and quite outdated. But, since I don't bother writing software for other operating systems than Windows, I've kept this technology for all my programming projects. Since the Visual Studio compiler supports the latest ISO C++ 20 standard, STL is widely used as a replacement for classic C++ methods. In addition, Hungarian notation, introduced at Microsoft by Charles Simonyi, is systematically used to name program variables. Again, many programmers deny the use of this naming convention. But, once again, I don't worry about it. Charles Simonyi is one of the best software designers, and I have personally found Hungarian notation extremely useful in software development.

Naming Convention

This naming convention is quite classic and stems from my very first experience of C programmming the OS/2 API of Microsoft/IBM in the late eighties

Application Main Settings

The application is written in C++ using the Microsoft IDE Visual Studio Community Edition 2022.

The configuration is quite standard for a 64-bits application:

  1. Latest Plateform Toolset (v143)
  2. C++ Language Standard: ISO C++ 20

Dancing Links Configuration 1 - TGMDev
  1. Use of MFC: Use MFC in a Static Library (so I don't have to worry about MFC dlls)
  2. Character Set: Use Unicode Character Set

Dancing Links Configuration 2 - TGMDev

Application Classes

The application is made of the following classes:

  1. CDLXSudokuSolverApp (derived from CWinApp): the main MFC application class that handles initialization, execution, and termination of the DLXSudokuSolver application.
  2. CDLXSudokuSolverDlg (derived from CDialogEx): DLXSudokuSolver is a simple dialog-based application. This class manages user interaction and updates the graphical interface.
  3. CDLXSolver: the base class implementing the core Dancing Links algorithm.
  4. DLXNode: a foundational support class used internally by CDLXSolver.
  5. DLXColumn: a companion class derived from DLXNode, used for column tracking in the Dancing Links structure.
  6. CButtonBoard: a custom button class (derived from CButton) used to graphically display the Sudoku board.
  7. CAboutDlg: the dialog class (derived from CDialogEx) that displays the “About” box of the application.
  8. DebugTrace: a namespace providing internal tracing tools for monitoring and debugging the execution flow.

Note: the namespace DebugTrace is heavily used in DLXSodukuSolver and provides several macros (DBG_LOG, DBG_TMB, DBG_TME, ..) to trace the execution of the application. Complete explanations about this namespace is available in the C++ Section.

Process Execution

When the user click on the 'Solve' button, the function CDLXSudokuSolverDlg::OnSolve() is called by the MFC framework.

The main actions are:


    // Build and Initialize Solver Instance

    m_pDLXSolver = new CDLXSolver(this->GetSafeHwnd(), static_cast(str), GetDelay(), nSolverMode);

    // Update Board with Initial Sudoku Data

    m_ButtonDLXBoard.DrawBoard(m_pDLXSolver->m_nGroupSize, m_pDLXSolver->m_vctrSudoku);

    // Start Dancing Links Solver

    m_pDLXSolver->StartSolver();
	

The parameters of the Solver constructor are the following:

The Sudoku grid (second parameter) is passed as a std::wstring. This string is then converted in a vector of std::pair named m_vctrSudoku in the function CDLXSolver::ConvertStringToVector()

This vector m_vctrSudoku is used to:

The function CDLXSolver::StartSolver() simply starts the solver in a thread:


    // Start Thread to Solve Sudoku

    m_thread = std::thread(&CDLXSolver::Solve, this);
	

At that time, the actual solving process starts:

Visually, the recursion process can be illustrated by using the macro DBG_IND_LOG with the parameters DBG_INCR and DBG_DECR at the entry and the exit points of the function CDLXSolver::Search. Complete explanations about this namespace is available in the C++ Section.

Solver recusion - TGMDev

Note that non-valid Sudoku grids can generate more than one solution. These grids are not useable for human resolution but are stored for further display (if requested by the user) in the vector m_vctrSolutions. Note the s at the end of the vector name as it is used to store a potential array of strings (declared as std::vector m_vctrSolutions in the CDLXSolver include file.

Download Link

Download DLXSudokuSolver Source CodeReturn to C++ Programming Main Page