Stelma Napisano Lipiec 17, 2010 Zgłoś Share Napisano Lipiec 17, 2010 Witam Z racji iż jest to mój pierwszy post chciałem się przywitać Chciałem spytać bardziej doświadczonych kolegów czy poniższy modulik można ulepszyć zachowując jego pierwotne założenia losowania. Nie chciał bym zmieniać mu rodzaju losowania z prostej przyczyny gwarantuje on wylosowanie mi planszy w czasie krótszym niż 4 sekundy. Jednak jego ilość prób jest oszałamiająca ponieważ sięga u mnie czasami do 20 mln (Wliczając w to próby udane jak i nie). I oto właściwie chodzi chciałbym stworzyć coś bardziej zwięzłego. unit TTSudoku; { ////////////////PAWEŁ STELMASIAK\\\\\\\\\\\\\\\\\\\\ ///////////////////stedi2@o2.pl\\\\\\\\\\\\\\\\\\\\\\\ /////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Moduł jest wolno dostępny dla wszystkich którym może się przydać. Plansza jest tworzona na zasadzie rzucania piłeczki na stół pokryty otworami i zaklejanie tych które już nie uczesniczą w grze. Plansza jest zwracana typu tradycyjnego sudoku. Funkcja "Generator" zwraca wartość False w przypadku nie powodzenia losowania. Wystarczy tę funkcję wywołać w pętli Repeat..Until, While..do Zwracana tablica "R" posiada wartości 0-8 w celu szybszego generowania. Tablica jest całkiem (w zakresie pozwolenia Random, Randomize) losowa. Dzięki czemu moduł może działać samodzielnie bez potrzeby dodawania dodatkowych plików Testowany na : Procek : 1,6 Ghz "1 rdzeń" Ram : 512 DDR + 4 GB rzucanie na dysk twardy Dysk : Samsung 40 GB 5400 obr/min System : Windows XP pro Service Pack 3 Kompilator : Delphi 7 EN Czas reakcji Średnio 2 sekundy. Zawsze udawało mu się wygenerować planszę poniżej 4 sekund } interface uses Forms; //Moduły delphi type TSudoku = class(TObject) function Generator(Sender : TSudoku): boolean; //funkcja służy do generowania planszy public R : array [1..9, 1..9] of byte; //Deklaracja tablicy {R} Prawdziwa, {P} Pomocznicza private P : array [1..9, 1..9] of byte; //Deklaracja tablicy {P} Pomocznicza procedure CreateEmptyTable(Sender : TSudoku); //Funkcja służy do wyczyszczenia tablicy {R} procedure CreateHelpTable(Sender : TSudoku); //Funkcja "układa" pomocniczą tablice {P} procedure ElminateHelpTable(var x, y : Byte; Sender : TSudoku); //Funkcja w tablicy {P} zaznacza miejsca które są zajęte end; implementation procedure TSudoku.CreateEmptyTable(Sender : TSudoku); Var i, j :Integer; begin For i := 1 to 9 do For j := 1 to 9 do (Sender as TSudoku).R[i][j] := 0; end; procedure TSudoku.CreateHelpTable(Sender : TSudoku); Var i, j :Integer; begin For i := 1 to 9 do For j := 1 to 9 do IF (Sender as TSudoku).R[i][j] = 0 then (Sender as TSudoku).P[i][j] := 0 else (Sender as TSudoku).P[i][j] := 1; end; procedure TSudoku.ElminateHelpTable(var x, y : Byte; Sender : TSudoku); var i, j : Integer; begin For i := 1 to 9 do begin (Sender as TSudoku).P[i][x] := 1; //Zaznaczenie poziomów (Sender as TSudoku).P[y][i] := 1; //Zaznaczenie pionów end; x := (x - 1) div 3 * 3 + 1; //Ustalanie kwadratu X y := (y - 1) div 3 * 3 + 1; //Ustalanie kwadratu Y For i := 0 to 2 do //Zaznaczanie kwadratu X / Y For j := 0 to 2 do (Sender as TSudoku).P[y + i][x + j] := 1; end; function TSudoku.Generator(Sender : TSudoku): boolean; const Max = 2500; //Ilosc prób rzutów do zakończenia funkcji fiaskiem {2500} wydaje mi się optymalna var i, j, min : Integer; x, y : Byte; begin result := False; IF not (Sender is TSudoku) then exit; //Sprawdzanie czy klasa jest typu TSudoku Randomize; min := 0; (Sender as TSudoku).CreateEmptyTable(Sender); //Tworzenie pustej tabli For i := 1 to 8 do begin (Sender as TSudoku).CreateHelpTable(Sender); //Tworzenie tablicy pomocniczej Application.ProcessMessages; //Chwila oddechu dla procesora For j := 1 to 9 do begin Repeat y := Random(9) + 1; //Losowanie poziomu x := Random(9) + 1; //Losowanie pionu IF min = Max then exit //Sprawdzanie czy już przekroczono ilosc prób else Inc(min); //Jeżeli nie przekroczono to dopisz Until (Sender as TSudoku).P[y][x] = 0; //Jeżeli na planszy nie ma cyfry to skończ szukac (Sender as TSudoku).R[y][x] := i; //Zapisanie cyfry (Sender as TSudoku).ElminateHelpTable(x, y, Sender); //Wyeliminowanie miejsc w których liczba nie może wystąpic end; end; result := True; end; end. Z góry dziękuję za pomoc jak i przepraszam za chaotycznie napisany temat jak i moduł ;p Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.