Generator sudoku - problem

0
import java.util.Random;
public class Main {
static final int n=9;	//taka pomocnicza stala 
	
	public static int dodawaj(int x){	//dodawanie liczby		   
		if (x==9)
			x=1;
		else x++;
	   return x;   
	   
}
	public static int losowanieliczby(int x){ //losujemy liczbe
		Random r = new Random();
		x=r.nextInt(n)+1;
		return x;
	}
	public static int sprawdzaniepoziom(int indeks, int tab[]){	//sprawdzenie w poziomie
		int czyprawda=1;
		int licznik=(indeks%n); //ile pol ma sie cofac i sprawdzac		
		if (licznik==0) return czyprawda; //wykonywanie sprawdzenia
			else 
				for (int i=indeks-licznik; i<indeks; i++){
					if (tab[indeks]==tab[i]) {return czyprawda=0;}
				}
		return czyprawda;
	}
	public static int sprawdzaniekomorki(int indeks, int tab[]){ //sprawdzenie komorki
		int czyprawda=1;
		if ((indeks%9)%3==0 && (indeks/9)%3==0) return czyprawda;
		if ((indeks%9)%3==1 && (indeks/9)%3==0){ if (tab[indeks]==tab[indeks-1]) return czyprawda=0;} 
		if ((indeks%9)%3==2 && (indeks/9)%3==0){ if (tab[indeks]==tab[indeks-1] || tab[indeks]==tab[indeks-2]) return czyprawda=0;} 
		if ((indeks%9)%3==0 && (indeks/9)%3==1){ if (tab[indeks]==tab[indeks-9] || tab[indeks]==tab[indeks-8] || tab[indeks]==tab[indeks-7]) return czyprawda=0;} 
		if ((indeks%9)%3==1 && (indeks/9)%3==1){ if (tab[indeks]==tab[indeks-1] || tab[indeks]==tab[indeks-10] || tab[indeks]==tab[indeks-9] || tab[indeks]==tab[indeks-8]) return czyprawda=0;}
		if ((indeks%9)%3==2 && (indeks/9)%3==1){ if (tab[indeks]==tab[indeks-1] || tab[indeks]==tab[indeks-2] || tab[indeks]==tab[indeks-11] || tab[indeks]==tab[indeks-10] || tab[indeks]==tab[indeks-9]) return czyprawda=0;}
		if ((indeks%9)%3==0 && (indeks/9)%3==2){ if (tab[indeks]==tab[indeks-9] || tab[indeks]==tab[indeks-8] || tab[indeks]==tab[indeks-7] || tab[indeks]==tab[indeks-18] || tab[indeks]==tab[indeks-17] || tab[indeks]==tab[indeks-16]) return czyprawda=0;}
		if ((indeks%9)%3==1 && (indeks/9)%3==2){ if (tab[indeks]==tab[indeks-1] ||tab[indeks]==tab[indeks-10] || tab[indeks]==tab[indeks-9] || tab[indeks]==tab[indeks-8] || tab[indeks]==tab[indeks-19] || tab[indeks]==tab[indeks-18] || tab[indeks]==tab[indeks-17]) return czyprawda=0;}
		if ((indeks%9)%3==2 && (indeks/9)%3==2){ if (tab[indeks]==tab[indeks-1] ||tab[indeks]==tab[indeks-2]  ||tab[indeks]==tab[indeks-11] || tab[indeks]==tab[indeks-10] || tab[indeks]==tab[indeks-9] || tab[indeks]==tab[indeks-20] || tab[indeks]==tab[indeks-19] || tab[indeks]==tab[indeks-18]) return czyprawda=0;}
return czyprawda;
	}
	public static int sprawdzaniepion(int indeks, int tab[]){ //sprawdzenie w poionie
		int czyprawda=1;
		int licznik=indeks/n;	
		int y=indeks;
		if (licznik==0) return czyprawda;		
			else
				for (int i=0; i<licznik; i++){	
					y=indeks-9;
					if (tab[indeks]==tab[y]) {return czyprawda=0;}					
				}
		return czyprawda;
	}
	
