1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Sudoku. Como gerar números?

Discussão em 'Programação' iniciada por Keith, 30 de Julho de 2007. (Respostas: 11; Visualizações: 5413)

  1. Keith

    Keith Power Member

    Boas.

    Tal como o título diz, estou com dificuldade em gerar números para os tabuleiros de 9x9, tais como os clássicos de Sudoku.

    Já experimentei vários métodos, como tentar gerar apenas os números para uma linha de cada vez, ou para cada um dos 9 quadrados em que se divide o tabuleiro.

    Alguém pode sugerir alguma coisa? Já agora a linguagem é C.

    Vou continuar a tentar. Se alguém conseguir alguma coisa, por favor diga.

    Obrigado,
    Keith
     
  2. HecKel

    HecKel The WORM

    Gerar como assim? Criar os mapas ou preencher um mapa já feito?

    HecKel
     
  3. Keith

    Keith Power Member

    Quero criar um quadro completo. Não estou preocupado em deixar elementos vazios, tal como aparece num puzzle de Sudoku.

    Quero apenas que cada linha e cada coluna tenha os números de 1 a 9 (sem repetições). O quadro tem que respeitar regras do Sudoku.

    Espero ter-me feito entender.

    Keith
     
  4. alfinete

    alfinete Power Member

  5. alfinete

    alfinete Power Member

    pesso desulpa por em c não ter nada , mas tens aqui outra opção em java

    esta mostra os numeros que estão visiveis ao utilizador

    Código:
     private boolean placeNumber(int number, int occurrence) {
            // If 9 occurences are always placed, continue with the next number
            if (occurrence > 9) {
                number++;
                occurrence = 1;
            }
            if (number <= 9) {
                // Get valid places
                int[] validPlaces = getValidePlacesInColumn(occurrence - 1, number);
                // Try each place in order until finding the good one
                for (int i = 0; i < validPlaces.length; i++) {
                    int col = validPlaces[i] % 9;
                    int row = validPlaces[i] / 9;
                    sudokuCells[col][row] = -number;
                    // Place the next occurence or number
                    if (placeNumber(number, occurrence + 1)) {
                        // The Sudoku is solvable
                        return true;
                    } else {
                        // The Sudoku is not solvable
                        // Try with the next valide place
                        sudokuCells[col][row] = 0;
                    }
                }
                return false;
            }
            return true;
        }
    
    
    
    esta calcula nos numeros escondidos, que o jogador não vê

    Código:
     private void hideNumbers() {
            int[] locations = new int[81];
            for (int i = 0; i < locations.length; i++) {
                locations[i] = i;
            }
            scramblePlaces(locations, 81);
            int revealed = 81;
            int maxRevealed = 28 + (5 - level) * 5;
            for (int i = 0; i < locations.length && revealed >= maxRevealed; i++) {
                // Randomize column and row
                int col = locations[i] % 9;
                int row = locations[i] / 9;
                // If the cell number is revealed...
                if (sudokuCells[col][row] < 0) {
                    // Hide the cell number and apply a central symmetry
                    int value1 = sudokuCells[col][row];
                    int value2 = sudokuCells[8 - col][8 - row];
                    sudokuCells[col][row] = 0;
                    sudokuCells[8 - col][8 - row] = 0;
                    if (col != row || col != 4) {
                        // Ensure central symmetry
                        revealed -= 2;
                    } else {
                        // Central point
                        revealed--;
                    }
                    // Verify the solution unicity
                    if (!hasSingleSolution(col, row)) {
                        // Reveal the sudokuCells numbers
                        sudokuCells[col][row] = value1;
                        sudokuCells[8 - col][8 - row] = value2;
                        if (col != row || col != 4) {
                            // Ensure central symmetry
                            revealed += 2;
                        } else {
                            // Central point
                            revealed++;
                        }
                        // and try another sudokuCells group
                    }
                }
            }
        }
    
    
    não meperguntes como isto funciona, mas eu tirei de um jogo de um colega, feito em java, pois tb não percebo muito de java

    epero que estas duas dicas ajudem
     
  6. HecKel

    HecKel The WORM

    Boas!

    As restrições vais ter sempre de as aplicar, cria o conjunto de regras, e cria uma função para tratar de preencher o quadro, vai percorrendo cada casa livre e gera um valor aleatório para o mesmo, depois verifica se ele passa nas restrições.

    Faz isto recursivamente, no entanto tens um senão, é que podes estar a partir da solução errada, se chegares a um beco sem saída terás de voltar alguns passos atrás e experimentar outro caminho.

    O código não te vou fazer nem vou dar, mas aqui ficam estas dicas, espero que te ajudem ;)

    HecKel
     
  7. Keith

    Keith Power Member

    Obrigado.

    O meu intuito, quando abri este tópico, não era pedir código; gostava apenas que me mostrassem uma forma de proceder, para resolver o problema em questão.

    Agradeço ao pessoal que colocou código disponível, não era preciso tanto.

    Obrigado,
    Keith
     
  8. Keith

    Keith Power Member

    Criei algumas funções auxiliares para ajudar a gerar os números do tabuleiro:

    - int Sdk_CheckRow (int N, int R) -> devolve 1 se N não está na linha R; 0 caso contrário
    - int Sdk_CheckCol (int N, int C) -> devolve 1 se N não está na coluna C; 0 caso contrário
    - int Sdk_CheckSquare (int N, int S) -> devolve 1 se N não está no quadrado actual; 0 caso contrário
    - int Sdk_Square (int R, int C) -> dada linha R e coluna C diz qual é o quadrado a que estas coordenadas pertencem

    A função que estou a usar para gerar os números do tabuleiro é a seguinte:

    Código:
    void Sdk_Fill ()
    {
    int R, C, N, S, T = 0;
    
       R = rand() % 9;
       C = rand() % 9;
       S = Sdk_Square(R,C);
       N = 1 + (rand() % 9);
    
       if (T > 81) return;
    
       if ((TabSdk[R][C] != 0))
       {
          if ((!Sdk_CheckRow(N,R)) && (!Sdk_CheckCol(N,C)) && (!Sdk_CheckSquare(N,S))) { TabSdk[R][C] = N; T++; }
       }
    
       else Sdk_Fill();
    }
    
    Mas entra em ciclo e não vejo nada do resultado...

    Alguém me pode ajudar?

    Obrigado,
    Keith
     
  9. AragTey

    AragTey Power Member

    Epa assim de repente parece-me que estas ai depedente de demasiados random.....é quase como acertar no euromilhoes fazeres com que esses randoms devoltam os numeros que vai precisando para completar a linha, coluna ou quadrado.
     
  10. Keith

    Keith Power Member

    Pois...

    Como proceder?
     
  11. Reptil

    Reptil Power Member

    Talvez fazer um unico random de 1-9 a cada vez,confirmas se exe numero que sai ainda nao foi colocado naquela linha ou naquele quadrado(2funçoes auxiliares),e se derem resultado que ainda não voi colocado,tudo bem.Fazes isso dentro de um ciclo while.Enquanto nao preencheres aquela "peça" com um numero,continuas a repetir o que eu ecrevi em cima.
     
  12. wack

    wack Power Member

Partilhar esta Página