Facebook Twitter Instagram
    DeepCrazyWorld
    Facebook Twitter Instagram Pinterest YouTube
    • FLUTTER
      • FLUTTER APP
        • QRCode
        • Quiz App
        • Chat GPT
        • PDF App
        • News App
        • Fitness App
        • Weather App
        • BMI Calculator
        • GAME APP
        • Ecommerce App
        • wallpaper App
        • Finance app
        • Chat App
        • Wallet App
        • Taxi App
        • Quran app
        • Music player app
      • FLUTTER UI
        • Splash Screen
        • Onboarding Screen
        • Login Screen
        • Card Design
        • Drawer
    • PROJECT
      • Android Projects
      • College Projects
      • FLUTTER APP
      • Project Ideas
      • PHP Projects
      • Python Projects
    • SOURCE CODE
    • ANDROID
      • ANDROID APP
      • GAME APP
      • ANDROID STUDIO
    • MCQ
      • AKTU MCQ
        • RPA MCQ
        • COA MCQ
        • HPC MCQ
        • SPM MCQ
        • Renewable Energy All MCQ
        • Data Compression MCQ
        • Data Structure MCQ
        • Digital Image Processing MCQ
        • Software Engineering MCQ
        • Machine Learning MCQ
        • Artificial Intelligence MCQ
      • D PHARMA MCQ
        • Pharmaceutics – I MCQ
        • Pharmacognosy MCQ
        • Pharmaceutical Chemistry MCQ
        • Biochemistry and Clinical Pathology MCQ
        • Human Anatomy and Physiology MCQ
        • Heath Education and Community Pharmacy MCQ
    • INTERVIEW QUESTIONS
      • Flutter Interview Questions
      • INTERVIEW QUESTIONS
      • Python Interview Questions
      • Coding ninjas solution
    • MORE
      • WORDPRESS
        • SEO
        • TOP 10 WORDPRESS THEME
      • PRODUCTIVITY
      • Program
      • QUOTES
    DeepCrazyWorld
    Home»Web Developer»Sudoku : How to Make a Sudoku puzzle Game in html
    Web Developer

    Sudoku : How to Make a Sudoku puzzle Game in html

    DeepikaBy DeepikaAugust 1, 2020Updated:April 17, 2023No Comments14 Mins Read

    When We first started playing with writing a Sudoku game, I took the long way to create Sudoku templates and to make a sudoku puzzle in html Using a recursive backtracking algorithm, I would slowly fill up the grid with random numbers – checking the validity of the puzzle at each step. If I hit a roadblock where the puzzle cannot be completed, the algorithm would backtrack until it could move forward, and then move forward again. how to make a sudoku game in javascript,

    There is a more elegant solution however: create a solved sudoku and then shuffle it.

    Table of Contents

    Toggle
    • Generate and Solved Sudoku
    • Sudoku Puzzle Game Source Code
    • index.html
    • Make a puzzle in html
    • style.css
    • create a sudoku game in html css and js
    • script.js
    • YouTube Video
    • READ MORE

    Generate and Solved Sudoku

    1.Step : Creating the solved Sudoku is easy: just shift the row above to the left by 3 unless its vertical index is equally divisible by 3 (starting with index 0) in which case shift the row above by 4.

    1 2 3 4 5 6 7 8 9
    4 5 6 7 8 9 1 2 3
    7 8 9 1 2 3 4 5 6
    2 3 4 5 6 7 8 9 1
    5 6 7 8 9 1 2 3 4
    8 9 1 2 3 4 5 6 7
    3 4 5 6 7 8 9 1 2
    6 7 8 9 1 2 3 4 5
    9 1 2 3 4 5 6 7 8


    2.Step : Shuffle the rows and columns. Of course, to do so and ensure the Sudoku rules maintain integrity, you can only shuffle rows and columns of the same group: groups being 1-3, 4-6, and 7-9. Demonstrated below, the columns 1 and 3 are shuffled

    <img decoding=

    Sudoku Puzzle Game Source Code

    index.html

    <!DOCTYPE html>
    <html lang="en" >
    <head>
      <meta charset="UTF-8">
      <title>DeepCrazyWorld - SUDOKU Puzzle Project</title>
      <link rel="stylesheet" href="./style.css">
    
    </head>
    <body>
    <!-- partial:index.partial.html -->
    <a href="#" id="sidebar-toggle">
       <span class="bar"></span>
       <span class="bar"></span>
       <span class="bar"></span>
    </a>
    
    <h1 id="sudoku_title">SUDOKU PROJECT</h1>
    
    <div id="sudoku_menu">
      <ul>
        <li><a class="restart" href="#">New Game</a></li>
        <li></li>
      </ul>
    </div>
    
    <div id="sudoku_container"></div>
    <!-- partial -->
      <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script><script  src="./script.js"></script>
    
    </body>
    </html>
    

    Make a puzzle in html

    style.css

    h1 { 
        background:black;
        color:white;
        margin:0px 0px 2px 0px;
        font-size:20px;
        padding:2px 1px 5px 1px;
        text-align:center;    
    }
    
    body {
        font-family:verdana,helvetica,arial,sans-serif;
        border:0px; margin:0px; padding:0px;
            
        background:url(
            data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAIUlEQVQYV2N89urtfwYiACNIoZSYMCMhtaMK8YYQ0cEDAG5yJ8eLRhTfAAAAAElFTkSuQmCC
        ) repeat;
    }
    
    /* board */
    .sudoku_board {
        margin:6px auto;
      
        overflow: hidden;
        
        -webkit-user-select: none;  
        -moz-user-select: none;    
        -ms-user-select: none;      
        user-select: none;
        
        box-shadow: 0px 0px 5px 5px #bdc3c7;
    }
    
    .sudoku_board .cell {    
        width:11.11%;    
        display: inline-block;    
        float:left;
        cursor:pointer;    
        text-align: center;
        overflow: hidden;  
        
        -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    	    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    	    box-sizing: border-box;
        
        box-shadow: 0px 0px 0px 1px #bdc3c7;
      
        background:white;
    }
    
    .sudoku_board .cell.border_h {
        box-shadow: 0px 0px 0px 1px #bdc3c7, inset 0px -2px 0 0 #34495e;    
    }
    
    .sudoku_board .cell.border_v {
        box-shadow: 0px 0px 0px 1px #bdc3c7, inset -2px 0 0 #34495e;
    }
    
    .sudoku_board .cell.border_h.border_v {
        box-shadow: 0px 0px 0px 1px #bdc3c7, inset -2px 0 0 black, inset 0px -2px 0 black;
    }
    
    .sudoku_board .cell span {
        color:#2c3e50;
        font-size:14px;
        text-align:middle;    
    }
    
    .sudoku_board .cell.selected, .sudoku_board .cell.selected.fix {
        background:#FFE;    
    }
    
    .sudoku_board .cell.selected.current {
        position:relative;
        background: #3498db;
        font-weight:bold;
        box-shadow: 0px 0px 3px 3px #bdc3c7;
    }
    
    .sudoku_board .cell.selected.current span {
        color:white;
    }
    
    .sudoku_board .cell.selected.group {
        color:blue;    
    }
    
    .sudoku_board .cell span.samevalue, .sudoku_board .cell.fix span.samevalue {
        font-weight:bold;  
        color:#3498db;
    }
    
    .sudoku_board .cell.notvalid, .sudoku_board .cell.selected.notvalid{
        font-weight:bold;
        color:white;;
        background:#e74c3c;
    }
    
    .sudoku_board .cell.fix {
        background:#ecf0f1;
        cursor:not-allowed;
    }
    
    .sudoku_board .cell.fix span {
      color:#7f8c8d;
    }
    
    .sudoku_board .cell .solution {
      font-size:10px;
      color:#d35400;
    }
    
    .sudoku_board .cell .note {
        color:#bdc3c7;    
        width:50%;    
        height:50%;
        display: inline-block;    
        float:left;
        text-align:center;
        font-size:14px;
      
        -webkit-box-sizing: border-box;
    	    -moz-box-sizing: border-box;
    	    box-sizing: border-box;
    }
    
    .gameover_container .gameover {
        color:white;
        font-weight:bold;
    	    text-align:center; 
        
        display:block;
        position:absolute;       
        width:90%;    
        padding:10px;
        
        box-shadow: 0px 0px 5px 5px #bdc3c7;
    }
    
    
    .restart {
      background:#7F8C8D;
      color:#ecf0f1;
    }
    
    /* console */
    .board_console_container, .gameover_container {
        background-color: rgba(127, 140, 141, 0.7);
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        
         -webkit-user-select: none;  
         -moz-user-select: none;    
         -ms-user-select: none;      
         user-select: none;
    }
    
    .board_console {
        display:block;
        position:absolute;        
        width:50%;        
        color:white;
        background-color: rgba(127, 140, 141, 0.7);
        box-shadow: 0px 0px 5px 5px #bdc3c7;
    }
    
    .board_console .num {
        width:33.33%;    
        color:#2c3e50;    
        padding: 1px;
        display: inline-block;    
        font-weight:bold;
        font-size:24px;
        text-align: center;    
        cursor:pointer;
        
        -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    	    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    	    box-sizing: border-box;
        
        box-shadow: 0px 0px 0px 1px #bdc3c7;
    }
    
    
    .board_console .num:hover {
        color:white;
        background:#f1c40f;
    }
    
    .board_console .num.remove {
        width:66.66%;    
    }
    
    .board_console .num.note {
        background:#95a5a6;
        color:#ecf0f1;
    }
    
    .board_console .num.note:hover {
        background:#95a5a6;
        color:#f1c40f;
    }
    
    .board_console .num.selected {
        background:#f1c40f;
        box-shadow: 0px 0px 3px 3px #bdc3c7;
    }
    
    .board_console .num.note.selected {
        background:#f1c40f;  
        box-shadow: 0px 0px 3px 3px #bdc3c7;
    }
    
    .board_console .num.note.selected:hover {
      color:white;
    }
    
    .board_console .num.no:hover {
        color:white;
        cursor:not-allowed;
    }
    
    .board_console .num.remove:hover {
        color:white;
        background:#c0392b;
    }
    
    .statistics {
        text-align:center;    
    }
    
    #sudoku_menu {
        background-color: black;
        position: absolute;
        z-index:2;
        width: 100%;
        height: 100%;
        left: -100%;
        box-sizing: border-box;
        -moz-box-sizing: border-box;
    }
    
    #sudoku_menu ul {
       margin: 0;
       padding: 100px 0px 0px 0px;
       list-style: none;
    }
    
    #sudoku_menu ul li{
      margin: 0px 50px;
    }
    
    #sudoku_menu ul li a {
      text-align:center;
      padding: 15px 20px;
      font-size: 28px;
      font-weight: bold;
      color: white;
      text-decoration: none;
      display: block;
      border-bottom: 1px solid #2c3e50;
    }
    
    #sudoku_menu.open-sidebar {
      left:0px;
    }
    
    #sidebar-toggle {
        z-index:3;
        background: #bdc3c7;
        border-radius: 3px;
        display: block;
        position: relative;
        padding: 22px 18px;
        float: left;
    }
    
    #sidebar-toggle .bar{
        display: block;
        width: 28px;
        margin-bottom: 4px;
        height: 4px;
        background-color: #f0f0f0;
        border-radius: 1px;   
    }
    
    #sidebar-toggle .bar:last-child{
         margin-bottom: 0;   
    }
    
    /*Responsive Stuff*/
    
    @media all and (orientation:portrait) and (min-width: 640px){
        h1 { font-size:50px; }
        .statistics { font-size:30px; }    
        .sudoku_board .cell span { font-size:60px; }    
        .board_console .num { font-size:60px; }
    }
    
    @media all and (orientation:landscape) and (min-height: 640px){
        h1 { font-size:50px; }
        .statistics { font-size:30px; }
        .sudoku_board .cell span { font-size:50px; }
        .board_console .num { font-size:50px; }
    }
    
    @media all and (orientation:portrait) and (max-width: 1000px){
        .sudoku_board .cell span { font-size:30px; }   
    }
    
    @media all and (orientation:portrait) and (max-width: 640px){
    	.sudoku_board .cell span { font-size:24px; }
      .sudoku_board .cell .note { font-size:10px; }
    }
    
    @media all and (orientation:portrait) and (max-width: 470px){
    	.sudoku_board .cell span { font-size:16px; }
    .sudoku_board .cell .note { font-size:8px; }
    }
    
    @media all and (orientation:portrait) and (max-width: 320px){
    	.sudoku_board .cell span { font-size:12px; }
    .sudoku_board .cell .note { font-size:8px; }
    }
    
    @media all and (orientation:portrait) and  (max-width: 240px){
    	.sudoku_board .cell span { font-size:10px; }   
    }

    create a sudoku game in html css and js

    script.js

    
    /**
    Sudoku game by deepcrazyworld
    */
    function Sudoku(params) {
        var t = this;
      
        this.INIT = 0;
        this.RUNNING = 1;
        this.END = 2;
        
        this.id = params.id || 'sudoku_container';
        this.displaySolution = params.displaySolution || 0;
        this.displaySolutionOnly = params.displaySolutionOnly || 0;
        this.displayTitle = params.displayTitle || 0;
        this.highlight = params.highlight || 0;  
        this.fixCellsNr = params.fixCellsNr || 32;
        this.n = 3;    
        this.nn = this.n * this.n;      
        this.cellsNr = this.nn * this.nn;
        
        if (this.fixCellsNr < 10 ) this.fixCellsNr = 10;
        if (this.fixCellsNr > 70 ) this.fixCellsNr = 70;      
        
        this.init();
      
        //counter    
        setInterval(function(){
          t.timer();
        },1000);
              
        return this;
    }
    
    Sudoku.prototype.init = function() {    
        this.status = this.INIT;
        this.cellsComplete = 0;
        this.board = [];
        this.boardSolution = [];
        this.cell = null;
        this.markNotes = 0;  
        this.secondsElapsed = 0;
        
        if(this.displayTitle == 0) {
          $('#sudoku_title').hide();
        }
        
        this.board = this.boardGenerator(this.n, this.fixCellsNr);
        
        return this;
    };
    
    Sudoku.prototype.timer = function() {
      if (this.status === this.RUNNING) {
        this.secondsElapsed++;
        $('.time').text( '' + this.secondsElapsed );
      }
    };
    
    /**
    Shuffle array
    */
    Sudoku.prototype.shuffle = function(array) {
        var currentIndex   = array.length, 
            temporaryValue = 0,
            randomIndex = 0;        
        
        while (0 !== currentIndex) {
            randomIndex   = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;
            temporaryValue      = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex]  = temporaryValue;
         }
        
        return array;
    };
    
    /**
    Generate the sudoku board
    */
    Sudoku.prototype.boardGenerator = function(n, fixCellsNr) {
        var matrix_fields = [],
            index = 0,
            i = 0,
            j = 0,
            j_start = 0,
            j_stop = 0;
      
        //generate solution
        this.boardSolution = [];
      
        //shuffle matrix indexes
        for (i = 0; i < this.nn; i++) {
            matrix_fields[i] = i+1;
        }  
        
        //shuffle sudoku 'collors'
        matrix_fields = this.shuffle(matrix_fields);
        for (i = 0; i < n*n; i++) {
            for (j = 0; j < n*n; j++) {
                var value = Math.floor( (i*n + i/n + j) % (n*n) + 1 );            
                this.boardSolution[index] = value;
                index++;
            }
        }
        
        //shuffle sudokus indexes of bands on horizontal and vertical
        var blank_indexes = [];    
        for (i = 0; i < this.n; i++) {
            blank_indexes[i] = i+1;        
        }
      
        
        //shuffle sudokus bands horizontal
        var bands_horizontal_indexes = this.shuffle(blank_indexes);
        var board_solution_tmp = [];
        index = 0;
        for (i = 0; i < bands_horizontal_indexes.length; i++) {
            j_start = (bands_horizontal_indexes[i] -1) * this.n * this.nn;
            j_stop  = bands_horizontal_indexes[i] * this.n * this.nn;
            
            for( j = j_start; j < j_stop; j++ ) {
              board_solution_tmp[index] = this.boardSolution[j];
              index++;
            }
        }
        this.boardSolution = board_solution_tmp;
        
        
        //shuffle sudokus bands vertical
        var bands_vertical_indexes   = this.shuffle(blank_indexes);
        board_solution_tmp = [];
        index = 0;    
        for (k = 0; k < this.nn; k++) {      
          for (i = 0; i < this.n; i++) {      
            j_start = (bands_vertical_indexes[i]-1) * this.n;
            j_stop  = bands_vertical_indexes[i] * this.n;
          
            for( j = j_start; j < j_stop; j++ ) {
              board_solution_tmp[index] = this.boardSolution[j + (k*this.nn)];
              index++;
            }
          }
        }
        this.boardSolution = board_solution_tmp;
        
        //shuffle sudokus lines on each bands horizontal
        //TO DO
      
        //shuffle sudokus columns on each bands vertical
        //TO DO
        
        //board init
        var board_indexes =[],
            board_init = [];
      
        //shuffle board indexes and cut empty cells    
        for (i=0; i < this.boardSolution.length; i++) {
            board_indexes[i] = i;
            board_init[i] = 0;
        }
        
        board_indexes = this.shuffle(board_indexes);
        board_indexes = board_indexes.slice(0, this.fixCellsNr);
        
        //build the init board    
        for (i=0; i< board_indexes.length; i++) {
            board_init[ board_indexes[i] ] = this.boardSolution[ board_indexes[i] ];
            if (parseInt(board_init[ board_indexes[i] ]) > 0) {
              this.cellsComplete++;
            }
        }
        
        return (this.displaySolutionOnly) ? this.boardSolution : board_init;    
    };
    
    /**
    Draw sudoku board in the specified container
    */
    Sudoku.prototype.drawBoard = function(){
        var index = 0,
            position       = { x: 0, y: 0 },
            group_position = { x: 0, y: 0 };
        
        var sudoku_board = $('<div></div>').addClass('sudoku_board');
        var sudoku_statistics = $('<div></div>')
                                    .addClass('statistics')
        .html('<b>Cells:</b> <span class="cells_complete">'+ this.cellsComplete +'/'+this.cellsNr +'</span> <b>Time:</b> <span class="time">' + this.secondsElapsed + '</span>');
        
        $('#'+ this.id).empty();
        
        //draw board 
        for (i=0; i < this.nn; i++) {
            for (j=0; j < this.nn; j++) {
                position       = { x: i+1, y: j+1 };
                group_position = { x: Math.floor((position.x -1)/this.n), y: Math.floor((position.y-1)/this.n) };
                
                var value = (this.board[index] > 0 ? this.board[index] : ''),
                    value_solution = (this.boardSolution[index] > 0 ? this.boardSolution[index] : ''),
                    cell = $('<div></div>')
                                .addClass('cell')
                                .attr('x', position.x)
                                .attr('y', position.y)
                                .attr('gr', group_position.x +''+ group_position.y)
                                .html('<span>'+ value +'</span>' );
              
                if (this.displaySolution) {
                   $('<span class="solution">('+ value_solution +')</span>').appendTo(cell);
                }
              
                if ( value > 0) {
                    cell.addClass('fix');
                }
                
                if ( position.x % this.n === 0 && position.x != this.nn ) {
                    cell.addClass('border_h');
                }
                
                if ( position.y % this.n === 0 && position.y != this.nn ) {
                    cell.addClass('border_v');
                }
                
                cell.appendTo(sudoku_board);
                index++;
            }
        }
        
        sudoku_board.appendTo('#'+ this.id);
        
        //draw console
        var sudoku_console_cotainer = $('<div></div>').addClass('board_console_container');
        var sudoku_console = $('<div></div>').addClass('board_console');
        
        for (i=1; i <= this.nn; i++) {
            $('<div></div>').addClass('num').text(i).appendTo(sudoku_console);
        }
        $('<div></div>').addClass('num remove').text('X').appendTo(sudoku_console);
        $('<div></div>').addClass('num note').text('?').appendTo(sudoku_console);
        
        //draw gameover
        var sudoku_gameover = $('<div class="gameover_container"><div class="gameover">Congratulation! <button class="restart">Play Again</button></div></div>');
        
        //add all to sudoku container
        sudoku_console_cotainer.appendTo('#'+ this.id).hide();
        sudoku_console.appendTo(sudoku_console_cotainer);    
        sudoku_statistics.appendTo('#'+ this.id);
        sudoku_gameover.appendTo('#'+ this.id).hide();  
      
        //adjust size
        this.resizeWindow();
    };
    
    Sudoku.prototype.resizeWindow = function(){
        console.time("resizeWindow");
        
        var screen = { w: $(window).width(), h: $(window).height() };
        
        //adjust the board
        var b_pos = $('#'+ this.id +' .sudoku_board').offset(),
            b_dim = { w: $('#'+ this.id +' .sudoku_board').width(),  h: $('#'+ this.id +' .sudoku_board').height() },
            s_dim = { w: $('#'+ this.id +' .statistics').width(),    h: $('#'+ this.id +' .statistics').height()   };
        
        var screen_wr = screen.w + s_dim.h + b_pos.top + 10;
      
        if (screen_wr > screen.h) {
            $('#'+ this.id +' .sudoku_board').css('width', (screen.h - b_pos.top - s_dim.h - 14) );
            $('#'+ this.id +' .board_console').css('width', (b_dim.h/2) );
        } else {
            $('#'+ this.id +' .sudoku_board').css('width', '98%' );
            $('#'+ this.id +' .board_console').css('width', '50%' );
        }
        
        var cell_width = $('#'+ this.id +' .sudoku_board .cell:first').width(),
            note_with  = Math.floor(cell_width/2) -1;
      
        $('#'+ this.id +' .sudoku_board .cell').height(cell_width);
        $('#'+ this.id +' .sudoku_board .cell span').css('line-height', cell_width+'px');    
        $('#'+ this.id +' .sudoku_board .cell .note').css({'line-height': note_with+'px' ,'width' : note_with, 'height': note_with});
        
        //adjust the console
        var console_cell_width = $('#'+ this.id +' .board_console .num:first').width();
        $('#'+ this.id +' .board_console .num').css('height', console_cell_width);
        $('#'+ this.id +' .board_console .num').css('line-height', console_cell_width+'px');
        
        //adjust console
        b_dim = { w: $('#'+ this.id +' .sudoku_board').width(),  h: $('#'+ this.id +' .sudoku_board').width() };
        b_pos = $('#'+ this.id +' .sudoku_board').offset();
        c_dim = { w: $('#'+ this.id +' .board_console').width(), h: $('#'+ this.id +' .board_console').height() };
        
        var c_pos_new = { left : ( b_dim.w/2 - c_dim.w/2 + b_pos.left ), top  : ( b_dim.h/2 - c_dim.h/2 + b_pos.top ) };    
        $('#'+ this.id +' .board_console').css({'left': c_pos_new.left, 'top': c_pos_new.top});
        
        //adjust the gameover container
        var gameover_pos_new = { left : ( screen.w/20 ), top  : ( screen.w/20 + b_pos.top ) };    
        
        $('#'+ this.id +' .gameover').css({'left': gameover_pos_new.left, 'top': gameover_pos_new.top});    
        
        console.log('screen', screen);    
        console.timeEnd("resizeWindow");
    };
    
    /**
    Show console
    */
    Sudoku.prototype.showConsole = function(cell) {
      $('#'+ this.id +' .board_console_container').show();
      
      var 
        t = this,
        oldNotes = $(this.cell).find('.note');
      
      //init
      $('#'+ t.id +' .board_console .num').removeClass('selected');
        
      //mark buttons
      if(t.markNotes) {
        //select markNote button  
        $('#'+ t.id +' .board_console .num.note').addClass('selected');
      
        //select buttons
        $.each(oldNotes, function() {
          var noteNum = $(this).text();
          $('#'+ t.id +' .board_console .num:contains('+ noteNum +')').addClass('selected');
        });  
      }
      
      return this;
    };
    
    /**
    Hide console
    */
    Sudoku.prototype.hideConsole = function(cell) {
      $('#'+ this.id +' .board_console_container').hide();
      return this;
    };
    
    /**
    Select cell and prepare it for input from sudoku board console
    */
    Sudoku.prototype.cellSelect = function(cell){    
        this.cell = cell;
        
        var value = $(cell).text() | 0,
            position       = { x: $(cell).attr('x'), y: $(cell).attr('y') } ,
            group_position = { x: Math.floor((position.x -1)/3), y: Math.floor((position.y-1)/3) },
            horizontal_cells = $('#'+ this.id +' .sudoku_board .cell[x="'+ position.x +'"]'),
            vertical_cells   = $('#'+ this.id +' .sudoku_board .cell[y="'+ position.y +'"]'),
            group_cells      = $('#'+ this.id +' .sudoku_board .cell[gr="'+ group_position.x +''+ group_position.y +'"]'),
            same_value_cells = $('#'+ this.id +' .sudoku_board .cell span:contains('+value+')');
        
        //remove all other selections
        $('#'+ this.id +' .sudoku_board .cell').removeClass('selected current group');
        $('#'+ this.id +' .sudoku_board .cell span').removeClass('samevalue');
        //select current cell
        $(cell).addClass('selected current');
        
        //highlight select cells
        if (this.highlight > 0) {        
            horizontal_cells.addClass('selected');
            vertical_cells.addClass('selected');
            group_cells.addClass('selected group');
            same_value_cells.not( $(cell).find('span') ).addClass('samevalue');
        }
        
        if ($( this.cell ).hasClass('fix')) {
            $('#'+ this.id +' .board_console .num').addClass('no');
        } else {
            $('#'+ this.id +' .board_console .num').removeClass('no');
            
            this.showConsole();
            this.resizeWindow();
        }    
    };
    
    /**
    Add value from sudoku console to selected board cell
    */
    Sudoku.prototype.addValue = function(value) {
        console.log('prepare for addValue', value);
        
        var    
            position       = { x: $(this.cell).attr('x'), y: $(this.cell).attr('y') },        
            group_position = { x: Math.floor((position.x -1)/3), y: Math.floor((position.y-1)/3) },
            
            horizontal_cells = '#'+ this.id +' .sudoku_board .cell[x="'+ position.x +'"]',
            vertical_cells   = '#'+ this.id +' .sudoku_board .cell[y="'+ position.y +'"]',
            group_cells      = '#'+ this.id +' .sudoku_board .cell[gr="'+ group_position.x +''+ group_position.y +'"]',
              
            horizontal_cells_exists = $(horizontal_cells + ' span:contains('+ value +')'),
            vertical_cells_exists   = $(vertical_cells + ' span:contains('+ value +')'),
            group_cells_exists      = $(group_cells + ' span:contains('+ value +')'),
            
            horizontal_notes = horizontal_cells + ' .note:contains('+ value +')',
            vertical_notes   = vertical_cells + ' .note:contains('+ value +')',
            group_notes      = group_cells + ' .note:contains('+ value +')',
              
            old_value = parseInt($( this.cell ).not('.notvalid').text()) || 0;
          
      
        if ($( this.cell ).hasClass('fix')) {
            return;
        }        
      
        //delete value or write it in cell
        $( this.cell ).find('span').text( (value === 0) ? '' : value );
            
        if ( this.cell !== null && ( horizontal_cells_exists.length || vertical_cells_exists.length || group_cells_exists.length ) ) {
            if (old_value !== value) {
                $( this.cell ).addClass('notvalid');            
            } else {            
                $(this.cell).find('span').text('');            
            }
        } else {
            //add value
            $(this.cell).removeClass('notvalid');        
            console.log('Value added ', value); 
          
            //remove all notes from current cell,  line column and group
            $(horizontal_notes).remove();
            $(vertical_notes).remove();
            $(group_notes).remove();      
        }
        
        //recalculate completed cells
        this.cellsComplete = $('#'+ this.id +' .sudoku_board .cell:not(.notvalid) span:not(:empty)').length;
        console.log('is game over? ', this.cellsComplete, this.cellsNr, (this.cellsComplete === this.cellsNr) );
        //game over
        if (this.cellsComplete === this.cellsNr) {
            this.gameOver();
        }
          
        $('#'+ this.id +' .statistics .cells_complete').text(''+this.cellsComplete+'/'+this.cellsNr);  
        
        return this;
    };
    
    
    /**
    Add note from sudoku console to selected board cell
    */
    Sudoku.prototype.addNote = function(value) {
      console.log('addNote', value);
     
      var 
        t = this,
        oldNotes = $(t.cell).find('.note'),
        note_width = Math.floor($(t.cell).width() / 2);
      
      //add note to cell
      if (oldNotes.length < 4) {
        $('<div></div>')
            .addClass('note')
            .css({'line-height' : note_width+'px', 'height': note_width -1, 'width': note_width -1})
            .text(value)
            .appendTo( this.cell );    
      }
      
      return this;
    };
    
    /**
    Remove note from sudoku console to selected board cell
    */
    Sudoku.prototype.removeNote = function(value) {
      if (value === 0) {    
          $(this.cell).find('.note').remove();
      } else {    
          $(this.cell).find('.note:contains('+value+')').remove();        
      }
      
      return this;
    };
    
    /**
    End game routine
    */
    Sudoku.prototype.gameOver = function(){
        console.log('GAME OVER!');  
        this.status = this.END;   
      
        $('#'+ this.id +' .gameover_container').show();
    };
    
    /**
    Run a new sudoku game
    */
    Sudoku.prototype.run = function(){
        this.status = this.RUNNING;
      
        var t = this;
        this.drawBoard();
        
        //click on board cell
        $('#'+ this.id +' .sudoku_board .cell').on('click', function(e){
            t.cellSelect(this);
        });
        
        //click on console num
        $('#'+ this.id +' .board_console .num').on('click', function(e){
            var 
                value          = $.isNumeric($(this).text()) ? parseInt($(this).text()) : 0,
                clickMarkNotes = $(this).hasClass('note'),
                clickRemove = $(this).hasClass('remove'),
                numSelected    = $(this).hasClass('selected');
                    
            if (clickMarkNotes) {
                console.log('clickMarkNotes');
                t.markNotes = !t.markNotes;
                
                if(t.markNotes) { 
                    $(this).addClass('selected'); 
                } else { 
                    $(this).removeClass('selected');
                    t.removeNote(0).showConsole();
                }
            
            } else {
                if (t.markNotes) {
                    if (!numSelected) {
                        if (!value) {
                            t.removeNote(0).hideConsole();
                        } else {
                            t.addValue(0).addNote(value).hideConsole();
                        }
                    } else {
                        t.removeNote(value).hideConsole();
                    }
                } else {
                    t.removeNote(0).addValue(value).hideConsole();
                }
            }        
        });
        
        //click outer console
        $('#'+ this.id +' .board_console_container').on('click', function(e){        
            if ( $(e.target).is('.board_console_container') ) {
                $(this).hide();
            }                
        });
        
        $( window ).resize(function() {
            t.resizeWindow();
        });
    };
    
    //main
    $(function() {
        console.time("loading time");    
        
        //init        
        $('head').append('<meta name="viewport" content="initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,width=device-width,height=device-height,target-densitydpi=device-dpi,user-scalable=yes" />');
        
        //game  
        var game = new Sudoku({ 
                        id: 'sudoku_container',                    
                        fixCellsNr: 30,
                        highlight : 1,
                        displayTitle : 1,
                        //displaySolution: 1,
                        //displaySolutionOnly: 1,
                   });
        
        game.run();
      
        $('#sidebar-toggle').on('click', function(e){
          $('#sudoku_menu').toggleClass("open-sidebar");
        });
      
         //restart game
        $('#'+ game.id +' .restart').on('click', function(){
            game.init().run();
        });
      
        $('#sudoku_menu .restart').on('click', function(){
            game.init().run();
            $('#sudoku_menu').removeClass('open-sidebar');
        });
        
        console.timeEnd("loading time");
    });

    YouTube Video

    And this can be continued for as many iterations as one likes, shuffling random rows and columns from a random group, resulting in a pseudo-random puzzle. I am still waiting for the day when I solve a puzzle and the result is the first puzzle above: not sure I would even notice until it is close to being solved.

    Don’t forget to share this post!

    READ MORE

    Share. Facebook Twitter LinkedIn WhatsApp Telegram Pinterest Reddit Email
    Previous ArticleSudoku : How to Create a Sudoku Puzzle game with Html
    Next Article How To Create YouTube Android App In Android Studio (Step By Step)

    Related Posts

    Top 20 Amazing Websites जिनके बारे में आपको जानना चाहिए 2023

    Web Developer 4 Mins Read

    Top 5 Beginner’s Guide: How To Learn Web Design At Home 2023

    Web Developer 12 Mins Read

    Model View Controller Pattern – MVC Architecture & Frameworks(updated)

    Web Developer 6 Mins Read

    Unable to load class ‘javax.xml.bind.JAXBException’

    Web Developer 3 Mins Read

    Leave A Reply Cancel Reply

    Recent Posts
    • Implementing a Dynamic FAQ Screen UI in Flutter Using ExpansionTile March 29, 2025
    • Creating an Instruction UI Screen in Flutter Application March 29, 2025
    • Animated Backgrounds in Flutter: A Complete Guide March 15, 2025
    • How to make Diary App using flutter stepwise using getx August 31, 2024
    • How to Create Music Player UI screen with fully functional in flutter August 30, 2024
    • How to make ListView Builder Ui in flutter with Source Code August 29, 2024
    • Create a TabBar View in flutter with fully functional stepwise August 28, 2024
    • How to create TabBar view in flutter with source code step wise August 27, 2024
    • How to make Heart rate measure app with Flutter stepwise August 26, 2024
    • How to make ChatGpt App in flutter with source code Stepwise August 25, 2024
    Facebook Twitter Instagram Pinterest YouTube
    • About
    • Contact
    • Disclaimer
    • Privacy Policy
    Copyright by DeepCrazyWorld © 2025

    Type above and press Enter to search. Press Esc to cancel.