SRM INSTITUTE OF SCIENCE AND TECHNOLOGY DELHI-NCR CAMPUS, MODINAGAR,
GHAZIABAD
Sudoku – A Logical Number Puzzle
Submitted BY:
Subject In-Charge
Dinesh Kumar
SRM Institute of Science & Technology
IntroductIon to the Project
• This project demonstrates how to implement a Sudoku game
using Object-Oriented Programming in C++.
• Sudoku is a logic-based number puzzle that challenges your
reasoning skills rather than your math skills.
• It involves filling a 9×9 grid so that each row, column, and 3×3
subgrid contains all digits from 1 to 9 without repeating.
Why Sudoku?
• Sudoku is a classic puzzle game that helps develop logic and
problem-solving skills. It's a great example for implementing
OOP.
Real-World Logic Application
• Sudoku puzzles are widely recognized for testing logical
thinking and problem-solving—skills essential for programming.
objectIve of the Project
• To build a console-based Sudoku solver that applies backtracking algorithm and uses C++ OOP principles.
• AI & Machine Learning: Constraint satisfaction and backtracking are used in search algorithms and decision-making.
• Cybersecurity: Sudoku-like algorithms are applied in cryptography and data obfuscation.
• Game Development: Logic engines in puzzle and strategy games use similar OOP and backtracking principles.
• Medical Research: Sudoku-solving logic is used in gene sequencing and medical diagnostics.
• Scheduling Systems: From timetables to resource allocation, the logic of Sudoku supports automated planning tools.
ooP concePtS uSed
• Encapsulation
• Abstraction
• Constructor & Destructor
• Class and Objects
• Member Functions
claSS deSIgn overvIeW
Class: Sudoku
�Attributes (Private):
int board[9][9];
A 9x9 grid representing the Sudoku puzzle.
Value 0 indicates an empty cell.
Memory and it’s purpose
• setBoard()
• Takes a 2D array as input and sets the puzzle board
Design Highlights
• Encapsulation: Puzzle logic and board data are kept together and hidden from direct access.
• Abstraction: Users only interact with methods—no need to manage grid directly.
• Reusability: The class can be reused in other games, puzzles, or apps.
• Scalability: Easily extendable for GUI, difficulty levels, or puzzle generation.
claSS: Sudoku
• This class encapsulates all functionalities related to Sudoku
puzzle handling and solving.
• This class handles:
• Board input/output
• Rule validation
• Puzzle solving via recursion
attrIbuteS and MethodS
• Attributes:
• - int board[9][9];
• Methods:
• - isValidMove()
• - solveSudoku()
• - printBoard()
conStructor & deStructor
• CONSTRUCTOR • DESTRUCTOR
The constructor initializes the Sudoku board by Even though we don’t use dynamic memory here, we can
define a destructor to indicate when the object is destroyed
setting all values to 0 (empty cells). (useful for debugging or resource cleanup).
// Constructor // Destructor
Sudoku() { ~Sudoku() {
for (int i = 0; i < 9; ++i) cout << "Sudoku object destroyed.\n";
}
for (int j = 0; j < 9; ++j)
board[i][j] = 0;
cout << "Sudoku board initialized.\n";
}
Method: ISvalIdMove()
Purpose: Checks whether placing a number in a specific cell follows Sudoku rules.
bool Sudoku::isValidMove(int row, int col, int num) {
// Check row and column
for (int i = 0; i < 9; i++) {
if (board[row][i] == num || board[i][col] == num)
return false;
}
// Check 3x3 sub-grid
int startRow = row - row % 3;
int startCol = col - col % 3;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[startRow + i][startCol + j] == num)
return false;
return true; // If no conflict, it's a valid move
}
Method: SolveSudoku()
Purpose:
Solves the entire Sudoku puzzle using recursive backtracking, a depth-first search technique.
Logic Breakdown:
• Searches for the first empty cell
• Tries numbers 1 to 9
• Checks if the move is valid with isValidMove()
• Calls itself recursively to solve the rest of the board
• If no number fits, it backtracks to the previous step
Method: PrIntboard()
Purpose:
Displays the current state of the Sudoku board in a user-friendly, readable format.
void Sudoku::printBoard() {
for (int i = 0; i < 9; i++) {
if (i % 3 == 0 && i != 0)
cout << "------+-------+------\n";
for (int j = 0; j < 9; j++) {
if (j % 3 == 0 && j != 0)
cout << "| ";
cout << board[i][j] << " ";
}
cout << endl;
}
}
MaIn functIon floW
START
↓
Create Sudoku Object
↓
Set Initial Board
↓
Display Board (Optional)
↓
Call solveSudoku()
↓
IF Solved?
↓ ↓
YES NO
↓ ↓
Print Show
Solved "No Solution"
Board Exists"
↓
END
code SnIPPet: claSS defInItIon
• class Sudoku {
• private:
• int board[9][9];
• public:
• bool solveSudoku();
• bool isValidMove(int row, int col, int num);
• void printBoard();
• };
code SnIPPet: Sudoku Solver functIon
bool Sudoku::solveSudoku() {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
// If the current cell is empty
if (board[row][col] == 0) {
// Try all numbers from 1 to 9
for (int num = 1; num <= 9; num++) {
if (isValidMove(row, col, num)) {
board[row][col] = num; // Place the number
// Recursively try to solve the rest
if (solveSudoku())
return true;
// Backtrack if placing num didn't lead to a solution
board[row][col] = 0;
}
}
// No valid number found, backtrack
return false;
}
}
}
// Puzzle is solved
return true;
}
code SnIPPet: valId Move functIon
bool Sudoku::isValidMove(int row, int col, int num) {
// Check if 'num' is not in the current row and column
for (int i = 0; i < 9; i++) {
if (board[row][i] == num || board[i][col] == num)
return false;
}
// Check if 'num' is not in the current 3x3 box
int startRow = row - row % 3;
int startCol = col - col % 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[startRow + i][startCol + j] == num)
return false;
}
}
return true; // Valid move
}
code SnIPPet: MaIn functIon
int main() {
Sudoku game;
// Sample board (0 represents empty cells)
int sampleBoard[9][9] = {
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}
};
game.setBoard(sampleBoard); // Initialize the board
if (game.solveSudoku()) {
std::cout << "Solved Sudoku:\n";
game.printBoard();
} else {
std::cout << "No solution exists.\n";
}
return 0;
}
full IMPleMentatIon
#include <iostream>
using namespace std;
class Sudoku {
private:
int board[9][9];
public:
// Constructor: Initializes the board to 0
Sudoku() {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
board[i][j] = 0;
}
// Method to set the initial board
void setBoard(int input[9][9]) {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
board[i][j] = input[i][j];
}
// Print the Sudoku board
void printBoard() {
for (int row = 0; row < 9; row++) {
if (row % 3 == 0 && row != 0)
cout << "------+-------+------\n";
for (int col = 0; col < 9; col++) {
if (col % 3 == 0 && col != 0)
cout << "| ";
cout << board[row][col] << " ";
}
cout << endl;
}
}
// Check if a number is valid in the given cell
bool isValidMove(int row, int col, int num) {
for (int i = 0; i < 9; i++) {
if (board[row][i] == num || board[i][col] == num)
return false;
}
int startRow = row - row % 3, startCol = col - col % 3;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[startRow + i][startCol + j] == num)
return false;
return true;
}
// Backtracking algorithm to solve Sudoku
bool solveSudoku() {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (board[row][col] == 0) {
for (int num = 1; num <= 9; num++) {
if (isValidMove(row, col, num)) {
board[row][col] = num;
if (solveSudoku())
return true;
board[row][col] = 0;
}
}
return false; // Trigger backtracking
}
}
}
return true; // Solved
}
};
// Main Function
int main() {
Sudoku game;
// Sample board with 0s representing empty cells
int sampleBoard[9][9] = {
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}
};
game.setBoard(sampleBoard);
cout << "Initial Sudoku Board:\n";
game.printBoard();
if (game.solveSudoku()) {
cout << "\nSolved Sudoku Board:\n";
game.printBoard();
} else {
cout << "\nNo solution exists.\n";
}
return 0;
}
outPut of code
Initial Sudoku Board: Solved Sudoku Board:
534|678|912
530|070|000
672|195|348
600|195|000
198|342|567
098|000|060
------+-------+------ ------+-------+------
800|060|003 859|761|423
400|803|001 426|853|791
700|020|006 713|924|856
------+-------+------ ------+-------+------
060|000|280 961|537|284
000|419|005
287|419|635
000|080|079
345|286|179
teStIng the Sudoku Solver
• Input board with some pre-filled values is tested.
• The output is verified to ensure it's a correct Sudoku solution.
• The puzzle was successfully solved.
• Output matches known solution.
• Demonstrates correct working of isValidMove() and solveSudoku()
methods.
thank you