Executando verificação de segurança...
12

PITCH: Sudoku: Um jogo feito em JavaScript

Hello guys, hoje eu vou mostrar um projeto pessoal que estou desenvolvendo usando JavaScript, que básicamente é a recriação do jogo sudoku.

Algoritmo de geração do tabuleiro

Como o projeto tá bem no inicio, hojé ele só esta gerando o tabuleiro de forma randômico, como mostra o gif baixo.


> link para o github page

como o algoritmo funciona?

para começar, eu dividir a explicação em 5 partes.

1° O algoritmo começa gerando de forma aleatória um número e uma posição que vai de [0, 80].

    DrawNumberAndPosition: function(){ // sortear os números para o square
        let position = Math.floor(Math.random() * ((width * hight) - 1) + 1) // gerar a posição aonde o elemento vai ficar na lista
        let element  = Math.floor(Math.random() * (10 - 1) + 1) // sortear os números

        return [position, element]
    },

2° Então é verificado se já existe o número na mesma linha e coluna através de duas funcão checkColumnValues e checkRowValues que retorna true ou false.

     // verificar se tem número repetido na mesma coluna
        const checkColumnValues = (position, values) => {

            let rowIndex    = parseInt(position / 9)           // calcular a linha apartir do index
            let columnIndex = position - (width * rowIndex) // calculo para determinar em qual coluna deve começar a peger os valores

            //pegar os valores da coluna e adicionar em um array de verificação
            for(let row=0; row<hight; row++){
                let index = columnIndex + (width * row)
                if(this.board[index] == values) return true
            }
            
            return false
        }


        //verifcar se tem número repetido na mesma linha
        const checkRowValues = (position, values) => {

            let rowIndex = parseInt(position / 9) // calcular o index da linha apartir da posição

            // pegar todos os valores da linha e colocar no array de verificação
            for(let column=0; column<width; column++){
                let index = column + (width * rowIndex)
                if(this.board[index] == values) return true
            }

            return false
        }

Mas existe um bug com esse tipo de geração, como mostra a imagem abaixo.

O algoritomo não consegue saber se já tem um número já existentes no quadrado.

3° para resolver esse problema com número repetidos no mesmo quadrado, eu bolei uma função que verifica quada quadrado do tabuleiro de acordo com a posição gerada.

       const checkSquareElements = (position, values) => {

            // sequência em que vai ser verificado se o index (posição aonde o n° vai ser colocado) 
            // em qual área (quadrado do sudoku) ele pertenci
            const areaSequence = [
                [2,2],
                [2,5],
                [2,8],
                [5,2],
                [5,5],
                [5,8],
                [8,2],
                [8,5],
                [8,8],
            ]

            //verificar a sequência da área (quadrado do sudoku)
            const checkSequence = () => {
                for(let i=0; i<areaSequence.length; i++){
                    if(rowIndex <= areaSequence[i][0] && columnIndex <= areaSequence[i][1]){
                        return i + 1
                    }
                }
            }

            let loadColumnValues = []                       // memoria que vai carregar os elementos para verificação
            let rowIndex    = parseInt(position / 9)        // calcular a posição da linha apartir do index
            let columnIndex = position - (width * rowIndex) // calcular a posição da coluna apartir do index


            switch(checkSequence()){
                case 1:
                    for(let column=0; column<3; column++){
                        for(let row=0; row<3; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 2:
                    for(let column=3; column<6; column++){
                        for(let row=0; row<3; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;
                
                case 3:
                    for(let column=6; column<9; column++){
                        for(let row=0; row<3; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 4:
                    for(let column=0; column<3; column++){
                        for(let row=3; row<6; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 5:
                    for(let column=3; column<6; column++){
                        for(let row=3; row<6; row++){
                            let index = column + (9 * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 6:
                    for(let column=6; column<9; column++){
                        for(let row=3; row<6; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 7:
                    for(let column=0; column<3; column++){
                        for(let row=6; row<9; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 8:
                    for(let column=3; column<6; column++){
                        for(let row=6; row<9; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 9:
                    for(let column=6; column<9; column++){
                        for(let row=6; row<9; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;
            }   

            return loadColumnValues.includes(`${values}`) // verificar se tem número repetidos e retonar um [true] ou [false] como resposta

        }
  • Na primeira parte eu criei um vetor que guarda os valores da coluna e da linha, com esse dados no vetor é possível pegar a posição do ultimo index de quada quadrado.
    const areaSequence = [
                [2,2],
                [2,5],
                [2,8],
                [5,2],
                [5,5],
                [5,8],
                [8,2],
                [8,5],
                [8,8],
            ]
  • Com isso, através da posição gerada é calculado em qual linha e coluna um elemento X vai está.
 let rowIndex    = parseInt(position / 9)        // calcular a posição da linha apartir do index
 let columnIndex = position - (width * rowIndex) // calcular a posição da coluna apartir do index
  • Para saber em qual quadrado o número tá, a função checkSequence vai pegar as variáveis rowIndex e columnIndex vai verificar se o valor é menor do que uns dos valores do vetor e retorna o número do quadrado.
    const checkSequence = () => {
                for(let i=0; i<areaSequence.length; i++){
                    if(rowIndex <= areaSequence[i][0] && columnIndex <= areaSequence[i][1]){
                        return i + 1
                    }
                }
            }
  • agora é só verificar em um switch case o retorno da função, pegar todos os elementos do quadrado selecionado, salvar em um array e verificar se já existe um número parecido e retornar como true e false.
    switch(checkSequence()){
                case 1:
                    for(let column=0; column<3; column++){
                        for(let row=0; row<3; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 2:
                    for(let column=3; column<6; column++){
                        for(let row=0; row<3; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;
                
                .
                .
                .

                case 8:
                    for(let column=3; column<6; column++){
                        for(let row=6; row<9; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;

                case 9:
                    for(let column=6; column<9; column++){
                        for(let row=6; row<9; row++){
                            let index = column + (width * row)
                            loadColumnValues.push(this.board[index])
                        }
                    }
                break;
            }   

            return loadColumnValues.includes(`${values}`) // verificar se tem número repetidos e retonar um [true] ou [false] como resposta

4° agora é só verificar as funções se o retorno é igual a false. Se todas as funções retornar false é colocado no board o nũmero gerado.

//verificar se pode adicionar os números no tabuleiro
if(!checkColumnValues(position,element) && !checkRowValues(position, element) && !checkSquareElements(position,element)){
       this.board[position] = `${element}`
       i++
 }

5° Para determinar o limite de números gerado no tabuleiro.

    if(i >= (81 - 36)break 

❗ Esse projeto ainda está em desenvolvimento, ainde tem mais coisas para ser implementado!

Carregando publicação patrocinada...