	public static class Sprawdzarka{
		static int y=0;		
		static int czyok=0;
	public static  int[]alggeneruj(int tab[], int indeks){	
			czyok=0;
			while(y!=9){
			if (sprawdzaniepoziom(indeks, tab)==0 || sprawdzaniekomorki(indeks, tab)==0 || sprawdzaniepion(indeks, tab)==0){
				tab[indeks]=dodawaj(tab[indeks]); 
						y++;
				alggeneruj(tab, indeks);
			}else{y=0; czyok=1; return tab;}
		}
		y=0; czyok=0; return tab;
		
	}
		}
	
	public static void main(String args[]){			
		int tab[] = new int [n*n];			
		int indeks=0;			
		while (indeks!=81){
			tab[indeks]=losowanieliczby(tab[indeks]);		
			tab=Sprawdzarka.alggeneruj(tab, indeks);			
			if (Sprawdzarka.czyok==0){				
				indeks--;
				while (Sprawdzarka.czyok!=1) {tab=Sprawdzarka.alggeneruj(tab, indeks);};
			}
			indeks++;
		}
		for (int j=0; j<81; j++){if (j%9==0)System.out.println();
			System.out.print(tab[j]);}
		
			
		}
		
		
		
	}

Hej zaczynam swoją przygodę z programowaniem. Postanowiłem się ostatnio zabrać za coś bardziej zaawansowanego i napisać generator sudoku. Postanowiłem rozwiązać ten problem poprzez zastosowanie tablicy jednowymiarowej i algorytmu nawracania. Program bez większego problemu generuje planszę 9x9, w której nie powtarzają się liczby w wierszach i komórkach. Nie radzi sobie jednak poradzić z sprawdzeniem kolumn. Próbuję wyłapać błąd od dłuższego czasu, ale nie potrafię go znaleźć.

3

Koszmar.
Zadanie na dziś: zmodyfikuj ten program tak żeby działał dla dowolnie dużego sudoku, na przykład milion na milion. Podpowiem ci ze gdybyś napisał to poprawnie to nie wymagałoby to praktycznie żadnych zmian.

0

Chętnie się dowiem też co powinienem poprawić w kodzie/douczyć się żeby wyglądał on przyzwoicie. I jeżeli ktoś mi podpowie co zrobić, żeby działał będę bardzo wdzięczny.

0

To akurat dość proste: musisz pozbyć się tej kaskady ifów która tam zrobiłeś. Co wiecej, domyślam się że ona nie działa ;]

0

Ona właśnie działa (można wywołać program, który będzie generował sudoku gdzie liczby w komórkach nie będą się powtarzały). Ta kaskada ifów jest dla sprawdzenie komórek w sudoku. Gdyby ją napisać dla n-owej tablicy ilość ifów była by chyba podobna. Nie mogę wpaść na pomysł jak zmniejszyć ich ilość.

0
daver napisał(a):

Nie mogę wpaść na pomysł jak zmniejszyć ich ilość.

słowo klucz: pętla

0
   public static class Sprawdzarka{
                static int y=0;                
                static int czyok=0;
        public static  int[]alggeneruj(int tab[], int indeks){        
                        czyok=0;
                        while(y!=9){
                        if (sprawdzaniepoziom(indeks, tab)==0 || sprawdzaniepion(indeks, tab)==0){
                                tab[indeks]=dodawaj(tab[indeks]); 
                                                y++;
                                alggeneruj(tab, indeks);
                        }else{y=0; czyok=1; return tab;}
                }
                y=0; czyok=0; return tab;
 
        }
                }
 
        public static void main(String args[]){                        
                int tab[] = new int [n*n];                        
                int indeks=0;                        
                while (indeks!=81){
                        tab[indeks]=losowanieliczby(tab[indeks]);                
                        tab=Sprawdzarka.alggeneruj(tab, indeks);                        
                        if (Sprawdzarka.czyok==0){                                
                                indeks--;
                                while (Sprawdzarka.czyok!=1) {tab=Sprawdzarka.alggeneruj(tab, indeks);};
                        }
                        indeks++;
                }
                for (int j=0; j<81; j++){if (j%9==0)System.out.println();
                        System.out.print(tab[j]); }
 
 
                } 
        }

Dobra doszedłem do wniosku, że wystarczy sprawdzić komórkę tylko jak dojedziemy do ostatniej liczby z komórki dzięki czemu pozbyłem się kilku ifów. Niestety teraz program wywala error: StackOverflowError. Jest to pewnie winna mojego źle napisanego alg. nawracania. Czy ktoś wie jak go usprawnić?

1 użytkowników online, w tym zalogowanych: 0, gości: 1