Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Risolvi Sudoku 1.1 - Risolvi Sudoku 1.1.c

Risolvi Sudoku 1.1.c

Caricato da: Zani88
Scarica il programma completo

  1. // nome prrogramma : Risolvi Sudoku
  2. // creatore : Davide Zanin - Zani88
  3. // versione : 1.1
  4. // data di creazione : 11-06-06
  5. // ultima modifica : 18-06-06
  6. // Programma che permette la risoluzione di Sudoku anche complessi
  7. //
  8. // il programma è liberamente modificale e pubblicabile a patto che venga
  9. // sempre indicato il mio nome tra i creatori.
  10. // Per problemi, errori o miglioramenti contattami davidezanin@gmail.com
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <time.h>
  15. #include <windows.h>
  16.  
  17. // per ora vengono gestiti solo sudoku 9x9 in futuro anche 16x16
  18. #define n 9
  19.  
  20. // funzione che implementa la GotoXY per compilatori non Borland
  21. // realizzata da cH!cus disponibile anche sul sito http://www.pierotofy.it/
  22. void GotoXY(int x, int y) {
  23.  COORD CursorPos = {x, y};
  24.  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  25.  SetConsoleCursorPosition(hConsole, CursorPos);
  26. }
  27.  
  28. // Funzione che restituisce il puntatore all'area di memoria riservata alla
  29. // matrice nXn di int
  30. int **AllocaMatrice(){
  31.  
  32.  int i,**m;
  33.  
  34.  m = (int **)malloc(n*sizeof(int *));
  35.  for( i = 0; i < n; i++)
  36.   m[i] = (int *)malloc(n*sizeof(int));
  37.  
  38.  return(m);
  39. }
  40.  
  41.  
  42. // funzione che restituisce il numero del primo elemento del riquadro che fà
  43. // parte x
  44. void Riquadro(int *x){
  45.  
  46.   switch (*x){
  47.   case 0 : *x = 0;
  48.            break;
  49.   case 1 : *x = 0;
  50.            break;
  51.   case 2 : *x = 0;
  52.            break;
  53.   case 3 : *x = 3;
  54.            break;
  55.   case 4 : *x = 3;
  56.            break;
  57.   case 5 : *x = 3;
  58.            break;
  59.   case 6 : *x = 6;
  60.            break;
  61.   case 7 : *x = 6;
  62.            break;
  63.   case 8 : *x = 6;
  64.  }
  65. }
  66.  
  67.  
  68. // Funzione che restituisce 1 se num non può essere inserito nella posizione
  69. // del sudoku r,c altrimenti restituisce 0
  70. int Esiste(int **S, int num, int r, int c){
  71.  
  72.  int i,j;
  73.  
  74.  // ciclo che controlla se num è presente nella riga r o nella colonna c
  75.  for(i = 0; i < n; i++)
  76.   if((num == S[r][i])||(num == S[i][c])) return(1);
  77.  
  78.  // r e c vengono modificati in modo da contenere la psizione del primo riquadro
  79.  // a cui appartengono
  80.  Riquadro(&r);
  81.  Riquadro(&c);
  82.  
  83.  // ciclo che controlla se num esiste già nel riquadro corrente
  84.  for(i = r; i < r+3; i++)
  85.   for(j = c; j < c+3; j++)
  86.    if(S[i][j]==num) return(1);
  87.  
  88.  return(0);
  89. }
  90.  
  91. // Funzione che legge da tastiera un sudoku
  92. int **LeggiSudokuDaTastiera(){
  93.  
  94.  int **S;
  95.  int i,j,x,y;
  96.  
  97.  S = AllocaMatrice();
  98.  
  99.  system("CLS");
  100.  printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  101.  printf("\n Inserisci il Sudoku (0 per lo spazio vuoto)\n\n");
  102.  
  103.  y = 5;
  104.  
  105.  for(i = 0; i < n; i++){
  106.   x = 2;
  107.   for(j = 0; j< n; j++){
  108.    GotoXY(x,y);
  109.    S[i][j] = (int)getch()-48;
  110.    GotoXY(x,y);
  111.    printf("%d",S[i][j]);
  112.    x += 2;
  113.    if(((j+1)%3 == 0)&&((j+1) != 9)){
  114.     GotoXY(x,y);
  115.     printf("|");
  116.     x += 2;
  117.    }
  118.   }
  119.   y++;
  120.   if(((i+1)%3 == 0)&&((i+1) != 9)){
  121.      GotoXY(2,y);
  122.      printf("---------------------\n");
  123.      y++;
  124.   }
  125.  }
  126.  printf("\n");
  127.  
  128.  return(S);
  129. }
  130.  
  131. // Funzione che legge il sudoku dal file "Archivio.dat" e restituisce il puntatore
  132. // alla matrice appena caricati dal file
  133. int **CaricaSudokuDaFile(){
  134.  
  135.  FILE *Archivio;
  136.  int **S,i,j;
  137.  char fine[1];
  138.  
  139.  // apertura del file
  140.  Archivio = fopen("Archivio.dat","r");
  141.  
  142.  if(Archivio == NULL){
  143.   system("CLS");
  144.   printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  145.   printf("\n Il file Archivio.dat non esiste\n");
  146.   printf("\n Premi un tasto per terminare \n ");
  147.  
  148.   getch();
  149.   exit(1);
  150.  }
  151.  
  152.  // allocazione della matrice
  153.  S = AllocaMatrice();              
  154.  
  155.  // lettura dei dati dal file
  156.  for(i = 0; i < n; i++){            
  157.   for(j = 0; j < n; j++){
  158.    fscanf(Archivio,"%d ",&S[i][j]);                      
  159.   }                            
  160.  }
  161.  
  162.  // chiusura del file
  163.  fclose(Archivio);  
  164.      
  165.  system("CLS");
  166.  printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  167.  printf("\n Sudoku caricato con successo\n");
  168.  printf("\n Premi un tasto per continuare \n ");
  169.  
  170.  getch();
  171.              
  172.  return(S);
  173. }
  174.  
  175.  
  176. int **CaricaSudoku(){
  177.  
  178.  char scelta;
  179.  int  **S;
  180.  
  181.  scelta = 0;
  182.  while((scelta != 49)&&(scelta != 50)){
  183.   system("CLS");
  184.   printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  185.   printf("\n Premi:\n");
  186.   printf("\n 1 - Per caricare il sudoku dal file 'Archivio.dat'\n ");
  187.   printf("\n 2 - Per inserire il sudoku da tastiera\n");
  188.   printf("\n ");
  189.   scelta = getch();
  190.   switch (scelta){
  191.    case 49 : S = CaricaSudokuDaFile();
  192.             break;
  193.    case 50 : S = LeggiSudokuDaTastiera(S);
  194.             break;
  195.   }
  196.  }
  197.  return(S);
  198. }
  199.  
  200. // funzione che stampa il sudoku
  201. void StampaSudoku(int **S){
  202.  
  203.  int i,j;
  204.  
  205.  for(i = 0; i < n; i++){
  206.   for(j = 0; j < n; j++){
  207.    if (S[i][j]==0) printf(" .");
  208.      else printf(" %d",S[i][j]);
  209.    if(((j+1)%3 == 0)&&((j+1) != 9)) printf(" |");
  210.   }
  211.   printf("\n");
  212.   if(((i+1)%3 == 0)&&((i+1) != 9)) printf(" ---------------------\n");
  213.  }
  214.  printf("\n");
  215. }
  216.  
  217.  
  218. // funzione che copia S in S2
  219. void Copia(int **S, int **S2){
  220.  
  221.  int i,j;
  222.  
  223.  for(i = 0; i < n; i++)
  224.   for(j = 0; j < n; j++)
  225.    S2[i][j] = S[i][j];
  226.  
  227. }
  228.  
  229.  
  230. // funzione che cerca i numeri che possono essere inseriti alla
  231. // riga r e alla colonna c e li restituisce in vet. Restituisce 0 in caso
  232. // non sia possibile inserire alcun numero
  233. int TrovaNumeri(int **S, int r, int c, int vet[]){
  234.  
  235.  int i,lun;
  236.  
  237.  // variabile che tiene traccia di quanti numeri sono stati trovati
  238.  lun = 0;
  239.  
  240.  for(i = 1; i < 10; i++){
  241.   if(Esiste(S,i,r,c)==0){
  242.    vet[lun] = i;
  243.    lun++;
  244.   }
  245.  }
  246.  
  247.  return(lun);
  248. }
  249.  
  250.  
  251. // funzione che salva il sudoku nel file "soluzione.txt"
  252. void SalvaSudoku(int **S){
  253.  
  254.  FILE *file;
  255.  int i,j;
  256.  char fine[1];
  257.  
  258.  file = fopen("soluzione.txt","w");
  259.  
  260.  for(i = 0; i < n; i++){
  261.   for(j = 0; j < n; j++)
  262.    fprintf(file," %d",S[i][j]);
  263.   fprintf(file,"\n");
  264.  }
  265.  
  266.  fclose(file);  
  267.  
  268. }
  269.  
  270.  
  271. // funzione che risolve il sudoku
  272. int **RisolviSudoku(int **S){
  273.  
  274.  int **S2,i,j,lun,num[9];
  275.  float t0,t1;
  276.  int fine;
  277.  float azzera;
  278.  
  279.  if(S == NULL){
  280.   system("CLS");
  281.   printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  282.   printf("\n Devi prima caricare un Sudoku\n");
  283.   printf("\n Premi un tasto per continuare \n ");
  284.   getch();
  285.   return(NULL);
  286.  }
  287.  
  288.  system("CLS");
  289.  printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  290.  
  291.  printf("\n Elaborazione in corso...");
  292.  
  293.  // parte il cronometro
  294.  t0 = ((float)clock())/CLK_TCK;
  295.  
  296.  // viene allocata la matrice che conterrà la soluzione
  297.  S2 = AllocaMatrice();
  298.  // S viene copiata in S2
  299.  Copia(S,S2);
  300.  
  301.   i = 0;
  302.   azzera = 0;
  303.   while(i < n){
  304.    j = 0;
  305.    while(j < n){
  306.     if(S2[i][j] == 0){
  307.      lun = TrovaNumeri(S2,i,j,num);
  308.      // se lun = 0 allora vuol dire che il sudoku generato è sbagliato quindi...
  309.      if(lun == 0){
  310.       // ...vengono azzerati gli indici del ciclo e S2
  311.       i = 0;
  312.       j = -1;
  313.       Copia(S,S2);
  314.       azzera++;
  315.      }else S2[i][j] = num[rand() % lun];
  316.     }
  317.     j++;
  318.    }
  319.    i++;
  320.   }
  321.  
  322.  system("CLS");
  323.  printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  324.  StampaSudoku(S2);
  325.  SalvaSudoku(S2);
  326.  
  327.  // viene fermato il cronometro
  328.  t1 = ((float)clock())/CLK_TCK;
  329.  
  330.  printf("\n Tempo per risolvere il sudoku: %3.0f\n", t1-t0);
  331.  printf("\n Numero di Sudoku sbagliati generati: %7.0f\n",azzera);
  332.  printf("\n Soluzione salvata nel file soluzione.txt\n");
  333.  printf("\n Premi un tasto per continuare \n");
  334.  printf("\n ");
  335.  
  336.  getch();
  337.  
  338.  return(S2);
  339. }
  340.  
  341.  
  342. int main(){
  343.  
  344.  int   **S,i,j;
  345.  int  scelta;
  346.  
  347.  // viene inizzializata celta
  348.  scelta = 0;
  349.  S = NULL;
  350.  
  351.  // viene inizzializato il generatore di numeri casuali
  352.  srand(time(NULL));
  353.  
  354.  // il programma termina se si preme 3
  355.  while(scelta!=51){
  356.   system("CLS");
  357.   printf("                  Risolvi Sudoku 1.1 by Davide Zanin - Zani88\n\n");
  358.   printf("\n Premi:\n");
  359.   printf("\n 1 - Per caricare un Sudoku\n");
  360.   printf("\n 2 - Per risolvere il Sudoku\n");
  361.   printf("\n 3 - Per uscire\n");
  362.   printf("\n ");
  363.   scelta = getch();
  364.   switch (scelta){
  365.    case 49 : S = CaricaSudoku();
  366.             break;
  367.    case 50 : RisolviSudoku(S);
  368.             break;
  369.   }
  370.  }
  371.  
  372.  return 0;
  373. }